目前网上已经移植好的基于STM32平台的uCOS-II系统,都是基于MDK编译器的,直接拿到COIDE上面,是不能使用的。
关键的地方,有两处。
1、多重包含。
uCOS_II.C文件中,使用#include包含了多个.c文件,这在MDK下是没有问题的,但是在COIDE却不行,把这些include语句都注释掉就可以了。
2、汇编格式不同。
os_cpu_a.asm文件使用的是Intel汇编,而COIDE下使用的是ARM GCC,而ARM GCC却不支持Intel汇编,所以得把它翻译成AT&T汇编。
首先改一下文件名后缀,os_cpu_a.asm改为os_cpu_a.s。
然后文件内容如下所示:
/*********************** (C) COPYRIGHT 2010 Libraworks *************************
* File Name : os_cpu_a.s
* Author : Librae
* Version : V1.0
* Date : 06/10/2010
* Description : μCOS-II asm port for STM32
*******************************************************************************/
.extern OSRunning @ External references
.extern OSPrioCur
.extern OSPrioHighRdy
.extern OSTCBCur
.extern OSTCBHighRdy
.extern OSIntNesting
.extern OSIntExit
.extern OSTaskSwHook
.global OSStartHighRdy
.global OSCtxSw
.global OSIntCtxSw
.global OS_CPU_SR_Save @ Functions declared in this file
.global OS_CPU_SR_Restore
.global PendSV_Handler
.equ NVIC_INT_CTRL, 0xE000ED04 @ 中断控制寄存器
.equ NVIC_SYSPRI2, 0xE000ED20 @ 系统优先级寄存器(2)
.equ NVIC_PENDSV_PRI,0xFFFF0000 @ PendSV中断和系统节拍中断
@ (都为最低,0xff).
.equ NVIC_PENDSVSET, 0x10000000 @ 触发软件中断的值.
@PRESERVE8
@AREA |.text|, CODE, READONLY
@THUMB
.syntax unified
@.section .text
.thumb
@********************************************************************************************************
@ CRITICAL SECTION METHOD 3 FUNCTIONS
@
@ Description: Disable/Enable interrupts by preserving the state of interrupts. Generally speaking you
@ would store the state of the interrupt disable flag in the local variable 'cpu_sr' and then
@ disable interrupts. 'cpu_sr' is allocated in all of uC/OS-II's functions that need to
@ disable interrupts. You would restore the interrupt disable state by copying back 'cpu_sr'
@ into the CPU's status register.
@
@ Prototypes : OS_CPU_SR OS_CPU_SR_Save(void)@
@ void OS_CPU_SR_Restore(OS_CPU_SR cpu_sr)@
@
@
@ Note(s) : 1) These functions are used in general like this:
@
@ void Task (void *p_arg)
@ {
@ #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
@ OS_CPU_SR cpu_sr@
@ #endif
@
@ :
@ :
@ OS_ENTER_CRITICAL()@ /* cpu_sr = OS_CPU_SaveSR()@ */
@ :
@ :
@ OS_EXIT_CRITICAL()@ /* OS_CPU_RestoreSR(cpu_sr)@ */
@ :
@ :
@ }
@********************************************************************************************************
.section .text.OS_CPU_SR_Save
.weak OS_CPU_SR_Save
.type OS_CPU_SR_Save, %function
OS_CPU_SR_Save:
MRS R0, PRIMASK @读取PRIMASK到R0,R0为返回值
CPSID I @PRIMASK=1,关中断(NMI和硬件FAULT可以响应)
BX LR @返回
.size OS_CPU_SR_Save, .-OS_CPU_SR_Save
.section .text.OS_CPU_SR_Restore
.weak OS_CPU_SR_Restore
.type OS_CPU_SR_Restore, %function
OS_CPU_SR_Restore:
MSR PRIMASK, R0 @读取R0到PRIMASK中,R0为参数
BX LR @返回
.size OS_CPU_SR_Restore, .-OS_CPU_SR_Restore
/**************************************************************************************
@* 函数名称: OSStartHighRdy
@*
@* 功能描述: 使用调度器运行第一个任务
@*
@* 参 数: None
@*
@* 返 回 值: None
**************************************************************************************/
.section .text.OSStartHighRdy
.weak OSStartHighRdy
.type OSStartHighRdy, %function
OSStartHighRdy:
LDR R4, =NVIC_SYSPRI2 @ set the PendSV exception priority
LDR R5, =NVIC_PENDSV_PRI
STR R5, [R4]
MOV R4, #0 @ set the PSP to 0 for initial context switch call
MSR PSP, R4
LDR R4, =OSRunning @ OSRunning = TRUE
MOV R5, #1
STRB R5, [R4]
@切换到最高优先级的任务
LDR R4, =NVIC_INT_CTRL @rigger the PendSV exception (causes context switch)
LDR R5, =NVIC_PENDSVSET
STR R5, [R4]
CPSIE I @enable interrupts at processor level
OSStartHang:
B OSStartHang @should never get here
.size OSStartHighRdy, .-OSStartHighRdy
/**************************************************************************************
@* 函数名称: OSCtxSw
@*
@* 功能描述: 任务级上下文切换
@*
@* 参 数: None
@*
@* 返 回 值: None
***************************************************************************************/
.section .text.OSCtxSw
.weak OSCtxSw
.type OSCtxSw, %function
OSCtxSw:
PUSH {R4, R5}
LDR R4, =NVIC_INT_CTRL @触发PendSV异常 (causes context switch)
LDR R5, =NVIC_PENDSVSET
STR R5, [R4]
POP {R4, R5}
BX LR
.size OSCtxSw, .-OSCtxSw
/**************************************************************************************
@* 函数名称: OSIntCtxSw
@*
@* 功能描述: 中断级任务切换
@*
@* 参 数: None
@*
@* 返 回 值: None
***************************************************************************************/
.section .text.OSIntCtxSw
.weak OSIntCtxSw
.type OSIntCtxSw, %function
OSIntCtxSw:
PUSH {R4, R5}
LDR R4, =NVIC_INT_CTRL @触发PendSV异常 (causes context switch)
LDR R5, =NVIC_PENDSVSET
STR R5, [R4]
POP {R4, R5}
BX LR
NOP
.size OSIntCtxSw, .-OSIntCtxSw
/**************************************************************************************
@* 函数名称: OSPendSV
@*
@* 功能描述: OSPendSV is used to cause a context switch.
@*
@* 参 数: None
@*
@* 返 回 值: None
***************************************************************************************/
.section .text.PendSV_Handler
.weak PendSV_Handler
.type PendSV_Handler, %function
PendSV_Handler:
CPSID I @ Prevent interruption during context switch
MRS R0, PSP @ PSP is process stack pointer 如果在用PSP堆栈,则可以忽略保存寄存器,参考CM3权威中的双堆栈-白菜注
CBZ R0, PendSV_Handler_Nosave @ Skip register save the first time
SUBS R0, R0, #0x20 @ Save remaining regs r4-11 on process stack
STM R0, {R4-R11}
LDR R1, =OSTCBCur @ OSTCBCur->OSTCBStkPtr = SP@
LDR R1, [R1]
STR R0, [R1] @ R0 is SP of process being switched out
@ At this point, entire context of process has been saved
PendSV_Handler_Nosave:
PUSH {R14} @ Save LR exc_return value
LDR R0, =OSTaskSwHook @ OSTaskSwHook()@
BLX R0
POP {R14}
LDR R0, =OSPrioCur @ OSPrioCur = OSPrioHighRdy@
LDR R1, =OSPrioHighRdy
LDRB R2, [R1]
STRB R2, [R0]
LDR R0, =OSTCBCur @ OSTCBCur = OSTCBHighRdy@
LDR R1, =OSTCBHighRdy
LDR R2, [R1]
STR R2, [R0]
LDR R0, [R2] @ R0 is new process SP@ SP = OSTCBHighRdy->OSTCBStkPtr@
LDM R0, {R4-R11} @ Restore r4-11 from new process stack
ADDS R0, R0, #0x20
MSR PSP, R0 @ Load PSP with new process SP
ORR LR, LR, #0x04
CPSIE I
BX LR @ Exception return will restore remaining context
.size PendSV_Handler, .-PendSV_Handler
.end