一、结构介绍
I/O设备管理层:实现对设备驱动程序的封装。应用程序通过IO设备层提供的标准接口访问底层设备。
设备驱动管理层:对同类硬件设备驱动的抽象,将不同厂家的同类设备驱动中相同的部分抽取出来,将不同部分留出接口,有驱动程序实现。
设备驱动层: 一组驱使硬件设备工作的程序,实现访问硬件设备的功能。负责创建和注册I/O设备。
对于相对复杂的设备,比如看门狗、串口设备、IIC、SPI等设备,底层驱动创建设备实例,然后将设备实例首先注册到相应的设备驱动框架中,然后定义设备的类型和其他参数通过函数rt_device_register()注册到I/O设备管理器中。(后边会根据程序进行具体说明)
I/O设备模型
RT-Thread的设备模型式建立在内核对象模型基础之上的,设备被认为是一类对象,被纳入对象管理器的范畴。每个设备对象都是由基对象派生而来,每个具体设备都可以继承父类对象的属性,并派生出其私有属性
其中设备类型的定义(rt_device_class_type)在rtdef.h中以枚举的形式列出。
设备对象的具体定义在rtdef.h中以结构体的形式给出
二、程序运行解析
创建和注册I/O设备
驱动层负责创建设备实例,并注册到I/O设备管理器中,可以通过静态申明的方式创建设备实例,也可以通过函数**rt_device_create()**进行动态创建。
rt_device_t rt_device_create(int type, int attach_size);
//其中 type:设备类型,可以取前面小节列出的设备类型值
// attach_size: 用户数据大小
调用该接口函数时,系统会从动态堆内存中分配一个设备控制块,大小为struct rt_device 和attach_size的和,设备的类型由type设定。
设备被创建后,需要实现它访问硬件的操作方法。
硬件的各个操作方法描述在rtdef.h中进行定义
当动态创建的设备叜需要使用函数rt_device_destroy(rt_device_t device)来进行销毁
设备被创建后,需要注册到I/O设备管理器中,应用程序才能访问,注册设备的函数为rt_device_register(rt_device_t dev, const char* name, rt_uint8_t flags)
flags:设备模式标志 在rtdef.h中定义
#define RT_DEVICE_FLAG_RDONLY 0x001 /* 只读 */
#define RT_DEVICE_FLAG_WRONLY 0x002 /* 只写 */
#define RT_DEVICE_FLAG_RDWR 0x003 /* 读写 */
#define RT_DEVICE_FLAG_REMOVABLE 0x004 /* 可移除 */
#define RT_DEVICE_FLAG_STANDALONE 0x008 /* 独立 */
#define RT_DEVICE_FLAG_SUSPENDED 0x020 /* 挂起 */
#define RT_DEVICE_FLAG_STREAM 0x040 /* 流模式 */
#define RT_DEVICE_FLAG_INT_RX 0x100 /* 中断接收 */
#define RT_DEVICE_FLAG_DMA_RX 0x200 /* DMA 接收 */
#define RT_DEVICE_FLAG_INT_TX 0x400 /* 中断发送 */
#define RT_DEVICE_FLAG_DMA_TX 0x800 /* DMA 发送 */
以IIC设备注册为例进行说明
IIC设备主要有四个文件,其中drv_soft_i2c.c位于底层驱动,主要用来定义i2c的管脚和硬件模式,针对硬件进行各种定义和初始化。
另外三个位于设备驱动管理器中,其中i2c-bit-ops.c主要是对i2c设备驱动框架总线中的各个硬件操作方法进行定义。然后在i2c_core.c中进行设备驱动框架的操作函数进行封装,比如i2c设备总线注册函数rt_i2c_bus_device_register()等,最后在i2c_dev.c中进行i2c设备驱动管理器的初始化,定义I/O设备管理接口函数供上层应用进行调用,并将I2C总线设备类通过rt_device_register()注册到设备基类中。
访问I/O设备
应用程序可以通过I/O设备管理接口来访问硬件设备,设备驱动实现后,应用程序就可以访问该硬件。I/O设备管理接口与I/O设备的操作方法的映射关系。
设备访问示例参考rtt官方文档https://www.rt-thread.org/document/site/programming-manual/device/device/