全文复制到TXT文件,格式问题可解决,感觉论坛的字体太少了,怎么排有排不出来,郁闷了。
1. 要使uCOS-II正常运行,处理器必须满足以下要求:
* 处理器的C编译器能够产生可重入型的代码;
* 处理器支持中断,并且能够产生定时中断,通常为10 ~ 100Hz;
* 用C语言可以开关中断;
* 处理器能支持一定数量的数据存储硬件堆栈;
* 处理器有将堆栈指针已经其他CPU寄存器内容读出,并存储到堆栈或内存中去的指令。
2. uC/OS-II硬件和软件结构体系
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ ┃
┃ 应用软件(用户代码) ┃
┃ ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
┏━━━━━━━━━━━━━━━━━━┓┏━━━━━━━━━━━━━━━━┓
┃ ┃┃ ┃
┃ uC/OS-II ┃┃ uC/OS-II配置 ┃
┃ (与处理器无关的代码) ┃┃ (与应用有关) ┃
┃ ┃┃ ┃
┃ OS_CORE.C ┃┃ ┃
┃ OS_FLAG.C ┃┃ ┃
┃ OS_MBOX.C ┃┃ ┃
┃ OS_MUTEX.C ┃┃ OS_CFG.H ┃
┃ OS_Q.C ┃┃ INCLUDES.H ┃
┃ OS_SEM.C ┃┃ ┃
┃ OS_TASK.C ┃┃ ┃
┃ OS_TIME.C ┃┃ ┃
┃ uCOS_II.C ┃┃ ┃
┃ uCOS_II.H ┃┃ ┃
┃ ┃┃ ┃
┗━━━━━━━━━━━━━━━━━━┛┗━━━━━━━━━━━━━━━━┛
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ ┃
┃ uC/OS-II移植 ┃
┃ (处理器相关代码) ┃
┃ ┃
┃ OS_CPU.H ┃
┃ OS_CPU_A.ASM ┃
┃ OS_CPU_C.C ┃
soft┃ ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
----------------------------------------------------------------------------------
┏━━━━━━━━━━━━━━━━━━━━━┓┏━━━━━━━━━━━━━┓
hard┃ ┃┃ ┃
┃ CPU ┃┃ TIMER ┃
┃ ┃┃ ┃
┗━━━━━━━━━━━━━━━━━━━━━┛┗━━━━━━━━━━━━━┛
3. 移植需要修改的部分
┏━━━━━━━━━━┳━━━━┳━━━━━━┳━━━━━━┳━━━━━━┓
┃ 名称 ┃ 类型 ┃ 所在文件 ┃ 语言类型 ┃ 简单程度 ┃
┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
┃ BOOLEAN ┃数据类型┃ OS_CPU.H ┃ C ┃ SUPER EASY ┃
┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
┃ INT8U ┃数据类型┃ OS_CPU.H ┃ C ┃ SUPER EASY ┃
┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
┃ INT8S ┃数据类型┃ OS_CPU.H ┃ C ┃ SUPER EASY ┃
┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
┃ INT16U ┃数据类型┃ OS_CPU.H ┃ C ┃ SUPER EASY ┃
┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
┃ INT16S ┃数据类型┃ OS_CPU.H ┃ C ┃ SUPER EASY ┃
┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
┃ INT32U ┃数据类型┃ OS_CPU.H ┃ C ┃ SUPER EASY ┃
┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
┃ INT32S ┃数据类型┃ OS_CPU.H ┃ C ┃ SUPER EASY ┃
┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
┃ FP32 ┃数据类型┃ OS_CPU.H ┃ C ┃ SUPER EASY ┃
┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
┃ FP64 ┃数据类型┃ OS_CPU.H ┃ C ┃ SUPER EASY ┃
┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
┃ OS_STK ┃数据类型┃ OS_CPU.H ┃ C ┃ VERY EASY ┃
┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
┃ OS_CPU_SR ┃数据类型┃ OS_CPU.H ┃ C ┃ VERY EASY ┃
┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
┃ OS_CRITCIAL_METHOD ┃ 宏定义 ┃ OS_CPU.H ┃ C ┃ EASY ┃
┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
┃ OS_STK_GROWTH ┃ 宏定义 ┃ OS_CPU.H ┃ C ┃ SUPER EASY ┃
┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
┃ OS_ENTER_CRITICAL()┃ 宏 ┃ OS_CPU.H ┃ C ┃ EASY ┃
┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
┃ OS_EXIT_CRITICAL() ┃ 宏 ┃ OS_CPU.H ┃ C ┃ EASY ┃
┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
┃ OSStartHighRdy() ┃ 函 数 ┃OS_CPU_A.ASM┃ ASM ┃ VERY EASY ┃
┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
┃ OSCtxSw() ┃ 函 数 ┃OS_CPU_A.ASM┃ ASM ┃ EASY ┃
┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
┃ OSIntCtxSw() ┃ 函 数 ┃OS_CPU_A.ASM┃ ASM ┃ EASY ┃
┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
┃ OSTickISR() ┃ 函 数 ┃OS_CPU_A.ASM┃ ASM ┃ EASY ┃
┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
┃ OSTaskStkInit() ┃ 函 数 ┃OS_CPU_C.C ┃ C ┃ EASY ┃
┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
┃ OSInitHookBegin() ┃ 函 数 ┃OS_CPU_C.C ┃ C ┃ SUPER EASY ┃
┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
┃ OSInitHookEnd() ┃ 函 数 ┃OS_CPU_C.C ┃ C ┃ SUPER EASY ┃
┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
┃ OSTaskCreaterHook()┃ 函 数 ┃OS_CPU_C.C ┃ C ┃ SUPER EASY ┃
┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
┃ OSTaskDelHook() ┃ 函 数 ┃OS_CPU_C.C ┃ C ┃ SUPER EASY ┃
┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
┃ OSTCBInitHook() ┃ 函 数 ┃OS_CPU_C.C ┃ C ┃ SUPER EASY ┃
┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
┃ OSTimeTickHook() ┃ 函 数 ┃OS_CPU_C.C ┃ C ┃ SUPER EASY ┃
┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
┃ OSTimeTickHook() ┃ 函 数 ┃OS_CPU_C.C ┃ C ┃ SUPER EASY ┃
┣━━━━━━━━━━╋━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫
┃ OSTaskIdleHook() ┃ 函 数 ┃OS_CPU_C.C ┃ C ┃ SUPER EASY ┃
┗━━━━━━━━━━┻━━━━┻━━━━━━┻━━━━━━┻━━━━━━┛
4. INCLUDES.H
5. OS_CPU.H
5.1.与编译器相关的数据类型
typedef unsigned char BOOLEAN; /* 布尔变量 */
typedef unsigned char INT8U; /* 无符号8位整型变量 */
typedef signed char INT8S; /* 有符号8位整型变量 */
typedef unsigned short INT16U; /* 无符号16位整型变量 */
typedef signed short INT16S; /* 有符号16位整型变量 */
typedef unsigned int INT32U; /* 无符号32位整型变量 */
typedef signed int INT32S; /* 有符号32位整型变量 */
typedef float FP32; /* 单精度浮点数(32位长度)*/
typedef double FP64; /* 双精度浮点数(64位长度)*/
typedef INT32U OS_STK; /* 堆栈是32位宽度 */
/* 兼容UC/OS V1.XX的数据类型,在uC/OS-II中没有使用 */
#define BYTE INT8S
#define UBYTE INT8U
#define WORD INT16S
#define UWORD INT16U
#define LONG INT32S
#define ULONG INT32U
5.2. OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()
5.2.1 #define OS_CRITICAL_MEHTOD 1 /* 定义进入中断的类型 */
实现:直接使用处理器的开关中断指令实现。
优点:最简单的方法,指令关闭中断;
缺点:调用uC/OS-II功能函数后可能将中断开关状态改变。
5.2.2 #define OS_CRITICAL_METHOD 2、
实现:利用堆栈保存PSW中断状态,退出功能函数后恢复PSW
优点:不改变中断状态;
缺点:可能延长应用程序的中断响应时间。
5.2.3 #define OS_CRITICAL_MEHTOD 3
实现:利用编译器本身提供的扩展功能将PSW保存在局部变量中去恢复PSW。*/
优点:简单方便,对中断状态无影响。
缺点:需要编译器支持。
5.3 OS_STK_GROWTH
设置系统堆栈的生长方式。
5.3.1 #define OS_STK_GROWTH 0
设置系统的堆栈方式为向上生长型(低地址向高地址生长)。
5.3.2 #define OS_STK_GROWTH 1
设置系统的堆栈方式位向下生长型(高地址向低地址生长)。
5.3.3 OS_TASK_SW
可以利用软件中断来完成。
6. OS_CPU_C.C
OSTaskStkInit(); /* 惟一必要的函数 */
OSTaskDelHook();
OSTaskSwHook();
OSTaskIdleHook();
OSTaskStatHook();
OSTimeTickHook();
OSTintHookBegin();
OSInitHookBegin();
OSInitHookEnd();
OSTCBInitHook();
6.1 OSTaskStkInit()
OS_STK *OSTaskStkInit (void (*task)(void *pd),
void *pdata,
OS_STK *ptos,
INT16U opt)
{
OS_STK *stk;
opt = opt; /* Avoid complier warnings */
stk = ptos; /* 获取堆栈指针 */
/* ADS1.2使用满递减堆栈 */
*stk = (OS_STK) task; /* pc */
*--stk = (OS_STK) task; /* lr */
*--stk = 0; /* r12 */
*--stk = 0; /* r11 */
*--stk = 0; /* r10 */
*--stk = 0; /* r9 */
*--stk = 0; /* r8 */
*--stk = 0; /* r7 */
*--stk = 0; /* r6 */
*--stk = 0; /* r5 */
*--stk = 0; /* r4 */
*--stk = 0; /* r3 */
*--stk = 0; /* r2 */
*--stk = 0; /* r1 */
*--stk = (unsigned int) pdata; /* r0,第一个参数使用R0传递 */
*--stk = (USER_USING_MODE|0x00); /* spsr,允许 IRQ, FIQ 中断 */
*--stk = 0; /* 关中断计数器OsEnterSum; */
return (stk);
}
┣━━━━━━━━━┫
┃ ┃
┣━━━━━━━━━┫
┃ PC ┃
┣━━━━━━━━━┫
┃ LR ┃
┣━━━━━━━━━┫
┃ R12 ┃
┣━━━━━━━━━┫
┃ R11 ┃
┣━━━━━━━━━┫
┃ R10 ┃
┣━━━━━━━━━┫
┃ R9 ┃
┣━━━━━━━━━┫
┃ R8 ┃
┣━━━━━━━━━┫
┃ R7 ┃
┣━━━━━━━━━┫
┃ R6 ┃
┣━━━━━━━━━┫
┃ R5 ┃
┣━━━━━━━━━┫
┃ R4 ┃
┣━━━━━━━━━┫
┃ R3 ┃
┣━━━━━━━━━┫
┃ R2 ┃
┣━━━━━━━━━┫
┃ R1 ┃
┣━━━━━━━━━┫
┃ R0 ┃
┣━━━━━━━━━┫
┃ CPSR ┃
┣━━━━━━━━━┫
┃ OSEnterSum ┃<------- SP
┣━━━━━━━━━┫
┃ ┃
┣━━━━━━━━━┫
7. OS_CPU_A.ASM
uC/OS-II需要用户编写的4个简单的汇编语言函数:
7.1. OSStartHighRdy()
__OSStartHighRdy
MSR CPSR_c, #(NoInt | SYS32Mode) ;进入管理模式关掉中断
LDR R4, =OSRunning ;告诉OS任务正在运行
MOV R5, #1
STRB R5, [R4]
BL OSTaskSwHook ;调用钩子函数
LDR R6, =OSTCBHighRdy ;获取最高就绪任务堆栈指针的指针
LDR R6, [R6] ;获取新任务堆栈指针
LDR R4, [R6] ;得到确切地址
ADD SP, R4, #68 ;17寄存器CPSR,OsEnterSum,R0-R12,LR,SP
LDR LR, [SP, #-8]
MSR CPSR_c, #(NoInt | SVC32Mode) ;进入管理模式
MOV SP, R4 ;设置堆栈指针
LDMFD SP!, {R4, R5} ;CPSR,OsEnterSum
;恢复新任务的OsEnterSum
LDR R3, =OsEnterSum
STR R4, [R3]
MSR SPSR_cxsf, R5 ;恢复CPSR
LDMFD SP!, {R0-R12, LR, PC }^ ;运行新任务
7.2. OSCtxSw()
OSIntCtxSw
;下面为保存任务环境
LDR R2, [SP, #20] ;获取PC
LDR R12, [SP, #16] ;获取R12
MRS R0, CPSR
MSR CPSR_c, #(NoInt | SYS32Mode)
MOV R1, LR
STMFD SP!, {R1-R2} ;保存LR,PC
STMFD SP!, {R4-R12} ;保存R4-R12
MSR CPSR_c, R0
LDMFD SP!, {R4-R7} ;获取R0-R3
ADD SP, SP, #8 ;出栈R12,PC
MSR CPSR_c, #(NoInt | SYS32Mode)
STMFD SP!, {R4-R7} ;保存R0-R3
LDR R1, =OsEnterSum ;获取OsEnterSum
LDR R2, [R1]
STMFD SP!, {R2, R3} ;保存CPSR,OsEnterSum
;保存当前任务堆栈指针到当前任务的TCB
LDR R1, =OSTCBCur
LDR R1, [R1]
STR SP, [R1]
BL OSTaskSwHook ;调用钩子函数
;OSPrioCur <= OSPrioHighRdy
LDR R4, =OSPrioCur
LDR R5, =OSPrioHighRdy
LDRB R6, [R5]
STRB R6, [R4]
;OSTCBCur <= OSTCBHighRdy
LDR R6, =OSTCBHighRdy
LDR R6, [R6]
LDR R4, =OSTCBCur
STR R6, [R4]
OSIntCtxSw_1
;获取新任务堆栈指针
LDR R4, [R6]
ADD SP, R4, #68 ;17寄存器CPSR,OsEnterSum,R0-R12,LR,SP
LDR LR, [SP, #-8]
MSR CPSR_c, #(NoInt | SVC32Mode) ;进入管理模式
MOV SP, R4 ;设置堆栈指针
LDMFD SP!, {R4, R5} ;CPSR,OsEnterSum
;恢复新任务的OsEnterSum
LDR R3, =OsEnterSum
STR R4, [R3]
MSR SPSR_cxsf, R5 ;恢复CPSR
LDMFD SP!, {R0-R12, LR, PC }^ ;运行新任务
文章评论(0条评论)
登录后参与讨论