uCOS II 在LPC11C14上面的移植方法
电子文档:http://download.youkuaiyun.com/detail/icegoly/5449031
第一:OS_CPU.H的移植 2
1.1 定义与编译器有关的数据类型 2
1.2 定义中断的实现方式 3
1.3 定义栈的生长方式 5
1.4 宏定义 优先级任务切换 6
1.5 定义开、关中断的函数 6
1.6 声明5个函数 6
第二:OS_CPU_C.C的移植 6
2.1 OSTaskStkInt()任务堆栈初始化函数 6
2.2 OSTaskStkInit() 10
2.3 OSTaskCreateHook() 11
2.4 OSTaskDelHook() 11
2.5 OSTaskSwHook() 11
2.6 OSTaskStatHook() 11
2.7 OSTimeTickHook() 11
第三:OS_CPU_A.S的移植 11
3.0 说明: 11
3.0.1 NVIC_INT_CTRL:中断控制和状态寄存器 12
3.0.2 NVIC_SCB_SHPR3系统处理程序优先级寄存器 14
3.0.3:PendSV 15
3.1 实现 中断开、关的汇编 15
3.2 OSStartHighRdy函数移植 16
A:设置PendSV 异常优先级为最低 17
B:初始化PSP设置为0 17
C:设置OSRunning=ture 17
D:触发PendSV 异常 17
E:开中断 18
3.3 OSCtxSw 任务切换 18
3.4 OSIntCtxSw任务切换 18
3.5 OS_CPU_PendSVHandler pendsv异常处理 18
A:获取任务的SP,如果为0 的话则 直接跳到 OS_CPU_PendSVHandler_nosave,去执行 18
B:保存R4-R11和SP 19
C:将当前的堆栈指针给当前进程的任务块 19
D:然后调用OSTaskSwHook 19
E:获取当前的高优先级 20
F获取当前就绪线程 20
G 得到新任务的Sp和恢复从堆栈r4-r11 20
H:载入新的SP和返回 21
第一:OS_CPU.H的移植
1.1 定义与编译器有关的数据类型
| typedef unsigned char BOOLEAN; /* boolean */ typedef unsigned char INT8U; /* Unsigned 8 bit quantity 无符号8位整型变量 */ typedef signed char INT8S; /* Signed 8 bit quantity 有符号8位整型变量 */ typedef unsigned short INT16U; /* Unsigned 16 bit quantity 无符号16位整型变量 */ typedef signed short INT16S; /* Signed 16 bit quantity 有符号16位整型变量 */ typedef unsigned int INT32U; /* Unsigned 32 bit quantity 无符号32位整型变量 */ typedef signed int INT32S; /* Signed 32 bit quantity 有符号32位整型变量 */ typedef float FP32; /* Single precision floating point 单精度浮点数(32位长度) */ typedef double FP64; /* Double precision floating point 双精度浮点数(64位长度) */ typedef unsigned int OS_STK; /* Each stack entry is 32-bit wide 堆栈是32位宽度 */ typedef unsigned int OS_CPU_SR; /* Define size of CPU status register (PSR = 32 bits) */ |
1.2 定义中断的实现方式
| 为了处理临界区代码,必须关中断,等处理完毕后,再开中断。关中断可以避免其他任务或中断进入临界区代码。uC/OS-II定义了这两个宏来实现,但注意一条:调用uC/OS-II功能函数时,中断应该总是开着的。 1)当OS_CRITICAL_METHOD= = 1时,简单实现如下: #define OS_ENTER_CRITICAL() disable_int() #define OS_EXIT_CRITICAL() enable_int() 但这样有一个问题,如果禁止中断的情况下调用uC/OS-II功能函数,那么从功能函数返回时,中断可能变成允许的了,而实际上还是希望是禁止的。 2)当OS_CRITICAL_METHOD= = 2时,实现如下: #define OS_ENTER_CRITICAL() asm(“PUSH PSW”); asm(“DI”); #define OS_EXIT_CRITICAL() asm(“POP PSW”); 执行OS_ENTER_CRITICAL()时,先将中断状态保存到堆栈,然后关中断;执行OS_EXIT_CRITICAL()时,再从堆栈中恢复原来的中断开/关状态。这种方法不会改变中断状态,避免前面的问题。 3)当OS_CRITICAL_METHOD= = 3时,实现如下: #define OS_ENTER_CRITICAL() cpu_sr = get_processor_psw(); disable_interrupts(); #define OS_EXIT_CRITICAL() set_ processor_psw(cpu_sr); ==================== 这里注意的是OS_CRITICAL_METHOD ,ucos提供了3种方法实现,第一种方法是直接简单的开关中断方式,但是一旦嵌套会发生意外,比如: view plaincopy to clipboardprint? ·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150 void Task (void *data) ......... OS_ENTER_CRITICAL(); //进入临界区1 //调用了某一函数,该函数也需要进入临界区: { OS_ENTER_CRITICAL(); ................ OS_EXIT_CRITICAL(); } //这里就自然变成废墟了 ........... //临界区切掉 OS_EXIT_CRITICAL(); } void Task (void *data) {
......... OS_ENTER_CRITICAL(); //进入临界区1 |