RT-Thread设备框架学习感悟

前面几周跟着野火的教程从0到1实现了RT-Thread的内核,对RT-Thread的调度机制和线程、定时器的底层实现有了总体的了解。后面还需进一步对齐实现细节进行探索,但大致先了解其框架,后面再进行细致的了解。在学习新知识时,最重要的是思维模式的转变。先了解其大致框架,再深入去了解细节。有些人(就是我,后来太痛苦终于悟了)学一个新知识,刚上来就从头到尾一个字一个字仔细看,生怕错过什么重要的内容,搞不懂关键点就立马停下来去查,一查发现哇!解释内容这么多,看解释的时候又发现有不懂得地方,又停下来去查,如此一环套一环,何时是个头。而且这样学习的结果就是学一个新知识很快就会筋疲力尽,觉得自己什么都不懂,自信心受到打击,从而陷入对自己的深深怀疑之中,最后很可能放弃学习(这种学习方式就像C语言中函数的递归调用,一层套一层,层层套娃,很容易导致栈空间不够用,最后造成程序崩溃。在陈正冲老师的《C语言深度剖析》中,就建议尽量不要使用递归,如果要使用一定要注意递归调用的深度和对应使用的栈空间)!其实你想想看,这些知识是前人付出多少心血才总结出来的,哪可能会让你一上来就搞得门儿清?除非你天赋异禀异于常人。因此在学习新知识的时候,先了解其大概,不求甚解,遇到了问题先保持疑问,带着疑问继续学下去。动手做起来再说,做的好不好,完不完美那是另一回事,先做,在做的过程中逐渐完善。有些人总是思前想后觉得要考虑的周到,完美再去做,这也没错,但是你考虑的就会和实际情况一模一样吗?在做中学习,诸葛亮舌战群儒说笔下虽有千言,而心中实无一策。我们也要做到不能心中虽有千言,而手上丝毫不动。很多问题其实在你学习后面的知识的过程中就自然而然的解决了。还记得去年学习Linux,对Linux的驱动开发、应用开发学的是一知半解,云里雾里。那时还在学习RT-Thread,学了一段时间Linux之后回过头再看RT-Thread发现好多在学习RT-Thread的疑问自然懂了。这就是当你接触了一个高等级的知识后,再回过头去看低等级的知识时发现就豁然开朗了。

比如在深入学习STM32时,你就会发现main函数并不是上电就开始运行的第一个函数,在main函数之前,在startup_xxx.S文件中(基于执行效率的考虑,使用汇编语言编写),系统做了好多事情,如完成堆和栈的内存分配等,最后在跳转到用户main函数运行。假使这个时候你发现汇编语言好像你什么都不会,对ARM的架构也不是很了解,然后买了本汇编语言和ARM-Cortex内核权威指南吭哧吭哧的开始读,希望能先解决掉这两个不懂得内容,你就会发现你看的时候实际上会碰到更多不懂得知识。假使你真的坚持住了,学完了这两本书,肯定你的知识层次会提高很多,但同时和你一块的人早都跑远了。因此,在实际学习新知识时,先了解个大概,后面再去进行细节的完善,当你有一个整个框架的时候再将细节逐渐补齐就会发现是水到渠成。

学习嵌入式的知识更要学会嵌入式的知识过于庞杂,硬件、协议、软件,这每一个都是大部头,如果心里没有规划,遇到什么都想去搞明白、研究透彻,那学来学去就忘记自己究竟想学什么了。确定自己学习的主线,先将该主线补齐,再去深入研究该主线上的分支。

当设计一个产品时,需要使用单片机还是Linux取决于硬件成本和软件成本,而不是一味的根据个人喜好去选择高性能的或套件更完善的,嵌入式中没有最好的,只有最合适的(此处可以参照清华大学曾鸣老师的《嵌入式ARM微控制器》,该课程逻辑清晰,值得反复刷)。因此,既要学会使用MCU跑裸机或RTOS用于一些低端的设备,也要学会Linux用于要求较高的场合。

在上层软件对底层硬件的操作上,单片机和Linux的实现没有太大的区别:

  1. 根据原理图确定是哪个引脚,需要配置该引脚为输入?输出?或交由外设控制?
  2. 查看芯片手册中实现具体功能需要使用到的寄存器
  3. 软件实现操作逻辑,实现既定功能(最终会落实到对寄存器的操作)

在单片机程序中没有程序分层的概念,应用程序和驱动程序混着写,至少没有明确的界限,很可能一个人就包揽了从硬件设计、模块调试(针对各模块进行驱动程序开发,如开发SPI、I2C器件的通讯程序,对外留出调用接口)、功能实现(应用程序开发,即使用接口对外围器件进行操作,程序实现各个功能模块的相互配合,从而实现既定功能)的全部内容,一般小公司都这么干,讲究全能型,什么活都能干,不需要有规范的标准,反正能搞出来,能以最短的时间实现既定的功能需求就是最好的。

Linux程序中驱动程序和应用程序进行了分层,驱动程序访问寄存器,应用程序只能通过驱动程序实现对寄存器的访问,而不能直接去操作寄存器。为什么要设计成应用分层有以下原因?

  • 保证程序运行的安全性

Linux系统比较复杂,庞大,因此其中应用程序很多。如果在软件程序中开发对底层寄存器的访问,那软件的设计不良可能会导致程序运行崩溃。因此在Linux系统中,将对底层寄存器访问的重要工作交给驱动程序去完成(系统认为驱动程序比较靠谱,只相信驱动程序的话,一般驱动程序开发需要即懂硬件又懂软件,从而才能设计出可靠的驱动程序,一般该工作由驱动工程师完成)

  • 保证应用程序的可移植性

驱动程序是和底层硬件直接打交道的,因此驱动程序和硬件之间是强相关的。在A款芯片上开发的驱动程序想在B款芯片上面使用就要修改,因此只要硬件有改动,就需要检查驱动程序是否也需要针对硬件的改动作出修改。而软件程序是和驱动程序打交道的,具体点来说是和驱动程序的调用接口打交道的。只要驱动程序提供的调用接口不变,底层硬件如何改变,应用程序是不会care的,也是不需要作任何修改的。这样做的好处就是,在需要将A款芯片上的程序移植到B款芯片上的时候,只需要根据硬件的变化修改驱动程序,应用程序不需要修改。

  • 程序分层易于团队协作

不像单片机程序,Linux项目一般规模比较大,一个人很难全套都搞定,因此就需要分工协作。将程序分为驱动程序和应用程序有利于团队协作,具体点就是做应用程序的只需关心如何实现业务逻辑,做驱动程序的只需要关心如何能提供对硬件操作的接口。举例假如要做一个人脸识别项目,有擅长做图像处理的,只要能给到他图像,他就能进行图像分析,具体你这个图像是用什么拍的,他是不关心的。而不同摄像头的硬件操作可能是存在差异的,因此使用哪款硬件,驱动工程师就需要针对硬件进行驱动程序的更改。

 

前面对RT-Thread的内核通过从0到1的实现已经有了大概的认识,接下来学习RT-Thread的设备驱动框架,和Linux的驱动树进行类比,其实RT-Thread的很多设计思想和具体实现都有借鉴Linux的设计,好的东西当然大家都要借鉴!因此,学习RT-Thread设备驱动框架又会促进对Linux的设备树的理解。白岩松说过,学习就是这样一个相互作用的过程,当你还不知道你学的知识有什么用的时候,坚持学就完事了。你不知道有什么用是因为你读的书还太少,当你读的书多了,学的知识多了,这些点才会被连起来,到时候就不是零零散散,而会成势。

RT-Thread的设备管理框架如上图所示,可以将以上分为应用层、驱动层、硬件层。RT-Thread的设计思想借鉴了Linux的应用层和驱动层设计理念,因此其设备框架和Linux非常相似,也许以后RT-Thread会引入设备树?

【应用层】应用层只需关心业务逻辑,而不需要关心底层硬件

【驱动层】对应用层提供接口使其可以间接的使用硬件,从而搭建起了应用层和硬件层之间的桥梁,驱动层未实现的硬件驱动应用层无法调用。

【硬件层】具体的硬件,可配置其内部的寄存器实现硬件功能的定制

可以这样去理解,【硬件层】是一堆原材料,【驱动层】是一个工匠,他可以将这些原材料打造成各种各样的工具,【应用层】是人,他只能使用工匠打造好的工具而不能直接去使用原材料。

应用层通过驱动层实现对硬件层设备的访问,驱动层程序的升级更改并不会影响应用层大程序。以此可以实现驱动层程序和应用层程序的低耦合,可独立进行开发。

要使用一个设备,要首先将其注册到I/O设备管理器中,让系统知道其的存在。设备被创建之后需要实现其对硬件的操作方法。根据设备功能的不同,可以选择实现部分操作方法或全部操作方法。

当设备被注册到I/O设备管理器之后,用户应用程序通过I/O设备管理器的接口来访问硬件设备。具体映射关系如下:

应用程序需要对硬件进行操作时可以按照如下步骤:

  1. 查找设备rt_device_t rt_device_find(const char* name);。根据设备名称(字符串)在I/O设备管理器中查找该设备,找到之后返回该设备的句柄(指针)。因此注册设备时需注意不同的设备名称不能重复
  2. 初始化设备rt_err_t rt_device_init(rt_device_t dev);。若该设备已经在之前被初始化成功,调用该接口将不会重复再对设备进行初始化
  3. 打开设备rt_err_t rt_device_open(rt_device_t dev, rt_uint16_t oflags);。打开设备时,系统会检查该设备是否已经被初始化,未被初始化的系统会自动调用初始化接口对设备进行初始化
  4. 读设备rt_size_t rt_device_read(rt_device_t dev, rt_off_t pos,void* buffer, rt_size_t size);

或写设备rt_size_t rt_device_write(rt_device_t dev, rt_off_t pos,const void* buffer, rt_size_t size);或控制设备rt_err_t rt_device_control(rt_device_t dev, rt_uint8_t cmd, void* arg);

5、关闭设备rt_err_t rt_device_open(rt_device_t dev, rt_uint16_t oflags);。打开设备和关闭设备一般需成对使用,因为打开设备会对打开设备次数加1,关闭设备会对打开的设备次数减1。如果不成对使用,则很可能设备并不会被完全关闭。例如调用了2次打开设备后调用1次关闭设备,实际上此时设备并未被关闭,仍是处于打开状态,只有当设备打开次数减为0时才会真正关闭设备。

 

需要注意的是,只有官方提供的BSP包才可以使用ENV工具进行配置。RT-Thread官方已经对主流芯片和开发板进行BSP包支持,因此在实际的项目使用中,我们可以先找自己项目使用的芯片对应的BSP包,再使用ENV工具对内核和功能组件进行配置,使用ENV下载软件包,生成MDK项目工程,在此基础之上进行项目开发。

ENV工具是针对全功能版本的RT-Thread源码进行配置的工具,因此不适用于使用RT-Thread Nano的版本。ENV工具常用的命令也没有几条,用几遍就记住了,记不住搜一下就出来了。

当使用ENV工具在配置工程后重新创建工程时,会发现调试选项会恢复成默认的。针对此问题,在《嵌入式实时操作系统 RT-Thread设计与实现》P193有说明,可以双击打开BSP中的template.uvprojx工程,直接修改其中的调试选项,如此使用Scons命令生成的新工程也会包含对模板文件中的修改。

 

RTT学习--制作BSP2https://blog.csdn.net/weixin_42381351/article/details/91127709

参考如上这篇文章将RT-Thread完整版移植到STM32F105芯片上。

 

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

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

相关文章

Tensorflow之RNN,LSTM

Tensorflow之RNN,LSTM #!/usr/bin/env python2 # -*- coding: utf-8 -*- """ tensorflow之RNN 循环神经网络做手写数据集分类 """import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data#设置随机数来比较两种计算…

python selenium T3

python selenium T3 既然要做自动,就得对得起自动化的这个名字。这一章我们将进一步的增加自动化测试的实用,增加自动发邮件功能、多线程 和定时任务,让我们的自动化工作真正变得高效而又强大起来。 EG1 : with open(report.html , r) as f:msg MIMEText(f.read() , _subtypeh…

RT-Thread中自定义MSH命令传入的参数是字符串,需用户自行检查和解析

如下是在将安富莱的dac8563模块对接到潘多拉开发板RT-Thread SPI设备框架中时导出到RT-Thread的自定义MSH命令,需要注意的是MSH传入的是字符串,需要自行对字符串进行解析处理。 #include "stdlib.h" /* 使用其中的函数:atoi(); */…

水平+垂直布局-css (借鉴)

1. 水平居中 方法一:margin:0 auto; (最常用的居中布局方式)方法二:text-align和inline-block的结合(设置父元素的text-align为center)。 这种方式最好应用于图片、按钮、文字之类的居中模式,否…

安富莱DAC8653模块

产品规格:1、供电电压 : 2.7 - 5.5V 【3.3V供电时,输出电压也可以到正负10V】2、通道数: 2路 (通过1片DAC8563实现)3、输出电压范围 : -10V ~ 10V 【客户可以自己更改为 0-10V输出范围。使…

AD16 SCH原理图打开正常,PCB图纸打开为空白或仍是上一个界面的解决方法

重新安装AD16并激活后,发现SCH图纸打开正常,但打开PCB图纸时要么显示一片空白,要么显示的还是上一屏的内容,重启AD16软件或者重启电脑都没有用。 【问题原因】电脑显卡驱动有问题 【解决方法】更新或重新安装电脑显卡驱动 step…

flex布局应用与踩坑

一、预告本文不是一篇入门的文章所有请符合以下条件的战斗人员绕道: 1、初学前端,对前端的传统布局还不是很熟悉的人 2、后端人员对前端不打算深入学习的同学 二、开篇flex布局原本是好几个月前就一直想学习的东西,当时flex布局还算是比较新鲜…

RT-Thread I/O设备模型

I/O设备指的是嵌入式系统中的一些Input输入/Output输出设备,输入输出设备是嵌入式系统重要的组成部分。输入和输出设备可以看做是计算机系统和外界进行沟通的桥梁,因此在计算机组成原理中输入输出设备是重要的组成部分。 计算机组成原理中的5大组成部分…

如何使用易我数据恢复向导恢复数码相机删除的图片

1 使用"易我数据恢复向导"的高级恢复(务必将数码相机的存储卡取出单独插入SD卡槽,而不是直接用数据线连接到电脑上,这样存储卡才能以磁盘方式显示) 2 选中对应磁盘,点击下一步 3 如果出现"分区参数不正确"提示,直接取消即可开始搜索 4 搜索完…

RT-Thread对GPIO操作两种方式的区别:1)通过设备操作接口2)直接通过通用GPIO设备驱动

在学习RT-Thread设备驱动框架时,看到潘多拉开发板的RT-Thread例程资料中的文档《AN0002-RT-Thread-通用 GPIO 设备应用笔记》有如下描述,因此产生使用文档中未使用的方式1)通过设备操作接口 方法实现GPIO操作的想法! 使用潘多拉开…

英语----情态动词(下)

should 应该 竟然 Youd should go to school right now. I should help him. How should i know. Im surprised tha he that he should be so rude to you. it worries me its a pity. You cant imagine.... ought to // 用在比较严肃的场合 You ought to take car…

清华大学-曾鸣-《ARM微控制器与嵌入式系统》I2C总线(一)

I2C是一种双向2线制同步串行通讯接口,是一类非常经典的串行总线通讯,理解好I2C通讯会帮助理解USB通讯、以太网通讯中的握手、数据帧等环节。 I2C的发展历史: SPI串行通讯主要是由MOTOROLA公司提出的,MOTOROLA公司的半导体部门独立…

清华大学-曾鸣-《ARM微控制器与嵌入式系统》I2C总线(二)

I2C(Inter IC Bus)的通讯数据帧: SCL线无方向区分,SDA线上有数据的流动方向。上图中灰色的代表的是主机向从机发送数据,此时SDA线的电平控制权由主机掌控,从机只能监听该线上的电平状态。白色代表的是从机向…

window.open 和showModalDialog的返回值

方法&#xff1a; 1: 在父级页面 test.aspx 的点击<input type"button" id"btnShow" οnclick"showItem();" value"显示子窗体"/>按钮触发 &#xff0c;然后 &#xff1a; <script language"JavaScript" type&qu…

RT-Thread I2C设备驱动框架的对接使用

I2C和SPI是MCU和板载芯片之间最常用的通讯方式&#xff0c;现在先介绍下I2C总线。I2C的基本原理也很简单&#xff0c;只需要两根线&#xff08;时钟线SCL和信号线SDA&#xff09;即可实现挂载在I2C总线上设备之间的相互通讯。I2C协议并未规定I2C总线上哪个是主机&#xff1f;哪…

给lnmp一键包中的nginx安装openresty的lua扩展

lnmp一键包&#xff08;https://lnmp.org&#xff09;本人在使用之后发现确实好用&#xff0c;能帮助我们快速搭建起lnmp、lamp和lnmpa的web生产环境&#xff0c;因此推荐大家可以多试试。但有的朋友可能需要使用openresty的lua扩展&#xff0c;这篇文章就会教你们怎么在军哥的…

RT-Thread 简介及架构

RT-Thread&#xff0c;全称是 Real Time-Thread&#xff0c;顾名思义&#xff0c;它是一个嵌入式实时多线程操作系统&#xff0c;基本属性之一是支持多任务&#xff0c;允许多个任务同时运行并不意味着处理器在同一时刻真地执行了多个任务。事实上&#xff0c;一个处理器核心在…

Linux中通过Socket文件描述符寻找连接状态介绍

针对下文的总结&#xff1a;socket是一种文件描述符 进程的打开文件描述符表 Linux的三个系统调用&#xff1a;open&#xff0c;socket&#xff0c;pipe 返回的都是一个描述符。不同的进程中&#xff0c;他们返回的描述符可以相同。那么&#xff0c;在同一个进程中&#xff0c;…

iOS HTML标签字符实体,转译字符串归类大全 【转载】

为什么要用转义字符串&#xff1f; HTML中<&#xff0c;>&#xff0c;&等有特殊含义&#xff08;<&#xff0c;>&#xff0c;用于链接签&#xff0c;&用于转义&#xff09;&#xff0c;不能直接使用。这些符号是不显示在我们最终看到的网页里的&#xff0c…

RT-Thread在github上的教程中图片显示不出来问题的解决方法

在github上查看RT-Thread STM32系列BSP制作教程时发现教程中所有的图片都加载不出来&#xff0c;非常影响教程的阅读使用。 使用记事本打开文件&#xff1a; C:\Windows\System32\drivers\etc\hosts 将如下内容复制粘贴到hosts文件末尾&#xff1a; # GitHub Start 140.82.11…