由于计算机技术的进步,单片机系统硬件规模越来越大,功能也越来越强,从而给运行嵌入式操作系统提供了硬件支持。为了更好地管理系统软硬件资源,嵌入式实时操作系统逐渐应用到嵌入式硬件平台。 1 嵌入式实时操作系统(RTOS) 嵌入式实时操作系统是嵌入式系统极为重要的组成部分,是能对整个系统及其操作部件装置等资源进行统一协调、指挥和控制的系统软件。RTOS具有通用操作系统的基本特点,如能够有效管理越来越复杂的系统资源;能够把硬件虚拟化,使得开发人员从繁忙的驱动程序移植和维护中解脱出来;能够提供库函数、驱动程序、工具集以及应用程序。 在嵌入式RTOS环境下,实时应用程序的开发设计过程得到了较大地简化,不需要大的改动就可增加新的功能,而且通过将应用程序分割成若干独立的任务模块,使对实时性要求苛刻的事件都得到了快速、可靠的处理。但是,使用嵌入式RTOS必需增加额外的ROM/RAM开销和2%~5%的CPU负荷。 2 uCOS II简介 2.1 uCOS II的特点 uCOS II是一种公开源代码、结构小巧实时内核的实时操作系统,其内核提供任务调度与管理、时间管理、任务间同步与通信、内存管理和中断服务等功能。它适用于小型控制系统,具有执行效率高、占有空问小、实时性能优良和扩展性强等特点,最小内核可以编译至2k左右。 uCOS II实时内核采用占先式调度策略,不支持时间片轮调度法,核心是始终运行就绪条件下的优先级最高的任务。在uCOS II中每一个任务必须赋予一个明确的并且与其他任务不同的优先级,根据各个任务的优先级,动态地切换各个任务,保证了对实时性的要求。如果希望某个任务的优先级根据条件的变化而发生改变,则可以通过调用改变任务优先级的函数来实现。
2.2 uCOS II的体系结构 uCOS II的体系结构如图1所示。 图1 uCOS II体系结构 uCOS II大部分代码是用c语言写的,只有一些与处理器相关的代码是用汇编语言写的,因为uCOS II在读写处理器寄存器时只能通过汇编语言来实现。 uCOS II内核分为与处理器无关部分和与处理器相关部分,其中与处理器相关的文件有三个:C语言文件OS_CPU.H,OS_CPU_C.C和汇编文件OS_CPU_A.ASM。在用uCOS II作为内核来编写嵌入式测控系统的控制软件之前,必须先完成uCOS II操作系统在微处理器上的移植工作,移植工作主要是修改与处理器相关的文件,使之适合待移植的处理器类型,其它内核文件直接嵌套使用即可。 3 uCOS II在C8051F120上的移植 数据采集系统采用了新华龙公司的C8051F120作为主控芯片,通过A/D接口采集处理传感器输入的温度压力信号。 3.1 OS_CPU.H文件的修改 (1)C8051F120是一种内核为51的单片机,其增长堆栈方向从低地址到高地址,故其堆栈增长方向应定义为1,即 #define OS_STK_ GROWTH 1 (2)定义相关宏。C8051F120有直接开关中断的指令,对临界区的设定直接定义如下: #define OS_ENTER_CRITICAL EA =0 #define OS_EXIT_CRITICAL EA =1 任务切换宏封装了对任务切换函数OSCtxSw()的调用,定义如下: #define OS_TASK_SW OSCtxSw() (3)数据类型的定义。根据C8051F120芯片特点来定义数据类型和数据长度,其定义与常用51内核单片机相同。
3.2 OS_CPU.C文件的修改 (1)添加系统时钟初始化程序 C8051F120采用TIMER0作为系统时钟中断源,其代码为可重入函数: void InitTimer0(void) reentrant {SFRPAGE =0x00;//切换寄存器页 TMOD =TMOD&0xF0; TMOD=TMOD | 0x01;//模式1(16位定时器),仅受TR0控制 TH0=0x70; //定义Tick=50次/秒(即0.02秒/次) TL0=0x00; ET0=1;//允许T0中断 TR0=1; } (2)任务堆栈初始化函数的改写 任务堆栈空间由高至低依次将保存着PSW,ACC,B,DPL,DPH等寄存器。为了使任务的调度一致,初始状态的堆栈实际上是模拟了一次中断发生后的堆栈结构,以便在OSSched()进行任务调度时,从堆栈中恢复刚开始运行时的处理器现场。当前任务堆栈初始化完成后,OSTaskStklnit返回新的堆栈指针stk,在OSTaskCreate()执行时将调用OS_TaskStkInit的初始化过程,然后再通过调用OSTCBInit()将返回的sp指针保存到该任务的TCB块中。
3.3 OS_CPU.ASM文件的修改 OS_CPU.ASM文件是用汇编语言编写的模块,包括大量对处理器寄存器的读写操作,其中主要由4个汇编语言函数:OSStartHighRdy()、OSCtxSw()、OSIntCtxSw()、OSTickISR()组成,每一个函数都需要用PUBLIC声明为可以被外部模块调用。 uCOS II任务的切换,系统寄存器需要频繁完成进栈和出栈操作,为了减少代码编写工作量,在OS_CPU.ASM中根据芯片特点将寄存器的进栈出栈操作定义为宏。
3.4 数据采集任务的实现 为了提高数据采集实时性和可靠性,对每个模拟量数据,uCOS II采用单独的任务来实现。下面给出温度和压力数据采集的实现程序。温度数据采集任务程序: void Task1(void *pada) { mux_select = MUX_CPU_TEMP;//温度数据测量 StartCollect(); For(;;) {read_TEMP_inputs();//数据读入,标度转换 temp_long=ADC0 - 42380/2; temp_long= (temp_long* 200L)/156; cpu_temperature=temp_long; …… OSTimeDly(OS_TICKS_PER_SEC);//任务调度 } } 压力数据采集任务程序: void Task2(void *pada) { mux_select = MUX_CPU_PRESS;//温度数据测量 StartCollect();// start the collecting For(;;) {read_Press_inputs(); press_long= ADC0; press_long= temp_ long; …… OSTimeDly(OS_TICKS_PER_SEC);//任务调度 } }
|