# linux_drivers **Repository Path**: startplatinum/linux_drivers ## Basic Information - **Project Name**: linux_drivers - **Description**: No description available - **Primary Language**: C - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-04-13 - **Last Updated**: 2021-06-21 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## Linux Driver 学习 ### 1 这是一个保存学习linux driver的项目,里面保存着学习linux driver的一些例子代码,通过这些代码可以学习了解一些简单的字符 设备驱动的写法,以及定时器、中断、tasklet软中断等等都实现方式。 ### 2 spin_lock 自旋锁 自旋锁在同一时刻只能最多被一个内核任务持有,所以一个时刻只有一个进程允许存在于临界区中。简单的说,自旋锁在内核中主要用来防止多处理器中并发访问临界区,防止内核抢占。 自旋锁不允许任务睡眠,能够在中断上下文中使用。 自旋锁适合用在短期内的轻量级锁定,一个被争用的自旋锁使得请求它的线程在等待锁重新可用的期间内进行自旋(十分浪费处理器时间),如果需要长时间锁定,最好使用信号量。 ``` spinlock_t lock; spin_init(&lock); spin_lock(&lock); spin_unlock(&lock); ``` ### 3 sem信号量 信号量是一种睡眠锁。如果一个任务试图获取一个已经被持有的信号量时,信号量会将其推入等待队列,然后让其睡眠。当信号量被释放后,等待队列中的任务将被唤醒,从而便可以获得这个信号量。 信号量的睡眠特性,使得信号量适合于锁被长期持有的情况,所以只能在进程上下文使用,因为中断上下文中是禁忌睡眠的。 当代码持有信号量的时候,不可以再持有自旋锁。 ``` struct semaphore sem; sema_init(&device->led_sem, 1); 可以被中断的睡眠,当信号到来,睡眠的任务被唤醒。 ret = down_interruptible(&dev->led_sem); ret = 0 表示获取到信号量 ret != 表示没能获取到信号量 up(&dev->led_sem); ``` | 函数 | 描述 | |:-:|:-:| | down(&sem) | 获取不到信号量就进入休眠,不能用在中断中。已不建议继续使用。| | down_trylock(&sem) | 获取不到信号量就立刻返回,永远不会休眠 | | down_interruptible(&sem) | 获取不到信号量就进入休眠,进程被置为TASK_INTERRUPTIBLE类型的睡眠状态。该函数由返回值来区分是正常返回还是被信号中断返回。返回值为0,表示获得信号量。返回值为-EINTR,表示被信号打断。| | 需求 | 建议的加锁方法 | |:-:|:-:| |低开销加锁 | 优先使用自旋锁 | |短期锁定 | 优先使用自旋锁 | |长期加锁 | 优先使用信号量 | |中断上下文中加锁 | 使用自旋锁 | |持有锁是需要睡眠、调度 | 使用信号量 |