4月13日期待已久的RT-Thread内核实现与应用开发实战指南基于STM32的书籍到了。之所以期待,是因为这本书是我参加电子工程世界的测评活动得到的书,展示一下收到的书籍。我和野火的缘分还不止这些,学习STM32一年半的时间,野火给了我很大的帮助,展示一下我参考的书籍。 我非常喜欢读野火的《STM32库开发实战指南》的第一章:为什么学习STM32,在第一章的第二节写了嵌入式工程师成长之路。一个人拥有更多的技能,能够做更多的事,一直鼓励着我不断学习。同样在《RT-Thread内核实现与应用开发实战指南》的第二章:为什么学习RTOS里面一句话与大家共勉:作为一个合格的嵌入式软件工程师,学习是永远不能停歇的事,时刻都得为将来准备。书到用时方恨少,我希望机会来临时你不要有这种感觉。接触STM32的时间是在2017年底,可是对于电子行业我在大学大二暑假的时候,参加电子设计竟赛,我的自学能力比较差,对于单片机的应用理解的也少,那次经历只让我有了深深的挫败感。一晃6年过去了,工作一开始没有做技术,直到工作不顺心,压抑。两年前让我坚持选择了做技术。
目前我虽然没有做过实时操作系统的工程,但是以我做过的工程的经验,嵌入式的应用更加广泛,长话短说,我想说一下,我通过《RT-Thread内核实现与应用开发实战指南》这本书,学到了那些RT——Thread的编程思想。在书的第5章讲了裸机系统和多线程系统的区别。裸机系统又分为轮询系统和前后台系统。轮询系统即是在裸机编程的时候,先初始化相关的硬件,然后让主程序在一个死循环里面不断循环,顺序地做各种事情。轮询系统是一种非常简单的软件结构,通常只适用于那些只需要顺序执行代码且不需要外部事件来驱动就能完成的事情。轮询系统只适合顺序执行的功能代码,当有外部事件驱动时,实时性就会降低。前后台系统相比轮询系统,前后台系统是在轮询的基础上加入了中断。外部事件的响应在中断里面完成,事件的处理还是回到轮询系统中完成,中断在这里我们称为前台,main函数里面的无线循环我们称为后台。多线程系统:相比前后台系统,多线程系统的事件响应也是在中断中完成的,但是事件的处理是在线程中完成的。在多线程系统中,线程跟中断一样,也具有优先级,优先级高的线程会被优先执行。当一个紧急的事件在中断被标记之后,如果事件对应的线程的优先级足够高,就会立马得到响应。相比于前后台系统,多线程的实时性又被提高了。在多线程系统中,根据程序的功能,我们把这个程序主体分割成一个个独立的,无限循环且不能返回的小程序,这个小程序我们称之为线程。每个线程都是独立的,互不干扰的,且具备自身的优先级,它由操作系统调度管理。加入操作系统,我们的编程反而变得简单了。整个系统随之带来的额外开销就是操作系统占据的那一丁点的FLASH和RAM。第6章介绍了线程的定义与线程切换的实现,什么是线程?在裸机系统中,系统的主体就是main函数里面顺序执行的无限循环,这个无限循环里面CPU按照顺序完成各种事情。在多线程系统中,我们根据功能的不同,把整个系统分割成一个个独立的且无法返回的函数,这个函数我们称为线程。在线程和裸机系统的区别是:在裸机系统中,如果有全局变量,有子函数调用,有中断发生。那么系统在运行的时候,全局变量放在哪里,子函数调用时,局部变量放在哪里,中断发生时,函数返回地址放在哪里,我们不用管。而写一个RTOS,这些种种环境参数,我们必须弄清楚他们是如何存储的。在裸机系统中,他们统统放在一个叫栈的地方,栈是单片机RAM中里面一段连续的内存空间,栈的大小一般在启动文件或者链接脚本里指定,最后由C库函数main进行初始化。但是,在多线程系统中,每个线程都是独立的,互不干扰的,所以要为每个线程分配独立的空间,这个栈空间通常是一个预先定义好的数组,也可以是动态分配的一段空间,但它们都存在RAM中。在多线程系统中,有多少个线程就需要定义多少个线程栈。线程函数的特点:线程是一个独立的函数,函数主体无限循环且不能返回。线程控制块的定义:在裸机系统中,程序的主体是CPU按照顺序执行的。而在多线程系统中,线程的执行是系统调度的。系统为了顺利的调度线程,为每个线程都额外定义了一个线程控制块,这个线程控制块就相当于线程的身份证,里面存有线程的所有信息,比如线程的栈指针,线程的名称,线程的形参等。有了这个线程控制块就相当于线程之后,以后系统对线程的全部操作都可以通过这个线程控制块来实现。定义一个线程控制块需要一个新的数据类型,该数据类型在rtdef.h这个头文件中声明,使用它可以为每个线程定义一个线程控制块实体。实现线程创建函数:线程的栈,线程的函数实体,线程的控制块最终需要联系起来才能由系统进行统一调度。我们可以写一个初始化函数来实现,这个初始化函数包含初始化线程控制块指针。初始化线程链表节点,线程的入口函数,线程参数,用于指向线程栈的起始地址,以及线程栈的大小。在初始化线程链表节点,往后我们把线程插入到各种链表中,就是通过这个节点来实现的,它就好像是线程控制块里面的一个钩子,可以把线程控制块挂在各种链表中,在初始化之前我们需要在线程控制块中添加一个线程链表节点。链表节点数据类型的节点里面有两个相同类型的节点指针next和prev,分别用来指向链表中的下一个节点和上一个节点。还有如何实现初始化链表节点,在双向链表表头后面插入一个节点,在双向链表表头前面插入一个节点,以及从双向链表删除一个节点。
截止到今天,我只懂得这些,我会利用接下来的时间继续读这本书,来和大家分享。我读书的过程比较慢,方法也不太好,望见谅!
此内容由EEWORLD论坛网友沈婷婷原创,如需转载或用于商业用途需征得作者同意并注明出处
本文来自论坛,点击查看完整帖子内容。