rtthread studio与正点原子apollo(15)--设备IO注册


前言

RT-Thread官方提供大部分设备的标准接口,如UART,ADC,I2C总线等,但并不是所有的设备,当我们所使用的设备在RT-Thread中未定义时,就需要按照RT-Thread提供的I/O 设备模型框架创建并注册自己的I/O设备,注册后的设备可以调用标准的I/O设备接口函数对设备进行相应的操作。

IO设备模型的介绍参考RT-Thread官方文档
I/O设备模型

一、I/O设备模型

RT-Thread 提供了的 I/O 设备模型框架共分成三层,从上到下分别是 I/O 设备管理层设备驱动框架层设备驱动层
在这里插入图片描述
1、I/O 设备管理层实现了对设备驱动程序的封装。
用户通过标准的接口函数访问设备,而这些函数就是由I/O设备管理层封装的,相关的接口函数在rtthread\src\device.c文件中定义

//查找设备
rt_device_t rt_device_find(const char *name);
//初始化设备
rt_err_t  rt_device_init (rt_device_t dev);
//打开设备
rt_err_t  rt_device_open (rt_device_t dev, rt_uint16_t oflag);
//关闭设备
rt_err_t  rt_device_close(rt_device_t dev);
//设备读
rt_size_t rt_device_read (rt_device_t dev,
                          rt_off_t    pos,
                          void       *buffer,
                          rt_size_t   size);
//设备写
rt_size_t rt_device_write(rt_device_t dev,
                          rt_off_t    pos,
                          const void *buffer,
                          rt_size_t   size);
//设备控制
rt_err_t  rt_device_control(rt_device_t dev, int cmd, void *arg);
//接收回调
rt_err_t rt_device_set_rx_indicate(rt_device_t dev,rt_err_t (*rx_ind)(rt_device_t dev, rt_size_t size));
//发送回调
rt_err_t rt_device_set_tx_complete(rt_device_t dev,rt_err_t (*tx_done)(rt_device_t dev, void *buffer));

2、设备驱动框架层是对同类硬件设备驱动的抽象,将不同厂家的同类硬件设备驱动中相同的部分抽取出来,将不同部分留出接口,由驱动程序实现。
这部分代码存储在工程目录\rt-thread\components\drivers下,在启动相应功能后,代码会自动加载到工程中,如串口是工程默认开启的,因此工程中的配置如下
在这里插入图片描述
3、设备驱动层是一组驱使硬件设备工作的程序,实现访问硬件设备的功能。负责创建和注册 I/O 设备,对于操作逻辑简单的设备,可以不经过设备驱动框架层,直接将设备注册到 I/O 设备管理器中。
功能代码存储位置:工程目录\drivers\下,如串口代码通过注册函数注册到系统,并实现了初始化等功能
在这里插入图片描述

二、I/O设备创建注册过程

I/O设备的注册有两种模式:

1、不经过设备驱动框架,直接注册到 I/O 设备管理器中
在这里插入图片描述
(1)创建设备—>(2)直接向I/O设备管理层注册设备—>(3)使用设备

2、设备实例先注册到对应的设备驱动框架中,再由设备驱动框架向 I/O 设备管理器进行注册
在这里插入图片描述
(1)创建设备—>(2)根据特定设备模型创建设备实例—>(3)向I/O设备管理层注册设备—>(4)使用设备

创建设备

可以通过静态申明的方式创建设备实例,也可以用接口进行动态创建。
例如RT-tThread对IO引脚和串口设备的创建采用的是静态申明的方式

//静态创建pin设备对象
static struct rt_device_pin _hw_pin;
//静态创建串口设备对象
struct rt_serial_device *serial;

动态创建接口

//动态创建一个特定类型的设备,返回类型是 rt_device_t
rt_device_t rt_device_create(int type, int attach_size);

其中设备类型在rtdef.h文件中枚举定义,类型非常丰富,可以根据需要定义

enum rt_device_class_type
{
    RT_Device_Class_Char = 0,                           /**< character device */
    RT_Device_Class_Block,                              /**< block device */
    RT_Device_Class_NetIf,                              /**< net interface */
    RT_Device_Class_MTD,                                /**< memory device */
    RT_Device_Class_CAN,                                /**< CAN device */
    RT_Device_Class_RTC,                                /**< RTC device */
    RT_Device_Class_Sound,                              /**< Sound device */
    RT_Device_Class_Graphic,                            /**< Graphic device */
    RT_Device_Class_I2CBUS,                             /**< I2C bus device */
    RT_Device_Class_USBDevice,                          /**< USB slave device */
    RT_Device_Class_USBHost,                            /**< USB host bus */
    RT_Device_Class_USBOTG,                             /**< USB OTG bus */
    RT_Device_Class_SPIBUS,                             /**< SPI bus device */
    RT_Device_Class_SPIDevice,                          /**< SPI device */
    RT_Device_Class_SDIO,                               /**< SDIO bus device */
    RT_Device_Class_PM,                                 /**< PM pseudo device */
    RT_Device_Class_Pipe,                               /**< Pipe device */
    RT_Device_Class_Portal,                             /**< Portal device */
    RT_Device_Class_Timer,                              /**< Timer device */
    RT_Device_Class_Miscellaneous,                      /**< Miscellaneous device */
    RT_Device_Class_Sensor,                             /**< Sensor device */
    RT_Device_Class_Touch,                              /**< Touch device */
    RT_Device_Class_PHY,                                /**< PHY device */
    RT_Device_Class_Security,                           /**< Security device */
    RT_Device_Class_Unknown                             /**< unknown device */
};

创建设备时,需要提供访问设备的操作方法,操作方法被定义成一组函数指针结构体,同样在rtdef.h文件中

struct rt_device_ops
{
    /* common device interface */
    rt_err_t  (*init)   (rt_device_t dev);
    rt_err_t  (*open)   (rt_device_t dev, rt_uint16_t oflag);
    rt_err_t  (*close)  (rt_device_t dev);
    rt_size_t (*read)   (rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size);
    rt_size_t (*write)  (rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size);
    rt_err_t  (*control)(rt_device_t dev, int cmd, void *args);
};

注册设备

设备创建成功后还必须注册设备才能正常使用,注册设备实际上就是给定设备访问名称并与创建的设备对象关联,并指明设备操作模式

rt_err_t rt_device_register(rt_device_t dev, const char* name, rt_uint8_t flags);

设备注册后就可以使用标准的I/O设备访问接口进行操作了,当设备不需要使用时可以注销或销毁

rt_err_t rt_device_unregister(rt_device_t dev);

void rt_device_destroy(rt_device_t device);

三、I/O设备注册实例

设备注册代码参考如下

//设备句柄
static rt_device_t test_dev;
int test_dev_Create(void)
{
    //注册设备为字符设备
    test_dev = rt_device_create(RT_Device_Class_Char,0);
    if (test_dev != RT_NULL) {
        //设备注册成功,添加设备方法
        test_dev->init = test_dev_Init;
        test_dev->open = test_dev_Open;
        test_dev->close = test_dev_Close;
        test_dev->read = test_dev_Read;
        test_dev->write = test_dev_Write;
        rt_device_register(test_dev,"test_dev", RT_DEVICE_FLAG_RDWR);
    }
    return 0;
}
INIT_DEVICE_EXPORT(test_dev_Create);

其中的设备方法需要以函数的形式提供

rt_err_t test_dev_Init(rt_device_t dev)
{
  //这里根据实际设备添加代码,如stm32可以将cubemx生成的初始化代码在此加载
  rt_kprintf("test_dev_Init test!\n");
  return E_OK;
}

其他操作函数根据功能依次实现即可。


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值