嵌入式面向对象学习 RT-Thread I/O 设备管理框架 设备驱动层 案例测试

本文详细介绍了RT-Thread的I/O设备管理模型,包括设备模型的概念、API操作以及如何在兆易创新GD32F407VET6和雅特力AT32A403A开发板上创建和测试设备驱动实例。还提到了mr-library开源库在设备抽象层方面的价值和特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

嵌入式面向对象 RT-Thread I/O 设备管理框架 设备驱动层

注:本文介绍性内容转载于《RT-Thread记录(十、全面认识 RT-Thread I/O 设备模型)》

注: 本次使用的开发板 :

​ 兆易创新GD32F407VET6开发板

​ 雅特力科技AT32A403A开发板

在这里插入图片描述
在这里插入图片描述

一、RT-Thread 的 I/O设备管理

1.1 什么是 I/O 设备模型
1.2 I/O 设备模型框架解析
1.3 I/O 设备操作逻辑说明
1.4 I/O 设备模型框架用处

二、I/O 设备模型操作 API

2.1 I/O 设备控制块
2.2 创建 I/O 设备相关
2.3 访问 I/O 设备相关

三、新建 I/O 设备模型实例

3.1 设备驱动层编写
3.2 应用层测试

一、RT-Thread 的 I/O设备管理

我们先从基本概念说起,了解RT-Thread 对 I/O 设备的管理方式,以及 I/O 设备模型框架的用途:

1.1 什么是 I/O 设备模型

有些小伙伴在刚接触到这个概念的时候还不太明白, I/O 设备模型,IO口?IO口的模型?

注意这里的 I/O 指的是 Input/Output。I/O 设备,就是指的输入 / 输出设备。

所谓 I/O 设备模型,指的是 RT-Thread 把所有的 输入 / 输出设备当做一类对象,然后通过自己的一套体系对这类对象进行管理,这类 I/O 设备对象就可以认为是 I/O 设备模型。

RT-Thread 提供了一套模型框架用来对所有的输入/输出设备进行管理的,名叫 I/O 设备模型框架 ,其 位于硬件层和应用程序之间,包括IO设备管理层、设备驱动框架层和设备驱动层, 向上层层抽象,目标是针对各种不同的I/O设备提供给应用程序相同的接口,如下图:
在这里插入图片描述
内容太多,具体内容在 嵌入式面向对象学习 RT-Thread I/O 设备管理框架 设备驱动层

三、新建 I/O 设备模型实例

前面的大部分内容都是参考文章的东西,对于I/O 设备模型进行了大量的说明。接下来进行案例测试

RT-Thread 驱动都是在 drivers 目录下面:
在这里插入图片描述

我们在目录下新建一个文件,作为驱动示例:

我们写一个简单的基本框架:

1、创建一个设备;
使用 rt_device_create 创建一个设备,需要定义一个 rt_device_t 接口体接收设备设备句柄。

2、实现设备操作的函数:
实现设备对象中对于 设备操作的init,open,close,read,write,control等 函数。在这里插入图片描述
3、注册设备到 I/O 设备管理器;
使用 rt_device_register 将设备注册到设备管理器。

drv_demo.c 中,我们实现如下代码:

在这里插入图片描述
其次,我们需要实现一下设备操作的函数:
在这里插入图片描述
最后,别忘了使用 INIT_BOARD_EXPORT 把设备初始化的代码加入板级硬件初始化:

设备模型实例代码:

#include <rtdevice.h>
#include <rtdbg.h>

rt_err_t  demo_init(rt_device_t dev)
{
    rt_kprintf("demo_init ok!\n");
    return RT_EOK;
}
rt_err_t  demo_open(rt_device_t dev, rt_uint16_t oflag)
{
    rt_kprintf("demo_open ok!\n");
    return RT_EOK;
}
rt_err_t  demo_cloes(rt_device_t dev)
{
    rt_kprintf("demo_cloes ok!\n");
    return RT_EOK;
}

rt_ssize_t demo_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
{
	  buffer = "this is device read example";
	  rt_kprintf("read example: %s\n",buffer);
	  return RT_EOK;
}
rt_ssize_t demo_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
{
	  buffer = "this is device write example";
	  rt_kprintf("write example: %s\n",buffer);
	  return RT_EOK;
}
rt_err_t  demo_control(rt_device_t dev, int cmd, void *args)
{
	switch(cmd)
	{
		case 0:
			rt_kprintf("this is demo_control example cmd-1!\n");	
			break;
		case 1:
			rt_kprintf("this is demo_control example  cmd-2!\n");	
			break;
		case 2:
			rt_kprintf("this is demo_control example  cmd-3!\n");	
			break;
		default:
			break;
	}
}


int rt_drvdemo_init(void)
{

    rt_device_t demo_dev = RT_NULL;

    demo_dev = rt_device_create(RT_Device_Class_Char, 0);
    if(demo_dev == RT_NULL){
        LOG_E("demo device create failed...\n");
        return RT_ERROR;
    }

    demo_dev->init=demo_init;
    demo_dev->open=demo_open;
    demo_dev->close=demo_cloes;
	demo_dev->read = demo_read;
    demo_dev->write = demo_write;
	demo_dev->control =demo_control;
    rt_device_register(demo_dev,"drvdemo",RT_DEVICE_FLAG_RDWR);
    return 0;
}


INIT_BOARD_EXPORT(rt_drvdemo_init);

上面我们完成的是 设备驱动层的 代码,接下来我们还需要简单演示一下,如果在应用层 使用这个 demo 设备。

我们根据上文所介绍的 访问 I/O 设备 进行对应操作,这里直接上图说明一下使用流程:

应用测试函数

rt_device_t dev = RT_NULL;

void *read_buf;
void *write_buf;

int main(void)
{

	dev = rt_device_find("drvdemo");
	
	  rt_device_init(dev);
	  rt_thread_mdelay(1000);
	  rt_device_open(dev,RT_DEVICE_OFLAG_OPEN);
	  rt_device_read(dev,0,read_buf,20);
	  rt_device_write(dev,0,write_buf,20);
	  rt_device_control(dev,0,RT_NULL);
	  rt_device_close(dev);
		
		
    return RT_EOK;
}

看一下测试结果,我们实现的 3 个驱动函数都只有打印输出,所以我们可以通过打印信息查看是否正确执行的驱动函数的内容:

下面是在雅特力AT32开发板的测试结果。

(原本打算使用gd32去做实验的,但是从官方的MDK工程打开一直存在问题,然后就换了一块板子,进行测试,从这里可以发现,统一的API接口的好处,应用层无缝对接)

在这里插入图片描述
在这里插入图片描述
下面是在对于立创开发板GD32F407进行详细实验。

  1. 下载rt-thread 源码
  2. 寻找bsp-gd32工程,gd32有两个类型一个是arm,一个risc-v
  3. 寻找立创开发板GD32F407模板工程 gd32f407v-lckfb
  4. 使用env工具进行配置

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  1. 如果直接编译,会报一个错误bug,需要修改,解决方法是添加condvar.c文件即可。

在这里插入图片描述

  1. 添加编写的drv_demo.c文件,完成设备驱动的添加

在这里插入图片描述
7. 编写应用层程序 测试

/*
 * Copyright (c) 2006-2024, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2024-01-13     yuanzihao    first implementation
 */

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

/* defined the LED1 pin: PB2 */
#define LED_PIN GET_PIN(B, 2)
rt_device_t dev = RT_NULL;

void *read_buf;
void *write_buf;
int main(void)
{
    int count = 1;
    dev = rt_device_find("drvdemo");
	
	  rt_device_init(dev);
	  rt_thread_mdelay(1000);
	  rt_device_open(dev,RT_DEVICE_OFLAG_OPEN);
	  rt_device_read(dev,0,read_buf,20);
	  rt_device_write(dev,0,write_buf,20);
	  rt_device_control(dev,1,RT_NULL);
	  rt_device_close(dev);
		
    /* set LED1 pin mode to output */
    rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT);
   
    while (count++)
    {
        rt_pin_write(LED_PIN, PIN_HIGH);
        rt_thread_mdelay(500);
			  //rt_kprintf("this is led_control on  [ok]!\n");	
        rt_pin_write(LED_PIN, PIN_LOW);
        rt_thread_mdelay(500);
			  //rt_kprintf("this is led_control off [ok]!\n");	
    }

    return RT_EOK;
}

在这里插入图片描述
在这里插入图片描述

通过上面的测试,我们实现了一个简单的设备驱动的设计,虽然demo比较简单,但是经过这么一个过程可以让我们更加的理解 RT-Thread I/O 设备模型的工作方式和流程。

在这里,同时介绍一个开源项目mr-library。

mr-library 是一个开源项目,设备抽象层应该比RT-Thread更加轻量级,是一个学习设备框架,设备驱动,面向对象操作的好东西。

设备抽象层的开源库 mr-library

mr-library 框架是专为嵌入式系统设计的轻量级框架。充分考虑了嵌入式系统在资源和性能方面的需求。 通过提供标准化的设备管理接口,极大简化了嵌入式应用开发的难度,帮助开发者快速构建嵌入式应用程序。

框架为开发者提供了标准化的开启(open)、关闭(close)、控制(ioctl)、读(read)、写(write) 等接口。它将应用程序与底层硬件驱动进行解耦。应用程序无需了解驱动的实现细节。 当硬件发生改变时,只需要适配底层驱动,应用程序就可以无缝迁移到新硬件上。这大大提高了软件的可重用性和应对新硬件的可扩展性。


在这里插入图片描述

关键特性

  • 标准化的设备访问接口
  • 应用程序和驱动开发解耦
  • 简化底层驱动和应用程序开发
  • 轻量易上手,资源占用低
  • 模块化设计,各部分解耦合并独立开发,极低的硬件迁移成本
  • 支持在裸机环境和操作系统环境下使用

主要组成

  • 设备框架:提供设备访问标准接口
  • 内存管理:动态内存管理
  • 工具:链表、队列、平衡树等常用数据结构
  • 各类功能组件

标准化设备接口

设备的所有操作都可通过以下接口实现:

接口描述
mr_dev_register注册设备
mr_dev_open打开设备
mr_dev_close关闭设备
mr_dev_ioctl控制设备
mr_dev_read从设备读取数据
mr_dev_write向设备写入数据

测试案例

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值