RTT设备驱动框架学习(CAN设备)

RTT设备框架属于组件和服务层,是基于RTT内核之上的上层软件。
设备框架是针对某一类外设,抽象出来的一套统一的操作方法及接入标准,可以屏蔽硬件差异,为应用层提供统一的操作方法。

RTT设备框架分为三层:设备驱动层、设备驱动框架层、I/O设备管理层。
其中设备驱动层直接对接底层硬件设备;I/O设备管理层向应用层提供了rt_device_find、open、read、write、close、register等访问设备的统一标准接口。而设备驱动框架层就是将同类型硬件设备的共同特征抽象出来,并且还预留了接口,可以添加不同设备的独有特性。

其中的设备模型被认为是一类对象,每个设备对象都是由基对象派生的,每个设备都可以继承其父类对象的属性,并派生私有属性。

正是这样的框架,使得RTT设备框架中各模块高内聚低耦合,对于已有的设备类型,只是将底层硬件的驱动对接到设备驱动层。就可以在应用程序中,调用统一的标准接口,使用不同厂家不同类型的硬件设备。

实例分析

设备对象在rtdef.h中的具体定义

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;rt_err_t (*rx_indicate)(rt_device_t dev, rt_size_t size);rt_err_t (*tx_complete)(rt_device_t dev, void *buffer);#ifdef RT_USING_DEVICE_OPSconst struct rt_device_ops *ops;
#else/* 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_ssize_t (*read)  (rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size);rt_ssize_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);
#endif /* RT_USING_DEVICE_OPS */#ifdef RT_USING_POSIX_DEVIOconst struct dfs_file_ops *fops;struct rt_wqueue wait_queue;
#endif /* RT_USING_POSIX_DEVIO */void                     *user_data;                /**< device private data */
};
}

然后从struct rt_device中派生出新的CAN设备类型struct rt_can_device,其中依据CAN类型设备共有的特性新增了一些结构体成员,位于rt-thread\components\drivers\include\drivers\can.h中

struct rt_can_device
{struct rt_device parent;const struct rt_can_ops *ops;struct can_configure config;struct rt_can_status status;rt_uint32_t timerinitflag;struct rt_timer timer;struct rt_can_status_ind_type status_indicate;
#ifdef RT_CAN_USING_HDRstruct rt_can_hdr *hdr;
#endif
#ifdef RT_CAN_USING_BUS_HOOKrt_can_bus_hook bus_hook;
#endif /*RT_CAN_USING_BUS_HOOK*/struct rt_mutex lock;void *can_rx;void *can_tx;
}

在stm32的CAN设备驱动中,又从struct rt_can_device中派生了新的CAN设备模型struct stm32_can,其中添加了这个设备类型的私有数据,便于底层驱动的对接:

struct stm32_can
{char *name;CAN_HandleTypeDef CanHandle;CAN_FilterTypeDef FilterConfig;struct rt_can_device;
};

可以看出,RTT通过结构体和函数指针使用C语言实现了一些面向对象编程的特性,如封装和继承等,这样面向对象、模块化的思维框架,有助于实现各模块之间高内聚低耦合,提高开发效率。

操作方法

在struct rt_can_device中可以看到针对CAN设备有以下操作方法,这些操作方法是需要我们在设备驱动层去针对不同的硬件设备进行对接实现的。对于一些特殊的设备类型,可以不用对接其所有的操作方法。

struct rt_can_ops{    rt_err_t (*configure)(struct rt_can_device *can, struct can_configure *cfg);    rt_err_t (*control)(struct rt_can_device *can, int cmd, void *arg);    int (*sendmsg)(struct rt_can_device *can, const void *buf, rt_uint32_t boxno);    int (*recvmsg)(struct rt_can_device *can, void *buf, rt_uint32_t boxno);
};

在drv_can.c中,就实现了所有CAN设备的操作方法,并赋值给对应的函数指针,可以直接调用。并且通过static const修饰符,使结构体变量的内容是固定的,提高了代码的安全性和可维护性。然后通过rt_hw_can_register注册。

static const struct rt_can_ops _can_ops = 
{_can_config,_can_control,_can_sendmsg,_can_recvmsg,
};
rt_err_t rt_hw_can_register(struct rt_can_device *can, const char *name, const struct rt_can_ops *ops, void *data);
rt_hw_can_register(&drv_can1.device, drv_can1.name, &_can_ops, &_can_ops, &drv_can1);

其中最后一个参数为void类型指针,在注册同类型的不同设备时,就可以通过最后一个参数,在注册时传入其特有的私有数据。例如STM32的drv_can中传入的就是stm32_can结构体类型,其中就包含了stm_can的私有数据域,在对接底层硬件驱动的时候就会方便很多。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/1233.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux中如何挂载yum云仓库进行软件的安装

1.首先在根目录下建立文件&#xff0c;用来挂载镜像文件 [rootclient ~]# mkdir /rhel9 2.挂载镜像文件&#xff1a; [rootclient ~]# mount /dev/cdrom /rhel9 3.切换到 /etc/yum.repos.d 下的目录并查看 &#xff0c;创建 rhel9.repo文件&#xff0c;并编辑云仓库域名&am…

Leetcode 410 分割数组

题目信息 LeetoCode地址: . - 力扣&#xff08;LeetCode&#xff09; 题目理解 将一个数组切k刀&#xff0c;每一块子数组求和&#xff0c;共k1个数&#xff0c;这里面有一个最大的数Max。找一种切法&#xff0c;使这个Max最小。 暴力解法一定是会超时的&#xff0c;因为包…

对前端路由的理解

在前端技术早期&#xff0c;一个 url 对应一个页面&#xff0c;如果要从 A 页面切换到 B 页面&#xff0c;那么必然伴随着页面的刷新。这个体验并不好&#xff0c;不过在最初也是无奈之举——用户只有在刷新页面的情况下&#xff0c;才可以重新去请求数据。 后来&#xff0c;改…

npm环境搭建

npm是什么 npm是前端的包管理工具&#xff0c;类似于后端的maven。现在npm已经集成到nodeJs中&#xff0c;安装好nodeJs就可以安装好npm了。 npm初始配置 一般下载好nodeJs后要对npm进行一些初始化配置。 修改npm的镜像源 npm默认的镜像源是https://registry.npmjs.org/&a…

西瓜书学习——线性回归

文章目录 基本格式线性回归一元线性回归多元线性回归 基本格式 f ( x ) w 1 x 1 w 2 x 2 . . . w d x d b f(x) w_1x_1 w_2x_2 ... w_dx_d b f(x)w1​x1​w2​x2​...wd​xd​b 一般可以表达为&#xff1a; f ( x ) w T x b f(x) w^Tx b f(x)wTxb w 和 b 可以通…

【前端】用CSS实现div全屏铺满的方式

在网页设计和开发中&#xff0c;有时我们需要让一个div元素全屏铺满整个浏览器窗口&#xff0c;以实现更加吸引人的视觉效果或者更好地适配不同设备的屏幕大小。 最近遇到一个需求&#xff0c;需要将一个div自动铺满全屏&#xff0c;width会默认铺满&#xff0c;所以不用考虑&…

LeetCode刷题总结 | 图论2—深度优先搜索广度优先搜索较为复杂应用

深搜广搜的标准模版在图论1已经整理过了&#xff0c;也整理了几个标准的套模板的题目&#xff0c;这一小节整理一下较为复杂的DFS&BFS应用类问题。 417 太平洋大西洋水流问题&#xff08;medium&#xff09; 有一个 m n 的矩形岛屿&#xff0c;与 太平洋 和 大西洋 相邻…

opencv图像处理

1、图像膨胀腐蚀 图像的膨胀(dilation)和腐蚀(erosion)主要用来寻找图像中的极大区域和极小区域。 膨胀类似于“领域扩张”&#xff0c;将图像的高亮区域或白色部分进行扩张&#xff0c;其运行结果图比原图的高亮区域更大。 腐蚀类似于“领域被蚕食”&#xff0c;将图像中的…

ElasticSearch有账号密码时: kibana配置

上一篇文章我们介绍过ElasticSearch关闭账号密码的的方式&#xff1a; config/elasticsearch.yml文件中 xpack.security.enabled: false 当我们关闭 账号密码&#xff0c;kibana是可以直接访问ElasticSearch的。 真实项目中&#xff0c;我们是不允许数据库裸跑的&#xff0c;所…

【前端甜点】某视频网站的m4s视频/音频下载方案(20240420)

引言 Sample&#xff1a;aHR0cHM6Ly93d3cuYmlsaWJpbGkuY29tL3ZpZGVvL0JWMWZKNDExUTdWeA 我在很久以前写过一个小脚本&#xff0c;发XHR请求来获取某视频网站的m4s视频和音频&#xff1a; // 唯一要改变的就是url(url must be https)&#xff0c;a.download是文件名&#xff…

【多线程学习】深入探究阻塞队列与生产者消费者模型和线程池常见面试题

˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN 如…

基于CppHttpLib的Httpserver

1 背景 大多数嵌入式设备由于没有屏幕输出&#xff0c;只能通过Web页面来配置。这里利用CPPHttpLib来实现HttpServer。 2 HttpServer HttpServer是利用CPPHttpLib开源库实现的Http服务器CppHttpLib是基于C11的HTTP开源库&#xff0c;开源协议是MIT. CppHttpLib下载地址 2.1 …

(2022级)成都工业学院数据库原理及应用实验六: SQL DML(增、删、改)

写在前面 1、基于2022级软件工程/计算机科学与技术实验指导书 2、成品仅提供参考 3、如果成品不满足你的要求&#xff0c;请寻求其他的途径 运行环境 window11家庭版 Navicat Premium 16 Mysql 8.0.36 实验要求 在实验三的基础上完成下列查询&#xff1a; 1、在科室表…

神经网络进阶学习文章(一)

1.讲解YOLO有关知识 深入浅出Yolo系列之Yolov5核心基础知识完整讲解 - 知乎 (zhihu.com) 2.目标检测算法综述 目标检测算法综述 - 知乎 (zhihu.com) 3.TensorFlow详解&#xff0c;当然现在用的最多的是Pytorch框架了 谷歌大神带你十分钟看懂TensorFlow - 知乎 (zhihu.co…

黑色主题个人主页HTML源码

源码介绍 黑色主题个人主页HTML源码&#xff0c;源码由HTMLCSSJS组成&#xff0c;记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行效果&#xff0c;也可以上传到服务器里面 效果预览 源码下载 黑色主题个人主页HTML源码

js的reduce

在JavaScript中&#xff0c;reduce() 是数组&#xff08;Array&#xff09;对象的一个方法&#xff0c;用于将数组中的所有元素归并成一个单一的输出值&#xff08;通常是数字&#xff0c;但也可以是字符串或其他类型&#xff09;。这个方法通过接收一个函数作为累加器&#xf…

LeetCode题练习与总结:编辑距离--72

一、题目描述 给你两个单词 word1 和 word2&#xff0c; 请返回将 word1 转换成 word2 所使用的最少操作数 。 你可以对一个单词进行如下三种操作&#xff1a; 插入一个字符删除一个字符替换一个字符 示例 1&#xff1a; 输入&#xff1a;word1 "horse", word2…

window cmd/PowerShell 实时查看监控日志命令Get-Content,类似与linux shell的tail命令

命令 最近10行&#xff0c;使用UTF8字符编码 Get-Content app.log -Wait -Tail 10 -Encoding UTF8查找“关键字”&#xff0c;忽略大小写&#xff0c;显示关键字的上下1行 Get-Content app.log -Wait -Tail 10 -Encoding UTF8 | Select-String "keyword" -CaseSen…

clickhouse学习笔记04

ClickHouse高可用之ReplicatedMergeTree引擎介绍 ClickHouse高可用架构准备-环境说明和ZK搭建 RPM安装ClickHouse 上传我们的clickhouse rpm文件。 安装&#xff1a; 中途需要输入用户名和密码 可以不设置 直接回车。 启动&#xff1a; 查看状态&#xff1a; 查看端口是否占用…

【状态压缩 并集查找 图论】2157. 字符串分组

本文涉及知识点 状态压缩 并集查找 图论 LeetCode2157. 字符串分组 给你一个下标从 0 开始的字符串数组 words 。每个字符串都只包含 小写英文字母 。words 中任意一个子串中&#xff0c;每个字母都至多只出现一次。 如果通过以下操作之一&#xff0c;我们可以从 s1 的字母集…