一、基础知识
1、驱动分类
字符设备驱动:字节流设备,例如键盘、串口等
块设备驱动:硬盘、光驱等
网络设备驱动:以太网、WiFi等
2、device 和 driver 关系
驱动和设备文件关联起来,然后上层应用通过设备文件找到驱动去执行。这两个注册的先后是不一定的,但在内核启动的时候,device的注册先于driver的注册。
3、其他
驱动的Makefile(单独编译驱动时用)。生成的是ko文件,通过insmod加载模块,lsmod或cat /proc/modules 查看当前已加载的模块 rmmod是卸载模块。记得虽然生成的ko模块可以动态加载,但不管怎么样,内核都要重新编译和烧写。
二、代码开发细节
(以三星Exynos 4412 开发板为例)
1、驱动相关头文件
#include <linux/module.h>
记得在写自己的驱动时,遵循GPL协议
MODULE_LICENSE("…"); 可填"Dual BSD/GPL"
MODULE_AUTHOR("…"); 可填作者名
#include <linux/init.h>
module_init(fun); //入口 fun是函数名
module_exit(fun);//出口
2、设备注册
在内核文件夹下的 ./arch/arm/mach-exynos/mach-itop4412.c 中增加以下内容(大致,太久了可能记得不太准确):
#ifdef CONFIG_HELLO_CTL
struct platform_device s3c_device_hello_ctl={
.name="…";
.id= … ;
}
#endif
#ifdef CONFIG_HELLO_CTL
&s3c_device_hello_ctl
#endif
3、驱动开发中ioctl 的cmd
①生成cmd
这是在内核中定义的四个宏,这四个宏用于辅助生成cmd
_IO(type,nr)
_IOR(type,nr,datatype)
_IOW(type,nr,datatype)
_IOWR(type,nr,datatype)
(其中nr是序数,datatype即是size)
②cmd参数的组成
cmd 是一个32位的变量,切分为4个区域
bit 00~07:“区别序号区”,给自己命令编号,即nr
bit 08~14:“魔数区”(或称幻数),一般不同设备设置不同的魔数,即type
bit 15~29:“数据大小区”,ioctl中arg变量传送的内存大小,即size
bit 30~31:“区别读写区”(方向),2位4个不同分别是:_IOC_NONE(无数据)、_IOC_READ(读)、_IOC_WRITE(写)、_IOC_READ|_IOC_WRITE(双向),即DIR
③逆操作取得cmd 每个区域
_IOC_TYPE(cmd) _IOC_DIR(cmd) _IOC_NR(cmd) _IOC_SIZE(cmd)