文章目录
- 前言
- 一、atomic是什么?
- 二、原子操作API函数
- 1.atomic原子操作
- 2.原子位操作API
- 三、atomic驱动实验
- 总结
前言
本文记录的是正点原子rk3568开发板的atomic实验
一、atomic是什么?
不同的线程在进行读写的过程中,可能会冲突乱入,导致会有预想不到的结果。所以为了让数据完整且无误地操作,需要对变量进行原子操作。
二、原子操作API函数
1.atomic原子操作
typedef struct {
int counter;
} atomic_t;
如果要使用原子操作 API 函数,首先要先定义一个 atomic_t 的变量,如下所示:
atomic_t a; //定义 a
也可以在定义原子变量的时候给原子变量赋初值,如下所示:
atomic_t b = ATOMIC_INIT(0); //定义原子变量 b 并赋初值为 0
可以通过宏 ATOMIC_INIT 向原子变量赋初值。
Linux 内核提供了大量的原子操作 API 函数,
2.原子位操作API
如果使用 64 位的 SOC 的话,就要用到 64 位的原子变量,Linux 内核也定义了 64 位原子
结构体,如下所示:
typedef struct {
s64 counter;
} atomic64_t;
原子位操作API函数
三、atomic驱动实验
本实验的目的:用atomic变量控制应用程序只允许打开一个
思路:
- 在驱动程序赋值atomic变量为1
- 应用程序正常打开一次,atomic变量减1。若atomic变量少于等于0,证明有应用程序占用着
- 应用程序结束后,atomic变量加1
驱动代码:atomic.c
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_gpio.h>
#include <asm/uaccess.h>
#include <asm/io.h>#define GPIOLED_CNT 1 /* 设备号个数 */
#define GPIOLED_NAME "gpioled" /* 名字 */
#define LEDOFF 0 /* 关灯 */
#define LEDON 1 /* 开灯 */struct led_dev
{dev_t devid; /* 设备号 */struct cdev cdev; /* cdev */struct class *class; /* 类 */struct device *device; /* 设备 */int major; /* 主设备号 */int minor; /* 次设备号 */struct device_node *nd; /* 设备节点 */int led_gpio; /* led所使用的GPIO编号 */ atomic_t lock; /* 原子变量 */
};struct led_dev gpioled;static int led_drv_open(struct inode *inode, struct file *filp)
{int val = 0;val = atomic_read(&gpioled.lock);if(val <= 0) {return -EBUSY;} else {/* 每打开一次文件都必须要减1 */atomic_dec(&gpioled.lock);}filp->private_data = &gpioled; /* 设置私有数据 */return 0;
}static