嵌入式 - 内核驱动3 - class/device | misc | ioctl |device/driver
一、自动设置设备号
1. 创建设备号设置
自动设置class / device 代替手动设置mknod
static struct class * led_class;
static struct device * led_device;// 自动配置设备号
led_class = class_create(THIS_MODULE, "class_led");
if(IS_ERR(led_class))
{ ret = (int)PTR_ERR; goto err_class_create;
} led_device = device_create(led_class, NULL, dev, NULL, DEV_NAME);
if(IS_ERR(led_device))
{ ret = (int)PTR_ERR; goto err_device_create;
}
2. 出错处理
IS_ERR -- 确保返回值一致
二、杂项设备驱动
动态编译misc
1. 概念
新的框架,本质等同于简化版的字符设备驱动,对比与典型设备驱动
固定主设备号为10
及开发者无需申请主设备号,省略MAJOR_NUM和MINOR_NUM的设置
自动在/dev目录下申请主设备号,省略自动设置class / device 代替手动设置mknod
能大幅减少驱动代码篇幅,提高效率
2. 使用
struct miscdevice misccdev;
主设备号为10
misc_register();
misc_deregister();
3. 编译
编译模块:动态加载
Kconfig 中定义配置类型为 tristate 三态
make menuconfig 配置为 m(编译为模块)
make modules 单独编译配置为 m 的模块
cp drivers/char/led_misc.ko /home/linux/nfs/imx6/rootfs/
4. 运行
insmod led.ko 加载led.ko驱动模块到内核
lsmod 查看动态加载的驱动模块
remmod 卸载动态加载的驱动模块
5. 补充
1. make
make zImage
Image 可以直接运行的内核映像 / 镜像
zImage 一段解压程序和Image的压缩包,在内核启动时可选是否解压
uImage 64字节的头信息 + zImage,通过mkimage工具生成
2. GPL协议许可
三、ioctl
1. 概念
ioctl(input / output control)输入/ 输出控制
1. 定义
作用于用户空间应用程序和内核空间驱动程序间,传递非标准的控制命令和数据
代替一般的操作接口(open,read,write,close等),作为其功能扩展及补充
2. 特定性
内核有一种安全或兼容性的保护机制,因此不是所有ioctl命令都能自由使用
有时内核或底层驱动可能会拦截某些特定的命令码,此时可能会返回 -EINVAL(无效参数)错误
所以在使用ioctl前,需查阅相关内核文档,了解设备类型的限制
3. 唯一性
ioctl在整个系统中是唯一的,不能与其他驱动已使用的命令码冲突
2. 使用
1. led_ioctl.c
2. led_app.c
代替
查询设备类型使用情况
在内核驱动头目录下
vim Documentation / ioctl / ioctl-number.txt
四、设备和驱动分离
1. 概念
将硬件描述(设备)和控制逻辑(驱动)分离开,让它们独立开发、注册,然后由内核在运行时进行匹配和绑定。
提高代码复用,降低耦合度
设备:设备资源
驱动:操作方法
platform总线是内核中一种虚拟的不依赖物理硬件的总线,用于在物理上没有典型总线连接(PCI、USB)的片上系统(SOC)设备
实现了设备与驱动的分离
2. 分离
1. device
向内核描述硬件资源
2. driver
操作该设备的操作函数
probe 回调函数指针
remove 回调函数指针
driver.name 驱动名
imx6ul和imx6ull不同