Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
C++_cpp
原创征文
设备驱动框架
模仿RT_Thread的设备驱动模型,使用C++实现
发布于 2023-10-23 22:02:14 浏览:822
订阅该版
##现状 >由于目前本人就职的公司不允许自由使用操作系统开发,且公司一般为C/C++混合开发的模式,驱动的开发也十分的草率,驱动代码与应用代码杂糅在一起,十分的不清晰。个人又十分喜爱RT_Thread这个系统,也翻阅过一些内核源码,学习到了非常多的有用的开发技能😀。于是我想到,为何不能自己建立一套驱动管理机制来进行统一?于是萌发了使用C++来构建RT_Thread的设备驱动框架的想法。当然,我并没有做到完全一致,而是加入了自己的一些想法,并且也是基于了目前的开发现状来进行了一定的修改(不允许贴源码只能截图哈)。 ##实现过程说明 RT_Thread的内核对象分为很多种类别,**线程、信号量、互斥量、设备、定时器**...由于借鉴了RT_Thread的源码,故进行了删减,只保留设备部分,且去除了对象类型和动态申请内存使用的size变量(RT_Thread的源码这一部分代码就不贴了),如图: ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20231023/1e95f2c705fa9076c93ddf34818ce020.png.webp) ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20231023/2eeed405c7e3409480a63bb706a06142.png) ###内核对象类: ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20231023/c6033321bb415132599fa6d607981ac0.png.webp) RT_Thread是把rt_object这个结构体作为双向链表的元素,这里的话是把**CObject**这个类作为双向链表的对象(C++的类其实和结构体是一样的)。对象的操作只保留了**object_find**、**object_init**、**object_detach**,修改了**register**和**unregister**的操作。**type**、**name**、**usr_data**保留,其中**type(设备的类型)**根据实际应用做了一些修改(部分定义): ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20231023/f8df071879a098000923bbf056283f4e.png.webp) 链表的插入删除操作原封不动“抄”了RT_Thread的源码😀,如图: ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20231023/e5c3ec504439f1915451885a701b729a.png.webp) ###新增驱动的控制与循环 因为删除了**open**和**close**,且考虑到有些驱动需要**调用循环**实现一定的功能,故新增一个驱动控制类**CObjCtrl**: ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20231023/6dace032163e8b6388462d1f89daaf74.png.webp) 该类非常简单,如果驱动未使能则循环退出,且循环的主体(**ObjProcess()**)需要该类被继承后进行虚函数的重写。 ###新建注册类(基本抽象类) 注册类的作用主要就是继承了**CObjCtrl**,且替代RT_Thread的**register**函数和**unregister**函数,将对象接入双向链表。该类的实现如下: ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20231023/5418efb04560b34ad3c9dfcc9f82cfec.png.webp) 需要注意的是,不在需要手动调用**register**和**unregister**这两个注册卸载函数了,因为在驱动类构造函数执行的时候回自动调用(见构造函数和析构函数)。**GetType()**和**GetName()**函数比较常规。构造函数需要传入驱动的类型、名字和私有数据(私有数据的作用下面会有说明)。因为继承了**CObjCtrl**类,故需要重写虚函数**ObjProcess()**,重写的**ObjProcess()**函数由调用了本类的**AbsLayerProcess()**纯虚函数,故本注册类依然需要被继承后重写该纯虚函数**AbsLayerProcess()**。 ###驱动抽象类 该类主要就是继承了上述注册类,且存在常规的**read**、**write**、**control**接口(虚函数)。RT_Thread的驱动初始化是在open函数调用的时候被调用的,我去除了**open**和**close**,所以驱动的初始化放在**find**函数内部,通过变量**b_IsInitOK**来记录是否已经进行过初始化,也可以手动调用函数**DriverInitial()**来进行驱动的初始化。查看构造函数可以发现,私有数据记录了本驱动抽象类的地址(因为传入了this指针)。 又重写了注册类的**AbsLayerProcess()**函数,该函数调用的真正需要驱动实现的循环函数**DriverProcess()**。 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20231023/8a1e7828bcd19c2edd35764c27953bc1.png.webp) *至此,设备驱动框架部分代码全部开发完毕*。😀😀😀😀 ##使用示例 以flash芯片AT45DB为例: ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20231023/f8590ed1d4981573c9fc5c3489380759.png.webp) 需要实现驱动的**read、write、control、init**函数(因为该驱动不需要循环,所以不需要重写**DriverProcess()**循环函数)。构造函数传入SPI相关信息(自己实现的代码,不深究)和驱动类型及名字。 实例化驱动类,自动将“对象”注册至链表内: ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20231023/962463ac3b84dda7f7df66e315c940ec.png.webp) ###使用如下: 使用宏定义简化类静态函数(find函数)的调用。 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20231023/18398c65103734876abc984642e7871d.png) 定义驱动的类指针。 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20231023/617e10e40e94ce67f5b35a210463b18b.png) 找到驱动(自动调用驱动的初始化函数)。 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20231023/23bd6cd83dd41a9558d28e2f5aaeaf4c.png) 使用**read、write、control**接口。 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20231023/ade7dbe8686f16191c87d7a1792d7cef.png) 至此,基本的设备驱动框架已经形成,当然后面又做了一定的拓展和优化,这里不再赘述。RT_Thread实在是一个宝藏系统! 目前使用下来,和RT_Thread使用感受基本一致,驱动和应用层终于不再恋恋不舍了! 这个思路只是个人的理解,敬请指正。
7
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
哈喽你好啊
这家伙很懒,什么也没写!
文章
1
回答
85
被采纳
0
关注TA
发私信
相关文章
1
RT-STUDIO下加入TOUCHGFX?
2
有没有人在RTT上使用C++编程
3
nano c++ 报错如何处理
4
让成员函数能作为rt_device中的回调函数
5
成员函数作为回调函数
6
C++编译问题 undefined reference to `_exit'
7
开启C++功能后,rt_kprintf和单步调试功能无法使用
8
RT-Thread Studio C++ 异常处理 (与预期不一致)
9
C++继承Thread类报错怎么办?
10
STM32使用C++ 编译报错
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
SFUD
msh
rt_mq_消息队列_msg_queue
keil_MDK
ulog
MicroPython
C++_cpp
本月问答贡献
出出啊
1517
个答案
342
次被采纳
小小李sunny
1443
个答案
289
次被采纳
张世争
805
个答案
174
次被采纳
crystal266
547
个答案
161
次被采纳
whj467467222
1222
个答案
148
次被采纳
本月文章贡献
出出啊
1
篇文章
4
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
1
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
1
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部