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

2024-04-22 14:36
文章标签 学习 驱动 框架 设备 rtt

本文主要是介绍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的私有数据域,在对接底层硬件驱动的时候就会方便很多。

这篇关于RTT设备驱动框架学习(CAN设备)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/926046

相关文章

GSON框架下将百度天气JSON数据转JavaBean

《GSON框架下将百度天气JSON数据转JavaBean》这篇文章主要为大家详细介绍了如何在GSON框架下实现将百度天气JSON数据转JavaBean,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录前言一、百度天气jsON1、请求参数2、返回参数3、属性映射二、GSON属性映射实战1、类对象映

Java+AI驱动实现PDF文件数据提取与解析

《Java+AI驱动实现PDF文件数据提取与解析》本文将和大家分享一套基于AI的体检报告智能评估方案,详细介绍从PDF上传、内容提取到AI分析、数据存储的全流程自动化实现方法,感兴趣的可以了解下... 目录一、核心流程:从上传到评估的完整链路二、第一步:解析 PDF,提取体检报告内容1. 引入依赖2. 封装

Unity新手入门学习殿堂级知识详细讲解(图文)

《Unity新手入门学习殿堂级知识详细讲解(图文)》Unity是一款跨平台游戏引擎,支持2D/3D及VR/AR开发,核心功能模块包括图形、音频、物理等,通过可视化编辑器与脚本扩展实现开发,项目结构含A... 目录入门概述什么是 UnityUnity引擎基础认知编辑器核心操作Unity 编辑器项目模式分类工程

Python学习笔记之getattr和hasattr用法示例详解

《Python学习笔记之getattr和hasattr用法示例详解》在Python中,hasattr()、getattr()和setattr()是一组内置函数,用于对对象的属性进行操作和查询,这篇文章... 目录1.getattr用法详解1.1 基本作用1.2 示例1.3 原理2.hasattr用法详解2.

解决若依微服务框架启动报错的问题

《解决若依微服务框架启动报错的问题》Invalidboundstatement错误通常由MyBatis映射文件未正确加载或Nacos配置未读取导致,需检查XML的namespace与方法ID是否匹配,... 目录ruoyi-system模块报错报错详情nacos文件目录总结ruoyi-systnGLNYpe

Python Web框架Flask、Streamlit、FastAPI示例详解

《PythonWeb框架Flask、Streamlit、FastAPI示例详解》本文对比分析了Flask、Streamlit和FastAPI三大PythonWeb框架:Flask轻量灵活适合传统应用... 目录概述Flask详解Flask简介安装和基础配置核心概念路由和视图模板系统数据库集成实际示例Stre

Linux之platform平台设备驱动详解

《Linux之platform平台设备驱动详解》Linux设备驱动模型中,Platform总线作为虚拟总线统一管理无物理总线依赖的嵌入式设备,通过platform_driver和platform_de... 目录platform驱动注册platform设备注册设备树Platform驱动和设备的关系总结在 l

Olingo分析和实践之OData框架核心组件初始化(关键步骤)

《Olingo分析和实践之OData框架核心组件初始化(关键步骤)》ODataSpringBootService通过初始化OData实例和服务元数据,构建框架核心能力与数据模型结构,实现序列化、URI... 目录概述第一步:OData实例创建1.1 OData.newInstance() 详细分析1.1.1

Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式

《Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式》本文详细介绍如何使用Java通过JDBC连接MySQL数据库,包括下载驱动、配置Eclipse环境、检测数据库连接等关键步骤,... 目录一、下载驱动包二、放jar包三、检测数据库连接JavaJava 如何使用 JDBC 连接 mys

Spring 框架之Springfox使用详解

《Spring框架之Springfox使用详解》Springfox是Spring框架的API文档工具,集成Swagger规范,自动生成文档并支持多语言/版本,模块化设计便于扩展,但存在版本兼容性、性... 目录核心功能工作原理模块化设计使用示例注意事项优缺点优点缺点总结适用场景建议总结Springfox 是