简介
定时器:应用于内核程序需周期性执行的功能。
自旋锁:自旋锁对于在Linux内核中抢占和中断
的领域使用非常广泛。
作用:
解决并发问题。
实现
目前自旋锁有3种使用方式:
自旋锁初始化
spin_lock_init
自旋锁的加锁和解锁
//优点:解决任务上下文抢占问题,缺点:可以被中断抢占
spin_lock / spin_unlock
//优点:解决单处理器中断上下文抢占问题和任务上下文抢占问题,缺点:仅限于单核
//原理:禁止中断和抢占
spin_lock_irq / spin_unlock_irq
//优点:对于多核处理器,虽然进入临界区前关闭了中断(本地),但其它CPU任然可以抢占,这种方式则可防止其它CPU抢占该临界区
spin_lock_irqsave / spin_unlock_irqsave
定时器和方式3自旋锁部分代码编写展示
/* timer设备结构体 */
struct timer_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; /* key所使用的GPIO编号 */
int timeperiod; /* 定时周期,单位为ms */
struct timer_list timer;/* 定义一个定时器*/
spinlock_t lock; /* 定义自旋锁 */
};
struct timer_dev timerdev; /* timer设备 */
// 定时器回调函数
void timer_function(unsigned long arg)
{
struct timer_dev *dev = (struct iemr_dev *)arg;
int timeperiod = 0;
unsigned long flag;
spin_lock_irqsave(&dev->lock, flag);
timeperiod = dev->timeperiod;
spin_unlock_irqrestore(&dev->lock, flag);
printk("hello linux kernel timer\r\n");
mod_timer(&dev->timer, jiffies + msecs_to_jiffies(timeperiod));
}
//模块入口
static int __init timer_init(void)
{
int ret = 0;
/* 初始化自旋锁 */
spin_lock_init(&timerdev.lock);
// 创建设备
/*
//...
*/
//初始化 timer
init_timer(&timerdev.timer);
timerdev.timer.function = timer_function;
timerdev.timer.data = (unsigned long)&timerdev;
//设置定时器周期为1s,并启动定时器
int timerperiod = 1000;
timerdev.timeperiod = timerperiod;
mod_timer(&timerdev.timer, jiffies + msecs_to_jiffies(timerperiod));
return 0;
}