并发:多个执行单元同时被执行
竟态:并发的执行单元对共享资源(硬件资源或全局变量等)的共享访问
通过semaphore机制和spin_lock机制实现
获取信号量不成功 该阻塞或者睡眠
1. 定义信号量 struct semaphore sem;
2. 初始化信号量 void sema_init(structsemaphore *sem ,int val) 初始化信号量的初值为val
3. void init_MUTEX(structsemaphore *sem)初始化一个互斥锁,把sem的值设为1
4. void init_MUTEX_LOCKED(structsemaphore *sem) 初始化一个互斥锁,把sem的值设为0
定义与初始化工作可由如下宏一步完成
DECLARE_MUTEX(name)定义一个信号量,并初始化为1
DECLARE_MUTEX_LOCK(name)定义一个信号量,并初始化为0,为已锁状态
5. 获取信号量void down(struct semaphore *sem)可能会导致进程睡眠,故不能在中断上下文中使用,如果sem非负直接返回,否则挂起(TASK_UNINTERRUPTIBLE),不建议使用
6. void down_interrruptible(structsemaphore *sem)信号量不可用 ,置为TASK_INTERRUPTIBLE
7. void down_killable(structsemaphore *sem)信号量不可用 ,置为TASK_KILLABLE
8. void up(struct semaphore *sem) 释放信号量
自旋锁不会引起调用者的睡眠,线程会移植忙循环,移植等待下去
1. spin_lock_init(x)初始化自旋锁
2. spin_lock(lock)获取自旋锁,不成功自旋在那
3. spin_trylock(lock)不会一直等待
4. spin_unlock
信号量可以有多个持有者(1个互斥信号量),自旋锁只有一个持有者
信号量适合保持时间较长,自旋锁适合保持时间较短
Ioctl对硬件进行控制(改变波特率,报告错误信息)
用户使用方法:intioctl(int fd, unsigned long cmd, …) 点表示可选参数
int(*ioctl)(struct inode *inode, structfile *filp, unsigned int cmd, unsigned long arg)
cmd用户空间传下来的,arg用户传下来的参数
ioctl命令实现方法:1.定义命令 2.实现命令
Documentation/ioctl-number.txt定义了使用的幻数
ioctl被划分为几个位段,include/asm/ioctl.h定义了这些字段:
1. 类型(幻数):8位宽,属于哪一类设备
2. 序号:表明设备命令的第几个
3. 传送方向:可能的值是_IOC_NONE , _IOC_READ, _IOC_WRITE是从应用程序的观点来看的
4 .参数的大小(数据的类型)
内核提供下列宏来帮助定义命令
_IO(type,nr)没有参数传递
_IOR(type, nr, datatype)从驱动中读数据
_I0W(type, nr, datatype)从数据到驱动
_IOWR(type, nr, datatype)type和number成员作为参数被传递
Ioctl函数的实现 1. 返回值 2. 参数使用 3. 命令操作
通常是个switch语句,不支持的返回 –EINVAL
使用ioctl中的参数:整数可以直接使用, 指针则使用前需进行正确的检查
参数检查
不需要检测的函数:copy_from_user,copy_to_user, get_user, put_user
需要检测的函数:__get_user,__put_user
int access_ok(int type, const void *addr, unsingned long size)
第一参数是VERIFY_READ或者VERIFY_WRITE, addr是要操作的用户内存的地址,size是操作的长度。access_ok返回一个布尔值:1.存取没问题 0. 失败,如果返回失败,
则ioctl应当返回-EFAULT.