由于操作系统一般都是很大的,而且牵扯的问题比较多,所以此处只是一个大体上的对ucos的总结。
一、 嵌入式操作系统概览嵌入式操作系统的主要好处就是屏蔽了底层硬件的差别,给上层应用提供统一的接口,并管理进程调度和资源(如CPU时间、内存)分配等。并且可以充分利用硬件资源,如在单任务时(大循环结构,如大部分51程序)遇到delay函数时,CPU在空转。而在多任务系统,遇到delay或需等待资源时系统会自动运行下一个任务,等条件满足再回来运行先前的任务,这样就充分利用了CPU,提高了效率。 uC/OS操作系统与裸机程序的最大不同点就在于uC/OS有任务调度,可以根据任务的重要程度(优先级)优先执行重要的任务,从而确保能及时处理最重要的数据。(所以对于一个系统有必要使用OS的判断是能否划分一个个的任务,并且各任务间的耦合很小)
可以思考下裸机程序中断的时候发生的过程。利用堆栈可以很自由的在A、B中切换,如果切换足够快,A、B看以来好像同时在执行,这就是并行,A、B就是任务。如果这个切换操作放到定时器函数中来做,就可以严格按照时间来切换。另外,各个任务之间有存在一定的关系,有逻辑上的先后等,必须引进全局的结构体、变量来标记一些信息,全局的这些数据是不会被释放的,所以所有的任务可以去通过读、写这些数据来实现各个程序块交流信息,实现所谓的同步、互斥。这就是操作系统的原理,而这些不同的通信方式按功能细分就成事件管理、内存管理等。
二、ucos的运行概览首先是主函数,然后是OSInit(),这个函数就是对那些全局的数据结构初始化,建立希望的链表等数据结构,为后面全局变量通信做好准备,并且创建了1-2个系统任务(空闲任务必须,为了不让操作系统返回。统计任务可选),而所谓的创建任务OSTaskCreate就是把一个函数的函数地址、自己的栈建立联系、优先级、任务控制块等弄好,为任务切换做好准备。设置好定时切换的相关信息类似定时器,按照节拍在中断中进行任务切换判断(这个节拍是给延时函数提供计时基准,一个任务的延时时间到或等待的资源满足而进入就绪表就会检查优先级看是否可以执行),可以的话就发生切换,这个时候还没有开启开关,所以等任务创建完成后,启动多任务函数OSStart(),这个函数是让SP指到其中的一个栈,然后出栈就跳到一个任务函数里去了,接下来就是正常的任务运行了。
对于操作系统,主要是任务怎么释放CPU(延时、中断、等待资源),其他的任务怎么获得CPU(进入就绪表),如何找到某个任务(优先级及任务控制列表)。
三、ucos各部分介绍μC/OS-II的各种服务都以任务的形式来出现的。在μC/OS-II中,每个任务都有一个唯一的优先级。它是基于优先级可剥夺型内核,适合应用在对实时性要求较高的地方。
3.1 μC/OS-II的任务μC/OS-II的核心部分就是它的任务,它也是通过任务来对不同事件进行响应和处理的。从代码上来看,μC/OS-II的任务一般为如下形式(C语言描述,后同):
void uCOSTask(void *p)
{
while(1)
{
任务具体的功能;
}
}
创建任务的函数有个是OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio),OSTaskCreate()需要四个参数:task是任务代码的指针,pdata是当任务开始执行时传递给任务的参数的指针,ptos是分配给任务的堆栈的栈顶指针,prio是分配给任务的优先级。
μC/OS-II的任务是在内存中来看,任务由三个部分构成:任务的代码部分、任务堆栈和任务控制块。其中任务控制块保存任务的属性;任务堆栈在任务进行切换时保存任务运行的环境;任务代码部分就是宏观上看到的C语言代码。
嵌入式设备中一般只有一个处理器,所以在某一具体的时刻只能有一个任务占用处理器。μC/OS-II的任务一共有5种状态:睡眠、就绪、运行、等待和中断服务。
3.2 任务控制块μC/OS-II中参与调度和管理的最小单位是任务。而任务是通过任务控制块的形式管理的。任务控制块是一个结构体,它包含了任务的堆栈信息,任务控制块的指针,前一个任务控制块和后一个任务控制块的指针(利用优先级一个个查找是否是要找的任务,所以优先级是唯一的),任务的优先级(根据优先级查找到任务控制块,从而就找到该任务),任务需要等待的时间(任务延时的时候时钟节拍中断来的时候会对等待时间做减,为零的时候就放入就绪表,查看一下是否需要切换)等信息。
任务控制块包含了除了指向任务代码的所有信息。而任务的代码地址在任务运行时是怎么获得的呢?其实,任务代码的地址是通过任务的堆栈储存的。
3.3 任务堆栈任务在创建时候,必须指明该任务的堆栈。任务的堆栈大小由用户根据实际情况自行定义。μC/OS-II的堆栈实际上是一个连续的内存块,任务在创建的时候,由函数OSTaskCreate()将任务的代码和用户为任务定义的堆栈联系起来。由于堆栈按照增长方向可以分为两种类型,故在创建任务的时候调用的堆栈初始化函数实际上也跟微处理器类型有关的。故这些代码也是移植时需要修改的。
3.4系统任务 μC/OS-II提供了两个系统任务:空闲任务和统计任务。其中空闲任务是必要的。因为在某一时刻可能所有的用户任务都不处于就绪状态,这样微处理器会因为没有任何任务运行造成系统崩溃。 |