内核定时器

1.节拍器    100hz 10ms间隔,jiffies 其实就是 jiffies_64 的低 32 位   记录系统节拍树,因为是32位所以记录最大值为4294967296(个节拍,也就是这么多个10ms) 4294967296/100/60/60/24 = 49.7 天  就会归零,也叫绕回  
可以用相关的API函数处理,实现定时

一秒的节拍数是HZ

特点: 需要“设置”,定时处理执行一次后结束,要周期处理的话需要想办法重新打开

timer_list  定时器结构体

 

直接加载驱动后就自己启动:

首先初始化IO,然后初始化定时器(设置“中断函数”timer.function、定时时间timer.expires,把定时器添加到系统中add_timer,)然后在中断函数中实现状态取反,然后使用mod_timer重新启动定时器   ,就可以实现闪灯

使用程序测试:

测试程序获取用户指令 开灯 关灯 设置循环周期,在设置循环周期的时候需要给定周期值,通过ioctl()  将用户指令标志位A与假定的周期值B这两个参数传递给驱动,驱动拿到后,通过.unlocked_ioctl = timer_unlocked_ioctl() 这个函数接收到程序传递的参数A和B,然后执行对应的指令。

 

按键消抖,按键驱动

首先驱动初始化字符设备,
初始化按键,设置默认的键值为0XFF,完成按键次数为0
初始化按键IO,of_get_named_gpio获取其一个GPIO标号A(对应具体按键),
gpio_request(A,name) 函数用于申请一个 GPIO 管脚(因为要用,防冲突),并起名字(对应具体按键)
然后gpio_direction_input设置某个 GPIO 为输入
使用irq_of_parse_and_map获取中断号irqnum(对应具体按键)
value=0(对应具体按键)handler(对应具体按键)赋值,编写中断服务函数handler开启定时器(对应具体按键)
【设置定时10ms,定时器函数里面判断按键状态】

此时,一个具体的按键属性集齐

然后request_irq申请中断(按键按下和抬起都处罚中断),创建定时器

测试的时候循环读取驱动传递的数据
,当按键按下的时候触发中断,进入key0_handler,定时10ms, 到时间后进入timer_function,这里判断按键是按下的,就给
具体按键的值,赋给当前设备的值,

此时当前设备通过imx6uirq_read, 判断有效按键的时候,只读取到按键按下的有效数据,但无法获得按键抬起的有效数据
当按键释放的时候,按键抬起的有效数据有了标志位,这里判断有效按键就成功,然后返回这个数据给到上层,然后清除标志位

中断上下部

问题1:中断服务函数的参数是如何传递过来的?imx6uirq.irqkeydesc[0].handler = key0_handler;   直接附带传值

问题2:中断的处理函数 return IRQ_RETVAL(IRQ_HANDLED); ??     return  IRQ_HANDLED ;  两者的区别

 

 keydesc = &dev->irqkeydesc[num];

 atomic_set(&dev->keyvalue, 0x80 | keydesc->value);

取对应按键值赋给设备结构体属性dev->keyvalue=   0x80 | keydesc->value  ==  1000 0000  | 0000 0001 == 1000 0001    

posted @ 2023-12-18 21:25  磕伴  阅读(26)  评论(0编辑  收藏  举报