博文

目前显示的是标签为“timer”的博文

定时中断键盘灯闪烁

在学习完《趣味定时器》后,是不是只在dmesg里看到效果很没劲,这次来点更实际的,我们让键盘灯闪起来。 对于定时器,就不多说了,接下来了解下键盘的基本内容。 键盘在Linux里是属于TTY(TeleTYpe)设备,既然我们要用到键盘,那先找其通用驱动代码,在Linux Kernel源码drivers/tty/vt/keyboard.c文件,我们找到需要的LED灯控制函数: void setledstate(struct kbd_struct  kbd, unsigned int led) ; 该函数被在同一文件的vt_do_kdskled()函数调用,而这函数又被drivers/tty/vt/vt_ioctl.c文件的vt_ioctl()函数调用,这函数是drivers/tty/vt/vt.c里 struct tty_operations con_ops的ioctl成员,在同一文件vty_init()函数里有如下语句: tty_set_operations(console_driver, &con_ops); 将 console_driver->ops赋值为&con_ops,而console_driver是如下类型: struct tty_driver *console_driver; 该结构体在include/linux/tty_driver.h定义,其被include/linux/tty.h文件中的struct tty_struct结构体包含,其又被同文件的struct tty_port结构体包含。 而我们在 drivers/tty/vt/vt_ioctl.c文件中有看到vt_disallocate_all()函数里有tty_port_destroy(&vc[i]->port); 操作,那么找到vc就可以关联起来,在include/linux/console_struct.h文件中有vc的类型struct vc_data结构体定义,而在drivers/tty/vt/selection.c文件中的set_selection()函数里有struct vc_data *vc = vc_cons[fg_console].d; 赋值操作,那么往下找vc_cons,其在drivers/tty/vt/vt.c文件中定义为stru...

趣味定时器

学习完中断后,接下来都是定时中断这一巧妙的中断模式。定时器是在设定时间并且时间一到后就会响应执行设定好的事件,但其只处理一次,如同机械时钟的闹钟功能。而日常中的手机等电子设备设置闹钟后可配置为隔多久再响一次,这需要实现循环定时中断,在下面的内容中会对比说明。 在Linux Kernel中有两种常用的定时器,两者主要是精度的区别,在了解使用它们前,先了解如下几个概念: 1.节拍率(tick rate):系统定时器频率,该值在Linux Kernel里是静态配置好的,使用HZ这个宏,在include/asm-generic/param.h文件中有如下宏: # define HZ CONFIG_HZ 而CONFIG_HZ在make menuconfig时已默认配置好,可以打开源码根目录下的.config文件,在我的机器上配置为CONFIG_HZ=250,即系统每1/CONFIG_HZ秒发生一次时钟中断,也就是说这种情况下时钟的精度为4ms,这在接下来说到的传统jiffies定时器时会用到。 2.节拍:两次时钟中断的间隔就是一个节拍(tick),其值为节拍率的倒数。 3.jiffies:全局变量,记录系统启动至今所产生的节拍数,通过jiffies/HZ就可知道启动后总共运行的秒数。在include/linux/jiffies.h文件中可看到如下内容: extern u64 __jiffy_data jiffies_64; extern unsigned long volatile __jiffy_data jiffies; 分别对应64位和32位系统的声明。 了解了上面的概念后,我们先来了解下传统(标准)的内核定时器,其使用到jiffies和HZ,故而其精度也就是在ms级别,在include/linux/timer.h文件中有如下定义: struct timer_list { /* * All fields that change during normal runtime grouped to the * same cacheline */ struct list_head entry; unsigned long expires; struct...