/***********************************************************************************
*
* spinlock,semaphore,atomic,mutex,completion,interrupt
*
* 声明:
* 1. 本系列文档是在vim下编辑,请尽量是用vim来阅读,在其它编辑器下可能会
* 不对齐,从而影响阅读.
* 2. 本文中有些源代码没有全部帖出来,主要是因为篇幅太大的原因;
* 3. 基于2中的原因,本文借鉴了python中的缩进代码风格进行代码的体现:
* 1. 有些代码中的'...'代表省略了不影响阅读的代码;
* 2. 如下代码缩进代表在一个函数内部的代码,至于在什么函数里,不影响阅读:
* ... //省略代码
* struct test_s {
* };
* ... //省略代码
*
* //进入临界区之前加锁 }
* spin_lock(&p->lock); |
* | |
* /* 有效代码 */ |-->|采用缩进,代表在一个函数内
* | |的代码
* //出临界区之后解锁 |
* spin_unlock(&p->lock); }
*
* ... //省略代码
* int __init test_init(void)
* {
* ... //省略代码
* }
* ... //省略代码
*
**********************************************************************************/
\\\\--*目录*--////////
| 一. spinlock接口;
| 二. semaphore接口;
| 三. atomic接口;
| 四. mutex接口;
| 五. completion接口;
| 六. interrupt接口;
| 七. 按键驱动大致写法;
| 八. 测试按键驱动;
\\\\\\//////////////
一. spinlock接口:
1. 声明: spinlock_t lock;
2. 初始化: spin_lock_init(&test.lock);
3. 获取自旋锁: spin_lock(&p->lock);
4. 释放自旋锁: spin_unlock(&p->lock);
5. spin_lock接口使用Demo:
...
struct test_s {
struct file_operations fops;
spinlock_t lock;
int major;
};
...
//进入临界区之前加锁
spin_lock(&p->lock);
for(i = 0; i < 3; i++)
{
printk('count = %d, %s', cnt++, kbuf);
/*msleep(10);*/
mdelay(10);
}
//出临界区之后解锁
spin_unlock(&p->lock);
...
int __init test_init(void)
{
int ret;
// 初始化spin_lock
spin_lock_init(&test.lock);
ret = register_chrdev(test.major,
DEV_NAME, &test.fops);
if(ret > 0)
{
test.major = ret;
printk('major = %dn', test.major);
ret = 0;
}
return ret;
}
...
二. semaphore接口:
1. 定义: struct semaphore sem;
2. 定义一个信号量,并初始化: DEFINE_SEMAPHORE(name);
3. 初始化: sema_init(&test.sem, 1);
4. 3种获取信号量:
1. down(&p->sem);
2. down_interruptible(&p->sem);
3. down_trylock(&p->sem);
5. 释放信号量: up(&p->sem);
6. semaphore接口使用Demo:
...
struct test_s {
struct file_operations fops;
/**
* spinlock_t lock;
* volatile int count;
*/
struct semaphore sem;
int major;
};
...
/**
* spin_lock(&p->lock);
* if(p->count <= 0)
* {
* spin_unlock(&p->lock);
* return -EAGAIN;
* }
* p->count--;
* spin_unlock(&p->lock);
*/
//加不了锁,睡眠等待
/*down(&p->sem);*/
if(down_trylock(&p->sem))
return -EAGAIN;
for(i = 0; i < 3; i++)
{
printk('count = %d, %s', cnt++, kbuf);
msleep(10);
}
up(&p->sem);
/**
* spin_lock(&p->lock);
* p->count++;
* spin_unlock(&p->lock);
*/
...
int __init test_init(void)
{
int ret;
/**
* spin_lock_init(&test.lock);
* test.count = 1;
*/
sema_init(&test.sem, 1);
ret = register_chrdev(test.major,
DEV_NAME, &test.fops);
if(ret > 0)
{
test.major = ret;
printk('major = %dn', test.major);
ret = 0;
上一篇:Samsung_tiny4412(驱动笔记08)----jiffies,timer,kthread,workqueue,tasklet
下一篇:Samsung_tiny4412(驱动笔记06)----list_head,proc file system,GPIO,ioremap
推荐阅读最新更新时间:2026-03-25 11:16
- 用于 7VIN 至 16VIN、1.5V 和 1.2V 输出的 LTM4628EV DC/DC 模块稳压器的典型应用电路
- 使用 Analog Devices 的 LTC3728LIGN 的参考设计
- DER-406 - 适用于 A19 灯的 5.76 W 高 PF 非隔离降压-升压型 TRIAC 调光 LED 驱动器
- ADR5045B 5V 输出精密微功率并联模式电压基准的典型应用
- LT3970EDDB-3.42 2.5V 降压转换器的典型应用
- MC78M08BDTG 8V 电流调节器的典型应用
- LT1021DCN8-5 精密电压基准的典型应用
- DER-282 - 100W, 扁平(11 mm), LLC DC-DC转换器
- REF193 低压差开尔文连接电压基准的典型应用电路
- LT3088EM 线性稳压器用于添加软启动的典型应用



Linux内核驱动笔记
三星2410开发板ALLEGRO BRD原文件
现代雷达系统的信号设计
BFR340T






京公网安备 11010802033920号