rt-thread简单设备驱动编写

rt-thread官网

RT-Thread 的设备模型是建立在内核对象模型基础之上的,设备被认为是一类对象,被纳入对象管理器的范畴。每个设备对象都是由基对象派生而来,每个具体设备都可以继承其父类对象的属性,并派生出其私有属性,下图是设备对象的继承和派生关系示意图。
设备对象


```c
struct rt_device
{
    struct rt_object          parent;        /* 内核对象基类 */
    enum rt_device_class_type type;          /* 设备类型 */
    rt_uint16_t               flag;          /* 设备参数 */
    rt_uint16_t               open_flag;     /* 设备打开标志 */
    rt_uint8_t                ref_count;     /* 设备被引用次数 */
    rt_uint8_t                device_id;     /* 设备 ID,0 - 255 */

    /* 数据收发回调函数 */
    rt_err_t (*rx_indicate)(rt_device_t dev, rt_size_t size);
    rt_err_t (*tx_complete)(rt_device_t dev, void *buffer);

    const struct rt_device_ops *ops;    /* 设备操作方法 */

    /* 设备的私有数据 */
    void *user_data;
};
typedef struct rt_device *rt_device_t;

I/O 设备类型

```c
RT_Device_Class_Char             /* 字符设备       */
RT_Device_Class_Block            /* 块设备         */
RT_Device_Class_NetIf            /* 网络接口设备    */
RT_Device_Class_MTD              /* 内存设备       */
RT_Device_Class_RTC              /* RTC 设备        */
RT_Device_Class_Sound            /* 声音设备        */
RT_Device_Class_Graphic          /* 图形设备        */
RT_Device_Class_I2CBUS           /* I2C 总线设备     */
RT_Device_Class_USBDevice        /* USB device 设备  */
RT_Device_Class_USBHost          /* USB host 设备   */
RT_Device_Class_SPIBUS           /* SPI 总线设备     */
RT_Device_Class_SPIDevice        /* SPI 设备        */
RT_Device_Class_SDIO             /* SDIO 设备       */
RT_Device_Class_Miscellaneous    /* 杂类设备        */

设备控制结构体

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_device_t rt_device_create(int type, int attach_size);
//删除/销毁
void rt_device_destroy(rt_device_t device);
//注册
rt_err_t rt_device_register(rt_device_t dev, const char* name, rt_uint8_t flags);
//注销
rt_err_t rt_device_unregister(rt_device_t dev);
//查找
rt_device_t rt_device_find(const char* name);
//打开
rt_err_t rt_device_open(rt_device_t dev, rt_uint16_t oflags);
//关闭
rt_err_t rt_device_close(rt_device_t dev);
//控制
rt_err_t rt_device_control(rt_device_t dev, rt_uint8_t cmd, void* arg);
//读
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_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));

flags 参数支持下列参数 (可以采用或的方式支持多种参数):

#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 发送 */

oflags (rt_device_open函数)支持以下的参数:

#define RT_DEVICE_OFLAG_CLOSE 0x000   /* 设备已经关闭(内部使用)*/
#define RT_DEVICE_OFLAG_RDONLY 0x001  /* 以只读方式打开设备 */
#define RT_DEVICE_OFLAG_WRONLY 0x002  /* 以只写方式打开设备 */
#define RT_DEVICE_OFLAG_RDWR 0x003    /* 以读写方式打开设备 */
#define RT_DEVICE_OFLAG_OPEN 0x008    /* 设备已经打开(内部使用)*/
#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 发送模式打开 */

rt_device_control函数
参数 cmd 的通用设备命令可取如下宏定义:

#define RT_DEVICE_CTRL_RESUME           0x01   /* 恢复设备 */
#define RT_DEVICE_CTRL_SUSPEND          0x02   /* 挂起设备 */
#define RT_DEVICE_CTRL_CONFIG           0x03   /* 配置设备 */
#define RT_DEVICE_CTRL_SET_INT          0x10   /* 设置中断 */
#define RT_DEVICE_CTRL_CLR_INT          0x11   /* 清中断 */
#define RT_DEVICE_CTRL_GET_INT          0x12   /* 获取中断状态 */

简单设备驱动例程
device.c

//一个简单的rt-thread驱动例程
rt_err_t  demo_init(rt_device_t dev)
{
    rt_kprintf("demo_init...\n");
    return 0;
}
rt_err_t  demo_open(rt_device_t dev, rt_uint16_t oflag)
{
    rt_kprintf("demo_open...\n");
    return 0;
}
rt_err_t  demo_close(rt_device_t dev)
{
    rt_kprintf("demo_close...\n");
    return 0;
}

int rt_demo_init(void)
{
    //定义一个rt_device_t指针demo_drv
    rt_device_t demo_drv;
    //通过rt_device_create函数创建一个驱动
    demo_drv=rt_device_create(RT_Device_Class_Char, 32);
    //判断驱动是否创建成功
    if(demo_drv==RT_NULL)
        return -ENOMEM;
    //将驱动函数指针传过来
    demo_drv->init=demo_init;
    demo_drv->close=demo_close;
    demo_drv->open=demo_open;
    //注册驱动
    rt_device_register(demo_drv, "demo", RT_DEVICE_FLAG_RDWR);
    return 0;
}
INIT_BOARD_EXPORT(rt_demo_init);

main.c

rt_device_t did;
int main(void)
{
    did = rt_device_find("demo");
    if(did==RT_NULL)
    {
        rt_kprintf("device find failed\n");
        return -EINVAL;
    }
    rt_device_init(did);
    rt_device_open(did, RT_DEVICE_OFLAG_RDWR);
    rt_device_close(did);
    return RT_EOK;
}
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
rt-thread是一个实时嵌入式操作系统,它提供了设备驱动开发的指南,帮助开发者更好地编写设备驱动程序。 首先,在rt-thread中进行设备驱动开发之前,需要了解rt-thread设备驱动框架,包括设备驱动的结构、设备驱动的注册和使用方法等。同时,开发者也需要了解rt-thread设备模型,包括设备设备驱动设备节点的概念,以便更好地理解设备驱动的开发流程。 其次,在编写设备驱动程序时,需要遵循rt-thread设备驱动编程规范,包括设备驱动的命名规范、接口函数的实现规范等。同时,还需要了解不同类型设备的特点和使用方法,以便更好地编写对应的设备驱动程序。 另外,rt-thread提供了丰富的设备驱动接口和函数,开发者可以根据需求选择合适的接口和函数进行设备驱动的开发。在编写设备驱动程序时,还需要注意设备驱动的稳定性和可靠性,及时处理错误和异常情况,以提高设备驱动程序的质量和可靠性。 最后,在设备驱动程序开发完成后,还需要进行设备驱动的测试和调试工作,确保设备驱动程序能够正常工作并符合需求。同时,还需要关注设备驱动程序的性能和优化工作,以提高设备驱动程序的效率和性能。 总之,rt-thread设备驱动开发指南提供了设备驱动开发的规范和方法,帮助开发者更好地编写设备驱动程序,并最终实现嵌入式系统的稳定和可靠运行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值