a) (Os_cpu_c.c文件中的OSTaskStkInit()函数)μC/OS-Ⅱ中每个任务都有自己的堆栈,新建立一个任务时,必须初始化该任务的上下文,这些被初始化的上下文放在该任务的堆栈中(任务建立时堆栈中除了放初始化的上下文,还会放其他东西,后边会讲到),将会在任务开始运行时从堆栈中弹出来放到对应的寄存器中。但由于任务未曾运行过,所以一般情况下,除了状态寄存器(它的中断位决定着任务开始运行时中断是否开启)和程序计数器(放置任务的起始地址)必须认真设置之外,任务的上下文被初始化成什么值是无所谓的。但是由于μC/OS-Ⅱ会给新建立的任务传递一个参数,而有的编译器会把前几个参数通过寄存器传递,所以也会涉及到上下文的初始化。
b) (Os_cpu_a.asm文件中的OSStartHighRdy ()函数)μC/OS-Ⅱ总是运行当前处于就绪状态的最高优先级的任务(Highest Priority Task,后边简称为HPT)。系统启动时,需要运行第一个任务,这个任务也必须是当前的HPT,而启动这个HPT的工作是由函数OSStart()执行的。
OSStart()函数先找出当前的HPT,再调用OSStartHighRdy (),在OSStartHighRdy ()中把HPT的上下文从HPT的堆栈中弹出到对应的寄存器中,以启动HPT的运行,即μC/OS-Ⅱ中第一个运行的任务。
c) (Os_cpu_a.asm文件中的OSCtxSw()函数)这个函数执行任务切换的工作,函数中先把当前任务的上下文保存到该任务的堆栈中,再把HPT的上下文弹出到对应的寄存器中,任务切换就完成了。
d) (所有的中断服务函数,即ISR(Interrupt Service Routine))中断处理过程中:○1先保存当前运行任务A的上下文,○2进行具体的中断处理,○3把HPT的上下文弹出到对应的寄存器中,以转入任务HPT运行【注意当A是当前最高优先级任务时,A和HPT是相同的】。
e) (Os_cpu_a.asm文件中的OSIntCtxSw ()函数)这个函数是第(3)点中的○3处调用的,用来检查A是否HPT:○1如果A不是HPT就把HPT的上下文弹出到对应的寄存器中,以转入HPT运行;○2如果A是HPT就返回调用处(即ISR中),在ISR中会把A的上下文弹出到对应的寄存器中,以转入任务A运行。
四、让μC/OS-Ⅱ在MSP430上的移植支持用C语言编写中断处理程序
MSP430的一大特色是对C语言的支持相当好,连中断处理函数也能用C语言方便地实现,很多地方C编译器都已经帮用户做好。可惜的是μC/OS-Ⅱ在MSP430F149上的官方移植程序的中断处理函数必须用汇编语言才能编写,但移植μC\OS-II的其中一个目的就是为了更方便的编写程序,这样就与初衷有所矛盾。虽然也可以用C语言编写函数做中断处理的工作,然后再由汇编语言编写ISR对这个C函数进行调用,但对于一些并不熟悉汇编的用户而言,也是比较麻烦的,特别是当需要向C函数传递参数或获取返回值时,还得清楚从汇编向C函数传递参数的具体规则。所以我决定想办法改变移植的程序,使其在C语言中也能直接编写ISR。我使用的集成开发环境是官方网站提供的CCSv4.0(Code Composer Studio Version 4.0)。