stm32上ucosii的工作流程从启动代码到ucosii的汇编
本文章介绍在stm32上也就是cortex m3核的基础上ucosii是如何运行起来的。
打卡启动代码 xx_cl.s
首先stm32起来后首先进入启动代码,
; Reset handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
启动代码中,系统初始化完成,然后在 dummy exception中唤醒一些中断,其中ucosii用到的系统滴答中断和cpu任务挂起切换的中断。按着箭头往下走。
DebugMon_Handler\
PROC
EXPORT DebugMon_Handler [WEAK]
B .
ENDP
OS_CPU_PendSVHandler\
PROC
EXPORT OS_CPU_PendSVHandler [WEAK]
B .
ENDP
SysTick_Handler PROC
EXPORT SysTick_Handler [WEAK]
B .
ENDP
关于这两个函数的位置,OS_CPU_PendSVHandler这个在os_cpu_a.asm里边有实体定义
OS_CPU_PendSVHandler
CPSID I ; Prevent interruption during context switch
MRS R0, PSP ; PSP is process stack pointer
CBZ R0, OS_CPU_PendSVHandler_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
OS_CPU_PendSVHandler_nosave
PUSH {R14} ; Save LR exc_return value
LDR R0, =OSTaskSwHook ; OSTaskSwHook();
BLX R0
POP {R14}
这个就是关中断,压入堆栈切换任务,OSTCBCur就是当前要切换任务的指针。
Sysytickhandler右键单击即可进入他的实体定义,我们定义在it.c里边,当然也有其他版本不在it.c里边的。
void SysTick_Handler(void)
{
OSIntEnter();
OSTimeTick();
OSIntExit();
}
这个函数就是一个1s延时中断,为ucosii提供时钟心脏。
接下来看main函数
int main(void)
{
INT8U ret = 0;
BspInit();
OSInit(); //uCOS-II
ret = OSTaskCreate( Start_Task,
(void*)0, &Start_TaskStk[PRIO_START_TASK_STK_SIZE-1],
PRIO_START_TASK); /
if (ret != OS_ERR_NONE)
{
OSStart();
}
Main里边就一个外设初始化和ucosii初始化,OSStart(); 是正式开始进入任务调度了,
void OSStart (void)
{
if (OSRunning == OS_FALSE) {
OS_SchedNew(); /* Find highest priority's task priority number */
OSPrioCur = OSPrioHighRdy;
OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; /* Point to highest priority task ready to run */
OSTCBCur = OSTCBHighRdy;
OSStartHighRdy(); /* Execute target specific code to start task */
}
}
开始时是吧优先级最高的赋给当前的任务指针OSTCBCur ,然后进入OSStartHighRdy();这个函数,这个函数又在cpu_.a.asm里边预定义。
OSStartHighRdy
LDR R0, =NVIC_SYSPRI14 ; Set the PendSV exception priority
LDR R1, =NVIC_PENDSV_PRI
STRB R1, [R0]
MOVS R0, #0 ; Set the PSP to 0 for initial context switch call
MSR PSP, R0
LDR R0, =OSRunning ; OSRunning = TRUE
MOVS R1, #1
STRB R1, [R0]
LDR R0, =NVIC_INT_CTRL ; Trigger the PendSV exception (causes context switch)
LDR R1, =NVIC_PENDSVSET
STR R1, [R0]
CPSIE I ; Enable interrupts at processor level
OSStartHang
B OSStartHang
程序能顺利的跑到这里基本就ok了。
文档下载地址 链接:http://pan.baidu.com/s/1o7lxrYi 密码:pfou