专业汽车网站东营网站建设入门

news/2025/9/22 22:39:27/文章来源:
专业汽车网站,东营网站建设入门,云建站的步骤,企业seo推广I/O设备模型 绝大部分的嵌入式系统都包括一些I/O#xff08;Input/Outut#xff0c;输入/输出#xff09;设备#xff0c;例如仪器上的数据显示屏、工业设备上的串口通信、数据采集设备上用于保存数据的Flash或SD卡#xff0c;以及网络设备的以太网接口等。 I/O设备模型…I/O设备模型 绝大部分的嵌入式系统都包括一些I/OInput/Outut输入/输出设备例如仪器上的数据显示屏、工业设备上的串口通信、数据采集设备上用于保存数据的Flash或SD卡以及网络设备的以太网接口等。 I/O设备模型框架 RT-Thread提供了一套简单的I/O设备模型框架如图所示它位于硬件和应用程序之间共分成三层从下到下分别是I/O设备管理层、设备驱动框架层、设备驱动层。 应用程序通过I/O设备管理接口获得正确的设备驱动然后通过这个设备驱动与底层I/O硬件设备进行数据交互。 I/O设备管理层实现了对设备驱动程序的封装。应用程序通过图中的I/O设备管理层提供的标准接口访问底层设备设备驱动程序的升级、更替不会对上层应用产生影响。这种方式使得设备的硬件操作相关的代码能够独立于应用程序而存在双方只需关注各自的功能实现从而降低了代码的耦合型、复杂性提高了系统的可靠性。 设备驱动框架层是对同类硬件设备驱动的抽象将不同厂家的同类硬件设备驱动中相同的部分抽取出来将不同部分留出接口由驱动程序实现。 设备驱动层是一组驱使硬件设备工作的程序实现访问硬件设备的功能。 它负责创建和注册I/O设备对于操作逻辑简单的设备可以不经过设备驱动框架层直接将设备注册到I/O设备管理器中。 设备驱动根据设备模型定义创建出具备硬件访问能力的设备实例将该设备通过rt_device_register()接口注册到I/O设备管理器中。应用程序通过rt_device_find()接口查找到设备然后使用I/O设备管理接口来访问硬件。 对于另一些设备如看门狗等则会将创建的设备实例先注册到对应的设备驱动框架中再由设备驱动框架向I/O设备管理器进行注册主要有以下几点 看门狗设备驱动程序根据看门狗设备模型定义创建出具备硬件访问能力的看门狗设备实例并将该看门狗设备通过rt_hw_watchdog_register()接口注册到看门狗设备驱动框架中。看门狗设备驱动框架通过rt_device_register()接口将看门狗注册到I/O设备管理器中。应用程序通过I/O设备管理接口来访问看门狗设备硬件。 I/O设备模型 RT-Thread的设备模型是建立在内核对象模型基础之上的设备被认为是一类对象被纳入对象管理器的范畴。每个设备对象都是由基对象派生而来每个具体设备都可以继承其父类对象的属性并派生出其私有属性。 struct rt_object {char name[RT_NAME_MAX];rt_uint8_t type;rt_uint8_t flag;rt_list_t list; }; typedef struct rt_object *rt_object_t;struct rt_device {struct rt_obejct 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;/* device call back */rt_err_t (*rx_indicate)(rt_device_t dev, rt_size_t size);rt_err_t (*tx_complete)(rt_device_t dev, void *buffer);/* 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_size_t (*read) (rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size);rt_size_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);void *user_data; }I/O设备类型 enum rt_device_class_type {RT_Device_Class_Char 0, /** character device */RT_Device_Class_Block, /** block device */RT_Device_Class_NetIf, /** net interface */RT_Device_Class_MTD, /** memory device */RT_Device_Class_CAN, /** CAN device */RT_Device_Class_RTC, /** RTC device */RT_Device_Class_Sound, /** Sound device */RT_Device_Class_Graphic, /** Graphic device */RT_Device_Class_I2CBUS, /** I2C bus device */RT_Device_Class_USBDevice, /** USB slave device */RT_Device_Class_USBHost, /** USB host bus */RT_Device_Class_USBOTG, /** USB OTG bus */RT_Device_Class_SPIBUS, /** SPI bus device */RT_Device_Class_SPIDevice, /** SPI device */RT_Device_Class_SDIO, /** SDIO bus device */RT_Device_Class_PM, /** PM pseudo device */RT_Device_Class_Pipe, /** Pipe device */RT_Device_Class_Portal, /** Portal device */RT_Device_Class_Timer, /** Timer device */RT_Device_Class_Miscellaneous, /** Miscellaneous device */RT_Device_Class_Sensor, /** Sensor device */RT_Device_Class_Touch, /** Touch device */RT_Device_Class_PHY, /** PHY device */RT_Device_Class_Security, /** Security device */RT_Device_Class_Unknown /** unknown device */ };其中字符设备、块设备是常用的设备类型它们的分类依据是设备数据与系统之间的传输处理方式。 字符模式设备允许非结构的数据传输即通常数据传输采用串行的形式每次一个字节。字符设备通常是一些简单设备如串口、按键。 块设备每次传输一个数据块例如每次传输512个字节数据。这个数据块是硬件强制性的数据块可能使用某类数据接口或某些强制性的传输协议否则就可能发生错误。 因此有时块设备驱动程序对读或写操作必须执行附加的工作。 当系统服务于一个具有大量数据的写操作时设备驱动程序必须首先将数据分为多个包每个包采用设备指定的数据尺寸。 而在实际过程中最后一部分数据尺寸有可能小于正常的设备块尺寸。 如上图中每个块使用单独的写请求写入到设备中头3个直接进行写操作。 但最后一个数据块尺寸小于设备块尺寸设备驱动程序必须使用不同于前3个块的方式处理最后的数据块。 通常情况下设备驱动程序需要首先执行相对应的设备块的读操作然后把写入数据覆盖到读出数据上然后再把这个“合成”的数据块作为一整个块写回到设备中。 例如块4驱动程序需要先把块4所对应的设备块读出来然后将需要写入的数据覆盖至从设备块读出的数据上使其合并成一个新的块最后再写回到块设备中。 创建和注册I/O设备 驱动层负责创建设备实例并注册到I/O设备管理器中可以通过静态声明的方式创建设备实例也可以用下面的接口进行动态创建 rt_device_t rt_device_create(int type, int attach_size) {int size;rt_device_t device;size RT_ALIGN(sizeof(struct rt_device), RT_ALIGN_SIZE);attach_size RT_ALIGN(attach_size, RT_ALIGN_SIZE);size attach_size;device (rt_device_t)rt_malloc(size);if(device){rt_memset(device, 0x0, sizeof(struct rt_device));device-type (enum rt_device_class_type)type;}return device; }调用该接口时系统会从动态堆内存中分配一个设备控制块大小为struct rt_device和attach_size的和设备的类型由参数type设定。 设备被创建后需要实现它访问硬件的操作方法。 struct rt_device_ops {/* 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_size_t (*read) (rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size);rt_size_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); };init初始化设备。设备初始化完成后设备控制块的flag会被置成已激活状态RT_DEVICE_FLAG_ACTIVATED。如果设备控制块中的flag标志已经设置成激活状态那么再运行初始化接口就会立刻返回而不会重新进行初始化。 rt_err_t rt_device_init(rt_device_t dev) {rt_err_t result RT_EOK;if(dev-init ! RT_NULL){result dev-init(dev);if (result ! RT_EOK){RT_DEBUG_LOG(RT_DEBUG_DEVICE, (To initialize device:%s failed. The error code is %d\n,dev-parent.name, result));}else{dev-flag | RT_DEVICE_FLAG_ACTIVATED;}} }open。打开设备。有些设备并不是系统一启动就已经打开开始运行或者设备需要进行数据收发但如果上层应用还未准备好设备也不应该默认已经使能并开始接收数据。所以建议在写底层驱动程序时在调用open接口时才使能设备。 rt_err_t rt_device_open(rt_device_t dev, rt_uint16_t oflag) {rt_err_t result RT_EOK;RT_ASSERT(dev ! RT_NULL);RT_ASSERT(rt_object_get_type(dev-parent) RT_Object_Class_Device);if(!(dev-flag RT_DEVICE_FLAG_ACTIVATED)){if(device_init ! RT_NULL){result device_init(dev);if (result ! RT_EOK){RT_DEBUG_LOG(RT_DEBUG_DEVICE, (To initialize device:%s failed. The error code is %d\n,dev-parent.name, result));return result;}}dev-flag | RT_DEVICE_FLAG_ACTIVATED;}/* 如果设备是一个独立的设备并且已经打开 */if ((dev-flag RT_DEVICE_FLAG_STANDALONE) (dev-open_flag RT_DEVICE_OFLAG_OPEN)){return -RT_EBUSY;}/* call device_open interface */if (device_open ! RT_NULL){result device_open(dev, oflag);}else{dev-open_flag (oflag RT_DEVICE_OFLAG_MASK);}/* set open flag */if (result RT_EOK || result -RT_ENOSYS){dev-open_flag | RT_DEVICE_OFLAG_OPEN;dev-ref_count;/* dont let bad things happen silently. If you are bitten by this assert,* please set the ref_count to a bigger type. */RT_ASSERT(dev-ref_count ! 0);}return result; }close关闭设备在打开设备时设备控制块会维护一个打开计数在打开设备时进行1操作在关闭设备时进行-1操作当计数器变为0时才会进行真正的关闭操作。 rt_err_t rt_device_close(rt_device_t dev) {rt_err_t result RT_EOK;/* parameter check */RT_ASSERT(dev ! RT_NULL);RT_ASSERT(rt_object_get_type(dev-parent) RT_Object_Class_Device);if(dev-ref_count 0)return -RT_ERROR;dev-ref_count--;if(dev-ref_count ! 0)return RT_EOK;if(dev-close ! RT_NULL)result dev-close(dev);/* set open flag */if (result RT_EOK || result -RT_ENOSYS)dev-open_flag RT_DEVICE_OFLAG_CLOSE;return result; }read。从设备读取数据。参数pos是读取数据的偏移量但是有些设备并不一定需要指定偏移量例如串口设备驱动程序应忽略这个参数。而对于块设备来说pos以及size都是以块设备的数据块大小为单位的。 例如块设备的数据块大小是512而参数中pos10size2那么驱动程序应该返回设备中第10个块从第0个块作为起始共计2个块的数据。这个接口返回的类型是rt_size_t即读到的字节数或块数目。正常情况下应该返回参数中size的数值如果返回零需要设置对应的errno值。 rt_size_t rt_device_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size) {/* parameter check */RT_ASSERT(dev ! RT_NULL);RT_ASSERT(rt_object_get_type(dev-parent) RT_Object_Class_Device);if (dev-ref_count 0){rt_set_errno(-RT_ERROR);return 0;}/* call device_read interface */if(device_read ! RT_NULL)return dev-read(dev, pos, buffer, size);rt_set_errno(-RT_ENOSYS);return 0; }write向设备写入数据。参数pos是写入数据的偏移量。与读操作类似对于块设备来说pos以及size都是以块设备的数据块大小为单位的。这个接口返回的类型是rt_size_t即真实写入数据的字节数或块数目。正常情况下应该会返回参数中 size 的数值如果返回零请设置对应的 errno 值。 rt_size_t rt_device_write(rt_device_t dev,rt_off_t pos,const void *buffer,rt_size_t size) {/* parameter check */RT_ASSERT(dev ! RT_NULL);RT_ASSERT(rt_object_get_type(dev-parent) RT_Object_Class_Device);if (dev-ref_count 0){rt_set_errno(-RT_ERROR);return 0;}/* call device_write interface */if (device_write ! RT_NULL){return device_write(dev, pos, buffer, size);}/* set error code */rt_set_errno(-RT_ENOSYS);return 0; } RTM_EXPORT(rt_device_write);control根据cmd命令控制设备。命令往往是由底层各类设备驱动自定义实现。例如参数RT_DEVICE_CTRL_BLK_GETGEOME意思是获取块设备的大小信息。 rt_err_t rt_device_control(rt_device_t dev, int cmd, void *arg) {/* parameter check */RT_ASSERT(dev ! RT_NULL);RT_ASSERT(rt_object_get_type(dev-parent) RT_Object_Class_Device);/* call device_write interface */if (device_control ! RT_NULL){return device_control(dev, cmd, arg);}return -RT_ENOSYS; } RTM_EXPORT(rt_device_control);当一个动态创建的设备不再需要使用时可以通过如下函数来销毁。 void rt_device_destroy(rt_device_t dev) {rt_object_detach((dev-parent));rt_free(dev); }设备被创建后需要注册到I/O设备管理器中应用程序才能够访问。 rt_err_t rt_device_register(rt_device_t dev, const char *name, rt_uint16_t flags) {if (dev RT_NULL)return -RT_ERROR;if (rt_device_find(name) ! RT_NULL) //应当避免重复注册已经注册的设备已经注册相同名字的设备。return -RT_ERROR;rt_object_init((dev-parent), RT_Object_Class_Device, name);dev-flag flags;dev-ref_count 0;dev-open_flag 0;return RT_EOK; }flags参数支持下列参数 #define RT_DEVICE_FLAG_RDONLY 0x001 /* 只读 */ #define RT_DEVICE_FLAG_WRONLY 0x002 /* 只写 */ #define RT_DEVICE_FLAG_RDWR 0x003 /* 读写 */ #define RT_DEVICE_FLAG_REMOVABLE 0x004 /* 可移除 */ #define RT_DEVICE_FLAG_STANDALONE 0x008 /* 独立 */ #define RT_DEVICE_FLAG_SUSPENDED 0x020 /* 挂起 */ #define RT_DEVICE_FLAG_STREAM 0x040 /* 流模式 */ #define RT_DEVICE_FLAG_INT_RX 0x100 /* 中断接收 */ #define RT_DEVICE_FLAG_DMA_RX 0x200 /* DMA 接收 */ #define RT_DEVICE_FLAG_INT_TX 0x400 /* 中断发送 */ #define RT_DEVICE_FLAG_DMA_TX 0x800 /* DMA 发送 */设备流模式RT_DEVICE_FLAG_STREAM参数用于向串口终端输出字符串当输出字符是\n时自动在前面补一个“\r”。 当设备注销后设备将从设备管理器中移除但不会释放设备控制块占用的内存。 看门狗设备注册示例 struct rt_device_ops {/* 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_size_t (*read) (rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size);rt_size_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); };const static struct rt_device_ops wdt_ops {rt_watchdog_init,rt_watchdog_open,rt_watchdog_close,RT_NULL,RT_NULL,rt_watchdog_control };rt_err_t rt_hw_watchdog_register(struct rt_watchdog_device *wtd,const char *name,rt_uint32_t flag,void *data) {struct rt_device *device;RT_ASSERT(wtd ! RT_NULL);device (wtd-parent);device-type RT_Device_Class_Miscellaneous;device-rx_indicate RT_NULL;device-tx_complete RT_NULL;device-ops wdt_ops;device-user_data data;/* register a character device */return rt_device_register(device, name, flag); }访问I/O设备 应用程序通过I/O设备管理接口来访问硬件设备当设备驱动程序实现后应用程序就可以访问该硬件。 设备驱动框架层在components/drivers里面查找。 设备驱动层在libraries/HAL_Drivers

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

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

相关文章

创新的网站建站企业宣传片拍摄公司

CF785D Anton and School - 2 题意: 给定一个长度≤210^5由(和)组成的字符串,问有多少个子串(可以不连续),前半部分是由(组成后半部分由)组成. 题解: 怎么括号匹配能出这么多题 如何才能不重不漏的选出…

常用的seo查询工具济宁网站建设优化亿峰

1、问题 Android Studio debug调试项目卡在waiting for debugger界面2、解决办法 一开始从启adb服务adb stop-server adb start-server 发现没什么用,然后呢,估计是很多app再运行,然后我就重启了Android studio,问题就解决了如果要是万一还不…

网站 演示代码中国目前最好的搜索引擎

理解线程同步线程的数据访问在并行(多线程)环境中,不可避免地会存在多个线程同时访问某个数据的情况。多个线程对共享数据的访问有下面3种情形:多个线程同时读取数据;单个线程更新数据,此时其他线程读取数据…

微信网页版公众号网站怎么做武夷山网站建设wzjseo

自然语言处理(Natural Language Processing,简称NLP)是计算机科学与语言学中关注于计算机与人类语言间转换的领域。 1. 文本预处理 文本预处理详情 4. RNN模型

ih5做自适应网站淮安企业网站制作

深度优先搜索(Depth-First-Search) 从起点出发,走过的点要做标记,发现有没走过的点,就随意挑一个往前走,走不 了就回退,此种路径搜索策略就称为“深度优先搜索”,简称“深搜”。 其实称为“远度优先搜索”…

做网站要哪些人员佳木斯建设局网站

经过无数次的实验,最终配置了一套比较舒服的主题,审美在不断的提高,但是内在快跟不上了哈 1. 安装主题 先下载资源包,资源包是收费的,算是犒赏吧。 https://download.csdn.net/download/wf19930209/23520618 1.1 更…

网站建设设计费用摊销年限运营实力 网站建设

目录 3.1 情况一:两个表数据一一对应 3.2 情况二:两个表数据并非一一对应 本专栏关于联合查询已建立相应库与表,原文链接如下: 【MySQL】_联合查询基础表-CSDN博客 内连接原文如下: 【MySQL】_内连接-CSDN博客 基…

AI 写代码 “翻车”?人类程序员 “偷笑”?AI能应对我们的问题吗?人工智能到底是“智能”还是“人工”?真相有点意思!

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

每日收获

今天的JAVA主要表达了一个编程思想-分解,并重写编写课程测试题.接下来,准备找<<程序员精炼之道,从小工到专家>>,并完成一部分作业.

网站外包维护一年多少钱做网站需要具备哪些条件

文章目录 复盘与一周总结2967. 使数组成为等数数组的最小代价&#xff08;中位数贪心 回文数判断&#xff09;2968. 执行操作使频率分数最大&#xff08;中位数贪心 前缀和 滑窗&#xff09; 复盘与一周总结 wa穿了第3题&#xff0c;赛时其实想到了思路&#xff1a;中位数贪心…

C++中std::map容器中元素删除方法汇总 - 详解

C++中std::map容器中元素删除方法汇总 - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", &qu…

物理半程与半时问题

本文旨在深入解析匀变速直线运动中常见的“半程问题”和“半时问题”,通过公式推导、多种方法比较以及物理意义的阐释,帮助你理解两者在平均速度上的差异及其内在原因。物理半程与半时问题 本文旨在深入解析匀变速直…

网站展现形式网站seo优化课程

一.简单实例&#xff1a; 1.实例要求 点击按钮&#xff0c;实现 >o<与#-#的转换。 2.步骤 补充&#xff1a;​​​​​​​ 1.如果我想在lambda中修改数据&#xff0c;怎么办&#xff1f; 写上mutable就行。

加盟网站做推广怎么收费营销型网站建设制作推广

文章目录 1. 前言2. 错误情况3. 解决办法3.1 获取gradle下载地址3.2 获取gradle存放目录3.3 替换并删除临时文件3.4 触发Try Again 4. 执行成功 1. 前言 今天调试项目&#xff0c;发现新装的AS&#xff0c;在下载gradle的过程中&#xff0c;一直显示连接失败&#xff0c;Gradl…

成都网站建设设计公司上海网站建设 劲晟

Innodb引擎Innodb引擎提供了对数据库ACID事务的支持&#xff0c;并且实现了SQL标准的四种隔离级别。该引擎还提供了行级锁和外键约束&#xff0c;它的设计目标是处理大容量数据库系统&#xff0c;它本身其实就是基于MySQL后台的完整数据库系统&#xff0c;MySQL运行时Innodb会在…

信息门户网站制作费用辽宁省建设厅网站升级

戳蓝字“CSDN云计算”关注我们哦&#xff01;技术头条&#xff1a;干货、简洁、多维全面。更多云计算精华知识尽在眼前&#xff0c;get要点、solve难题&#xff0c;统统不在话下&#xff01;Gartner公司已列出了2019年及以后影响平台即服务&#xff08;PaaS&#xff09;技术和平…

南京网站优化建站二级域名发放免费

一,安装JBOSS&#xff1a;安装JBOSS很简单。将jboss-4.0.4.GA.zip解压到一个目录(比如d:\ jboss-4.0.4.GA)下即可。提示&#xff1a;保留原来的zip文件&#xff0c;以免在使用过程中出错&#xff0c;还可以恢复到正常状态。二&#xff0c;运行JBOSS:在JBOSS的home目录(即$JBOSS…

9.22 科研小结:不要总是预设成功,失败才是常态

今天早上首先把main和augment的训练测试代码补全,还是不太能独立开发代码,基本功需要多夯实,尤其是一些基本库基本函数的使用,什么时候用axis什么时候用dim,还有就是代码结构思维,在写一个类的时候首先思考它的作…

STM32光强传感器实验详解 - 实践

STM32光强传感器实验详解 - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco&qu…

在CodeBolcks下wxSmith的C++编程教程——从Hello world开始讲述wxSmith使用基础

0.前言 欢迎来到 wxSmith 教程页面!wxSmith 与 Code::Blocks、wxWidgets 和 C++ 编译器相结合,为您提供一种所见即所得的方式来创建具有图形用户界面 (GUI) 的应用程序。该组合形成了一个用于快速应用程序开发 (…