#define BYTE INT8S /* Define data types for backward compatibility */
#define UBYTE INT8U /* .to uC/OS V1.xx. Not actually needed for . */
#define WORD INT16S /* ... uC/OS-II. */
#define UWORD INT16U
#define LONG INT32S
#define ULONG INT32U
堆栈单位因为处理器现场的寄存器在任务切换时都将会保存在当前运行任务的堆栈中,所以OS_STK 数据类型应该是和处理器的寄存器长度一致的。
typedef unsigned int OS_STK; /* Each stack entry is 16-bit wide */
堆栈增长方向该设置由编译器选项决定,在本开发中设定堆栈由高地址向低地址增长。
#define OS_STK_GROWTH 1 //define the stack to grow from high to low
2、OS_CPU_C.C 文件
任务堆栈初始化 这里涉及到任务初始化时的一个堆栈设计,也就是在堆栈增长方向上如何定义每个需要保存的寄存器位置,在ARM体系结构下,任务堆栈空间由高至低依次将保存着pc、lr、r12、r11、r10、… r1、r0、CPSR、SPSR。
void *OSTaskStkInit (void (*task)(void *pd), void *pdata, void *ptos, INT16U opt)
{
unsigned int *stk ;
opt = opt; /* 'opt' is not used, prevent warning */
stk = (unsigned int *)ptos; /* Load stack pointer */
*--stk = (unsigned int) task; / * lr */
……; /* r12—r0 */
*--stk = ARM_MODE_SYS; /* system mode */
*--stk = ARM_MODE_SYS; /* system mode */
return ((void *)stk);
}
当前任务堆栈初始化完成后,OSTaskStkInit 返回新的堆栈指针stk,在 OSTaskCreate()执行时将会调用 OSTaskStkInit 的初始化过程,然后通过OSTCBInit()函数调用将返回的sp指针保存到该任务的TCB块中。
OSStartHighRdy() 该函数是在主程序OSStart( )多任务启动后执行,负责从最高优先级任务的TCB控制块中获得该任务的堆栈指针sp,通过sp依次将cpu现场恢复,这时系统就将控制权交给用户创建的该任务进程,仅执行一次,此后多任务优先级调度由下面函数执行。
OSCtxSw() 任务级的上下文切换,它是当任务因为被阻塞而主动请求cpu调度时被执行,由于此时的任务切换都是在非异常模式下进行的,它的工作是先将当前任务的cpu现场保存到该任务堆栈中,然后获得最高优先级任务的堆栈指针,从该堆栈中恢复此任务的cpu现场,使之继续执行。
OSIntCtxSw() 中断级的任务切换,它是在时钟中断ISR(中断服务例程)中发现有高优先级任务等待的时钟信号到来,则在中断退出后直接调度就绪的高优先级任务执行。
OSTickISR() 时钟中断处理函数,它的主要任务是负责处理时钟中断,调用系统实现的OSTimeTick函数,如果有等待时钟信号的高优先级任务,则需要在中断级别上调度其执行。其他相关的两个函数是OSIntEnter()和OSIntExit(),都需要在ISR中执行。
移植完以上程序后,用户就可以结合自己的项目要求来编写自己的应用程序了,用户可以添加如打印、空等待等任务,以下给出了一个例程,通过调用OSTaskCreate ( )函数注册了三个任务,由系统根据最优调度原理进行调度。
void main (void)
{
Initialize(); /* Processor specific initialization */
