好久没看过驱动的教程,也没怎么做这方面的开发,所以已经忘得差不多了。但是想着重新拾起来应该不会花很长时间吧。
编写驱动首先得在源码下进行。我用的TQ2440的源码包,为了节约时间,就不自己移植了,直接用光盘里已经配置好的内核源码(linux-2.6.30.4)。
字符驱动格式
1 驱动说明。包括驱动描述,接口,用法等。
2 头文件
什么情况用哪些头文件,这点其实我也不是特别清楚。多加点吧。
3 设备名称、主设备号。
设备名称 是指我安装该驱动之后会在/dev 下存在的驱动文件名,供应用程序读写等操作。
主设备号可以自己定义,但为防止冲突,也可以由系统分配。
这里,我的设备名为ZHAO2440A-LED,主设备号为0,等会通过注册函数由系统分配。
4 定义 file_operations结构体声明驱动提供的操作方法。
这里可以提供open release read write ioctl等操作。根据实际需要选取。如LED驱动就可以不需要write函数,如下图所示:
每一行=后面指定的就是具体的实现函数。
5 几个基本的操作函数。open release ioctl等函数的实现。
static int
Zhao2440A_led_open(struct inode *inode, struct file *file);
static int
Zhao2440A_led_release(struct inode *inode, struct file *file);
static int
Zhao2440A_led_ioctl( struct inode *inode,
struct file *file,
unsigned int cmd,
unsigned long arg);
6 声明一个类用以在dev目录下创建设备节点
7 初始化函数
static int __init Zhao2440A_led_init(void)
7.1 注册设备
上面提到,主设备号(LEDDriver_Major)由系统分配,这里通过字符设备注册函数进行注册。
LEDDriver_Major = register_chrdev(0, DEVICE_NAME, &Zhao2440A_led_fops);
register_chrdev函数原形如下:
int register_chrdev
(unsigned int major
, const char *name
, struct file_operations *fops
);
7.2 类注册
当在系统中添加新设备或将附加设备的支持编译进内核之后,都必须为其建立设备节点。
这里可以注册一个类以便在dev目录下创建设备节点。
class_create 的函数原形如下:
struct class *class_create(
struct module *owner,
const char *name)
7.3 设备创建
有了以上几步,可以通过device_create函数创建。
device_create 函数原形如下:
struct device *device_create(
struct class *class,
struct device *parent,
dev_t devt,
void *drvdata,
const char *fmt, ...);
8 exit函数
static int __exit Zhao2440A_led_exit(void)
依次调用 unregister_chrdev device_destroy class_destroy 即可。
9 驱动的入口函数和释放
10 模块的版本信息等宏定义
以上大概就是一个的字符型驱动所必需的一些内容了。
完整文件内容可见附件
11 测试程序
最简单的测试程序包括有驱动文件的open,ioctl等。
LED驱动的测试程序也在附件里。
12 修改Kconfig 编译模块,安装,使用。
先就到这里吧。反正呢,这个得慢慢来,熟悉就好。
本帖最后由 lonerzf 于 2014-7-19 09:05 编辑