嵌入式实时操作系统的一些理解

时间:2022-11-09 19:55:18

说到操作系统,这是是一个我很感兴趣的东西,这可能源于中学时期玩文曲星留下的一些情怀,因为当时对文曲星系统内部构造相当感兴趣,经常用一些16进制显示软件对系统那些犹如乱码般的指令看了又看。
后来上大学了,接触了单片机,虽然到现在先后用过了51、AVR、MSP430、STM32,但这些都仅仅只是用过,让这些MCU做一些简单的事情,老感觉掌握的东西太少,用起来摸不着头脑。在这期间,我一直想自己写一个操作系统,今天,先把理解的东西记录一下。
1、先说说什么是操作系统
现在我没去查资料,用一个手机坐在一个没人来往的楼梯写这些东西,我不想被打扰。
我最开始所理解的操作系统跟现在一般定义的操作系统有些不一样,现在定义的操作系统一般是指实时操作系统,而我以前对于操作系统的概念好像并没上升到多任务,甚至觉得在能力较为单薄的小cpu上,单任务单线程才能真正发挥它的优势。之前我认为,一套这样的软件,将与硬件打交道的一些底层驱动写好,再将一些比较有用的或者通用的程序块写好,把这些程序块与驱动封装好,方便应用层调用,这样的一套软件就可以称为系统,然后加上一些人机交互的接口,显示、键盘输入、文件读写等东西,就可以称作操作系统。
可是后来啊,随着慢慢的理解我发现,大家一直在讨论的操作系统并不是这个。把这些工作做完了,顶多也只是个应用系统,方便后面程序编写的时候调用,这个……一直是单线程在允许啊。哦,原来大家一直在讨论的操作系统其实是在实现一种技术,让一个本质上是单线程的cpu看起来可以同时在做几件事情。后来我又发现,操作系统经过了这样几个过程,批处理操作系统、分时操作系统、实时操作系统。批处理好理解,就是将一些任务排序好,一个一个执行。但是我有很长一段时间没搞明白分时操作系统和实时操作系统的关系,老感觉似乎差不多啊,是不是两种机制现在都在用啊?后来再过一段时间的理解,稍微在这里理顺一下。这个分时操作系统,按理说现在用得比较少了,它是出现在以前电脑很昂贵,好几个人用一台电脑的时候,也就是一台主机,好几个显示器和键盘。这几个人同一段时间在操作电脑,都要打字,这个主机中的分时操作系统呢,这样处理,先让A打一段时间,马上切换成B打一段时间,接着C打一段时间……又A打一段时间,这样操作,如果每段时间都比较短,看起来相当于这几个人同时在操作这台电脑。而实时操作系统是为每个打字的人创建一个进程,然后一个固定的时间片段轮流切换这些进程。呃,不过突然发现这俩貌似区别不大啊,可能是分时操作系统每个任务分配的时间不一样吧,先不管了,写完再去查下资料,总之就是这样一项可以执行多个任务的技术。
2、多线程
终于说到多线程了,手机打字真累。上面说到的多任务,在程序上一般用线程来表示。可是,如何做到线程切换呢?比如我正在执行任务A,突然有命令告诉我得去执行任务B了,那我得先把A这里的任务做个书签吧。执行B任务的时候又接到需要执行任务A了,于是我先在B任务做一个书签然后跳到A任务刚才那个书签的位置执行……
这个“命令”是怎么发出来的呢?有这样两种方式,一种是在每个任务执行到一定程度的时候告诉系统发出命令然后切换任务,一种是系统有个定时器,一段时间后进行任务切换。于是,这就是最简单的多任务原理。
3、具体实现
既然要让程序很奇怪的老是跳过来跳过去的执行,最好还是要与底层打交道,也就是cpu指令了,也就是汇编了。
说实话,虽然用了这么几种单片机,但真正学过汇编的只有51了,既然51最简单,就用51来实现吧。
很长一段时间,我都以为,要操作程序的跳转,得操作PC寄存器,因为它就是指向了CPU下一步该在哪执行。但是后来我发现这样行不通,我要跳转,得写PC吧,写得写两字节吧,写了这字节它就跳了,不会执行下字节的写指令了。怎么办呢?还有一个东西,SP寄存器,堆栈指针,开始我堆栈这个东西只是用来存储一些临时数,后来才发现,我们在用LCALL后,执行完得RET吧,这个RET得回到哪里去呢?其实地址就存在堆栈里。LCALL的时候将LCALL后的地址PUSH到堆栈中,RET的时候再POP到PC寄存器。(呃,这样的话是不是直接操作PC也可以?)总之,操作SP就能让程序按我们的意思任意跳转了。
至于具体代码,现在手机上实在不方便,以后再补上。一般情况下是将操作SP以及一些现场保护的部分用汇编写嵌入到C当中,毕竟我们要用的,也是拿C来写程序。