S5PV210(TQ210)学习笔记——按键驱动程序
经过前面的配置,S5PV210开发已经可以成功进入Linux控制台了,那么,有了这个环境就可以开始学习Linux驱动的编写和测试了。学习Linux设备驱动,通常是从字符设备驱动开始。我写的第一个驱动程序是Led的,其实也就是熟悉下字符设备驱动的基本结构,本文以中断方式的按键驱动为例,简单的介绍下字符设备驱动程序。
一 按键驱动程序的简单实现
下面是基于中断和消息的按键驱动程序,其工作原理是:当应用程序读取键值时,会调用按键驱动程序的read函数,而我们实现的read函数检测完读取长度后没有直接读取键值而是等待按键消息,如果没有按键,程序会进入休眠状态,这样可以节省大量的CPU,而当我们按键时硬件会产生中断,程序自动进入中断处理函数,在中断处理函数中,驱动程序读取键值存入全局变量并激活read函数中等待的消息,应用程序被迅速唤醒并通过read函数读取键值,如此,完成了获取键值的工作。下面是源码,比较简单,也就不多说了。
源码:
#include <fcntl.h>#include <stdio.h>#include <poll.h>#include <signal.h>#include <sys/types.h>#include <unistd.h>#include <fcntl.h>/* sixthdrvtest */int fd; void my_signal_fun(int signum){ unsigned char key_val; read(fd, &key_val, 1); printf("key_val: 0x%x\n", key_val);}int main(int argc, char **argv){ unsigned char key_val; int ret; int Oflags; signal(SIGIO, my_signal_fun); fd = open("/dev/buttons", O_RDWR | O_NONBLOCK); if (fd < 0){ printf("can't open!\n"); return -1; } fcntl(fd, F_SETOWN, getpid()); Oflags = fcntl(fd, F_GETFL); fcntl(fd, F_SETFL, Oflags | FASYNC); int rest; while (1){ printf("Hello\n"); while(rest = sleep(50)){ sleep(rest); } } return 0;}这里需要注意的是,应用程序接收到消息会打断sleep,比如执行sleep(5)之后程序接收到了一个消息,这时,应用程序就被唤醒了,虽然是去执行的消息处理函数。如果程序接收到消息时仅睡眠了2秒,那么sleep被中断时会返回5-2=3,所以代码中采用while循环方式进行sleep,这样,即使接收到了消息也能完整的休眠5秒,当然,sleep函数本身是不够精确的,不过相差无几。
到这里,这个驱动程序基本上就算可以了,当然,还有对阻塞和非阻塞的支持,同步与互斥的支持,而阻塞与非阻塞无非是加上个逻辑判断,同步与互斥根应用程序的同步控制也差不多,无非就是信号量或者原子操作,这里就不多说了,如果有朋友需要这些内容可以留言讨论。