rt-thread I/O设备模型

        相信大家在学习裸机开发时已经很熟悉各种外设的使用了,现在我们要使用rt-thread操作系统,那么这些外设的操作与裸机操作有什么差别呢。

        事实上即便有操作系统也是可以直接使用裸机操作方式去操作的,但是这样做有几个缺点,一是代码看起来比较不统一,显得很乱,二是软件没有分层,耦合严重,不利于维护,三是裸机操作属于不受操作系统管控的部分,在对硬件资源的占用上,裸机操作可能会与操作系统操作产生冲突导致异常。

        rt-thread提供了一套设备驱动框架,只需要按规范去注册驱动,就可以直接使用rt-thread提供的系统函数去操作硬件了。这样代码就会显得很统一,硬件与驱动也分层了,全部由操作系统调度也不会导致冲突了。目前rt-thread提供的设备模型框架如下图所示,我们要做的就是完成具体设备驱动在rt-thread设备驱动框架上的注册。

       首先来了解一下在rt-thread上是如何访问和操作设备的,以应用程序读取设备为例。首先应用程序通过 rt_device_find() 接口查找到设备,在rt-thread里是通过设备名称字符串去查找的,如果能够找到则使用rt_device_open()去打开设备,在打开设备时也可以选择是按只读,只写或读写方式去打开。接着使用rt_device_read()去读取设备数据,当不需要使用该设备时可以通过rt_device_close()来关闭设备。

        以上这些都是操作系统层面对于设备的操作,那么具体是怎么操作到硬件的呢。可以看到最终访问设备用的是rt_device_read(),因此具体操作肯定也就在这个函数里面。实际上具体设备的驱动和操作系统的驱动函数是有个对应的,而用来实现这种对应的就是rt_device_register()函数,通过这个函数就可以将种类繁多的驱动注册到设备驱动框架上,之后就可以使用统一的操作函数了。

        接下来就讲讲如何去注册,首先得知道rt-thread有几种设备类型 ,因为不同设备类型,它们的操作系统层面驱动是不一样的,因此在注册时需要做的工作也不一样。

        我们先看看rt-thread里的device结构,可以发现跟具体设备驱动有关的只有rt_device_ops,也就是设备的操作方法。

         再来看看rt_device_ops的内容

        这下很明确了,只有这些操作是跟设备有关的,所以只要实现这些函数就可以了。现在我们可以知道该如何操作了 ,总结下步骤:

  1. 先创建一个rt_device设备,如rt_device_t usr_dev
  2. 完成rt_device_ops里的各个操作函数,如hw_init(),hw_open(),hw_close(),hw_read(),hw_write()等
  3. 注册函数,usr_dev.ops->init=hw_init,usr_dev.ops->open=hw_open......
  4. 使用rt_device_register注册到设备框架
  5. 之后便可以按操作系统标准方式去操作usr_dev

     下面给出一段注册示例代码供参考

#include <rtthread.h>
#include <rtdevice.h>

#define     usr_dev_name    "usr_dev"

rt_device_t    usr_dev;

/*无需打开关闭的类型,open()与close()省去*/
static void hw_init(void)
{}

static void hw_read(void)
{}

static void hw_write(void)
{}

int usr_dev_register(void)
{
    usr_dev.type=RT_Device_Class_Miscellaneous;//杂类设备
    usr_dev.ops->init=hw_init;
    usr_dev.ops->read=hw_read;
    usr_dev.ops->write=hw_write;

    return rt_device_register(usr_dev,usr_dev_name,RT_DEVICE_FLAG_RDWR);
}
INIT_DEVICE_EXPORT(usr_dev_register);//自动初始化

         然后是操作示例代码供参考

#include <rtthread.h>
#include <rtdevice.h>

#define     op_dev_name    "usr_dev"

static rt_device_t op_dev==RT_NULL;

int test_usr_dev(void)
{
    op_dev=rt_device_find(op_dev_name); 
    rt_device_open(op_dev,RT_DEVICE_FLAG_RDWR);
    char testch;
    rt_device_read(op_dev,0,&testch,1);
    if(testch!='Y')
    {
        rt_device_write(op_dev,0,'Y',1);
    }
    rt_device_close(op_dev);

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

慕诗客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值