今天看了个 MCS-51的例子,也许是因为对51比较熟悉,看其代码来比较快,对UC/OS-II的认识加深了些,笔记如下:
移植UC/OS-II
OS_CPU_A.ASM
OS_CPU.H
OS_CPU_C.C
OS_CFG.H需要配置一下
*********************************************************************************************************
* 处理器相关代码 MCU-51 (大模式)
* 针对51单片机,只使用方法1(直接开关中断)
*********************************************************************************************************
*/
#define OS_CRITICAL_METHOD 1
#if OS_CRITICAL_METHOD == 1
#define OS_ENTER_CRITICAL() EA=0 //关中断
#define OS_EXIT_CRITICAL() EA=1 //开中断
#endif //成对出现
#define OS_STK_GROWTH 0 //MCU-51堆栈从下往上增长 1=向下,0=向上
//在ARM7 LPC2132上为 1
#define OS_TASK_SW() OSCtxSw() //因为MCU-51没有软中断指令,所以用程序调用代替。两者的堆栈格式相同,
//RETI指令复位中断系统,RET则没有。实践表明,对于MCU-51,用子程序调
//用入栈,用中断返回指令RETI出栈是没有问题的,反之中断入栈RET出栈则
//不行。总之,对于入栈,子程序调用与中断调用效果是一样的,可以混用。
//在没有中断发生的情况下复位中断系统也不会影响系统正常运行。
//详见《uC/OS-II》第八章193页第12行
#define OS_ISR_PROTO_EXT 1
void OSCtxSw(void);
void InitHardware(void) reentrant; //初始化硬件时钟中断等,系统初始化工作 reentrant 可重入
#endif //_OS_CPU_H
//======================OSCtxSw在OS_CPU_A.。ASM中实现。
OSStack:
DS 40H
OSStkStart IDATA OSStack-1
PUSHALL MACRO ;定义压栈出栈宏
PUSH ACC
PUSH B
PUSH DPH
PUSH DPL
PUSH PSW
MOV A,R0 ;R0-R7入栈
PUSH ACC
MOV A,R1
PUSH ACC
MOV A,R2
PUSH ACC
MOV A,R3
PUSH ACC
MOV A,R4
PUSH ACC
MOV A,R5
PUSH ACC
MOV A,R6
PUSH ACC
MOV A,R7
PUSH ACC
;PUSH SP ;不必保存SP,任务切换时由相应程序调整
ENDM
。。。
OSCtxSw:
PUSHALL
/* *********************************************************************************************************
* 与ARM7体系结构相关的一些定义
**********************************************************************************************************/
#define OS_CRITICAL_METHOD 2 /* 选择开、关中断的方式 */
__swi(0x00) void OS_TASK_SW(void); /* 任务级任务切换函数 */
__swi(0x01) void _OSStartHighRdy(void); /* 运行优先级最高的任务 */
__swi(0x02) void OS_ENTER_CRITICAL(void); /* 关中断 */
__swi(0x03) void OS_EXIT_CRITICAL(void); /* 开中断 */
__swi(0x40) void *GetOSFunctionAddr(int Index); /* 获取系统服务函数入口 */
__swi(0x41) void *GetUsrFunctionAddr(int Index);/* 获取自定义服务函数入口 */
__swi(0x42) void OSISRBegin(void); /* 中断开始处理 */
__swi(0x43) int OSISRNeedSwap(void); /* 判断中断是否需要切换 */
__swi(0x80) void ChangeToSYSMode(void); /* 任务切换到系统模式 */
__swi(0x81) void ChangeToUSRMode(void); /* 任务切换到用户模式 */
__swi(0x82) void TaskIsARM(INT8U prio); /* 任务代码是ARM代码 */
__swi(0x83) void TaskIsTHUMB(INT8U prio); /* 任务代码是THUMB */
#define OS_STK_GROWTH 1 /* 堆栈是从上往下长的 */
/******************************************MCS-51******************************************************/
/*
设置硬件寄存器的初始值。
初始化定时器0,作为ucOS-II的系统时钟。
还有其他的与硬件相关的初始化也可以放在这里。
*/
void InitHardware(void) reentrant
{
TMOD=TMOD&0xF0;
TMOD=TMOD|0x01; //模式1(16位定时器),仅受TR0控制
TH0=0xB8; //普通51定时器方式1,必须在发生中断时,重新赋值并再次启动计时
TL0=0; //Tick=50次/秒(即0.02秒/次),晶振11.0592M
TR0 = 1;
ET0=1; //开时钟节拍中断
}
////////////===============================ARM7中-==============================
问题:没有弄明白OS_TASK_SW是怎么实现的
void SWI_Exception(int SWI_Num, int *Regs)
{
OS_TCB *ptcb;
switch(SWI_Num)
{
//case 0x00: /* 任务切换函数OS_TASK_SW,参考os_cpu_s.s文件 */
// break;
//case 0x01: /* 启动任务函数OSStartHighRdy,参考os_cpu_s.s文件 */
// break;
case 0x02: /* 关中断函数OS_ENTER_CRITICAL(),参考os_cpu.h文件 */