内核定时器
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