嵌入式实时操作系统 μC/OS-II 在S12单片机上的移植
和功能 公共头文件INCLUDES.H,这个文件会被所有的C 源程序引用。在本例中此文件的代码如下。 #include #include #include #include #include #include #include 前四个头文件是C 函数库、预定义的类型等,和移植没有关系,是否一定要加取决于所用的编译器。后三个头文件必须被引用,用户可以添加自己的头文件,但一定要放 在最后面。 需要根据应用修改的文件是OS_CFG.H,这个文件用于配置内核的属性。用于设置与微控制器CPU 核心相关的属性,包括各种数据类型对应的存储长度等等。OS_CPU.H 包括了用#define 语句定义的、与处理器相关的常数、宏及类型等。因为不同的处理器有不同的字长,所以μC/OS-II 的移植包括的一系列数据类型定义,以确保其可移植性。μC/OS-II 代码不使用语言中的short,int,及long 等数据类型,因为它们是与编译器相关的,是不可移植的。采用定义的整形数据结构等既是可移植的,又很直观。 typedef unsigned char BOOLEAN; /* 布尔变量*/ typedef unsigned char INT8U; /* 无符号8 位整型变量*/ typedef signed char INT8S; /* 有符号8 位整型变量 */ typedef unsigned int INT16U; /* 无符号16 位整型变量*/ typedef signed int INT16S; /* 有符号16 位整型变量*/ …… 用户还必须将任务堆栈的数据类型告诉给μC/OS-II。S12CPU 的是堆栈是16 位的,所以定义OS_STK 为INT16U。所有的任务堆栈都必须用OS_STK 来声明数据类型。 #define OS_STK INT16U /* 堆栈是16 位宽度*/ 对于不同的处理器而言,数据入堆栈时堆栈指针的增长方向也是不一样的,MC9S12DG128 单片机的堆栈指针是由高地址向低地址增长的,所以,要预先设定堆栈的 增长方向: #define OS_STK_GROWTH 1 /*堆栈指针由高地址向低地址增长*/ μC/OS-II 需要先禁止中断再访问代码的临界段,并且在访问完毕后重新允许中断。这就使得μC/OS-II 能够保护临界段代码免受多任务或中断服务例程的破坏。禁止和允 许中断的宏是OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL(),定义这两个宏的有三种方法,移植时采用的是方法1,进入临界代码前关中断,脱离临界代码后开中断[2]。方法1在OS_CPU.H 中是这样定义的: #if OS_CRITICAL_METHOD == 1 //方法一 #define OS_ENTER_CRITICAL( ) asm SEI #defien OS_EXIT_CRITICAL () asm CLI #endif 3.2 编写与硬件相关的代码 接下来需要编写与硬件相关的代码。这部分代码可以用C 语言,也可以用汇编语言。移植中与硬件相关的文件中最主要的是OS_CPU_C.C 和汇编文件OS_CPU_A.ASM。由于移植使用的是Metrowerks 公司提供的CodeWarrior CW12 V4.6 版本的C 交叉编译工具,而CW12 V4.6 允许在C 代码中插入汇编语句,所以可以把OS_CPU_A.ASM 这个文件合并 到OS_CPU_C.C 文件中去。以下是具体的移植过程。 3.2.1 中断服务子程序OSTickISR() 中断服务子程序所使用的中断可以用实时时钟产生,也可以用单片机片内的定时器模块来产生。本次移植采用的是用模数计数器产生精确时钟节拍中断,用S12 的模数计数器可以实现任意时间的精确中断,这里的中断为每秒30 次。 时钟节拍中断发生时,CPU12 会自动CPU 把CPU 寄存器推入堆栈,然后是清中断标志。但是页面寄存器PPAGE 并没有被推入堆栈,如果CPU12 的寻址范围超过了64KB,则要把PPAGE 也推入堆栈,本文中没有用到PPAGE 寄存器。 时钟节拍中断服务子程序可能激活一个优先级高于当前被中断任务的优先级的任务。时钟节拍中断服务子程序要连续调用:OSIntEnter()、OSTimerTick()和OSIntExit() 这三个函数。OSIntEnter()通知μC/OS-II 进入中断服务子程序了。OSTimerTick()给要求延迟若干时钟节拍的任务延迟计数器减1,减1 后为0 则该任务进入就绪态。 OSIntExit()函数告诉μC/OS-II 时钟节拍中断服务子程序结束了,如果这时有更高优先级的任务进入了就绪态,OSIntExit()就会调用中断级的任务切换函数OSIntCtxSw() 做任务切换,以便让更高的优先级的任务运行。以下是函数代码: void OSTickISR(void) { /*根据需要决定是否保存PPAGE 寄存器,此处没有保存*/ OSIntEnter(); MCFLG_MCZF=1; //清除模计数器中断标志位 OSTimeTick(); OSIntExit(); //退出中断并进行任务切换 } 3.2.2 任务堆栈初始化函数OSTaskStkInit() 这个C语言写的函数是与CPU硬件相关的。这个函数初始化任务的堆栈,由建立任务的函数OSTaskCreate()或扩展的建立任务函数OSTaskCreatExit()调用。建立任务的函数带有4个形式参数,扩展的建立任务的函数有8个参数。其中pdata用于向任务传递参数。利用了这个参数将
- VxWorks实时操作系统下MPC8260ATM驱动的实现(11-11)
- VXWORKS内核分析(11-11)
- 嵌入式实时操作系统设计探讨(10-15)
- 嵌入式实时操作系统μC/OS-II 在P89V51RD2中的移植(04-09)
- LPC2292的伪中断与伪中断处理(03-25)
- 网络处理器IP2022及其在嵌入式牌照识别系统中的应用设计(05-16)