uCosII移植到stm32上的文章和demo已经很多了,细节上建议大家可以看官方的移植文档(
当
然是E文的)。网上流传的各种移植版本基本都是基于官方的移植版本做了小改进。这些改进基本都限制在更适合自己的项目或自己的使用习惯上。当然我也一样,
我的改进是为了搭建一个平台,只要stm32+ucos平台都使用这个版本,无论是我使用或是一起开发者,能更快上手。
uCosII
V2.86版本在cortex-m3的移植上面有bug,具体可以自己google一下。我目前使用的是V2.91版本,建立在stm32
V3.40的库基本上。我是强烈要求(或是强制要求)协同开发者使用库函数,除非在速度要求高的情况下或中断里需要直接操作寄存器,也必须使用库的地址定
义,并要求在后面注明对应的库函数。因为程序不是你一个人看的……例如:
-
-
DMA1->IFCR = DMA1_IT_TC4;
-
-
DMA1_Channel4->CCR &= (u16)(~DMA_CCR1_EN);
好了,进入正题。uCos在stm32上的移植官方的版本是默认不支持中断嵌套的(个人理解),因为其没有调用
NVIC_PriorityGroupConfig这一函数或使用相同的功能语句。stm32在复位的状态下默认进去
NVIC_PriorityGroup_0,即只要子优先级没有主优先级,即先到先处理,同时到达再按优先级处理。
官方在这上面也是留有空间,因为NVIC_PriorityGroupConfig只能调用一次,采用默认状态,开发者可以加入并完善使用中断嵌套。
官方的移植把所有的应用中断入口都指向了
BSP_IntHandler这个函数,并定义了一个函数数组static CPU_FNCT_VOID
BSP_IntVectTbl[BSP_INT_SRC_NBR];因此,如果要加入自己的中断函数的话,只需把自己写的中断函数的指针存入这个数组就
OK了,在初始化中断前调用这函数BSP_IntVectSet。官方的中断优先级设置方式,我全删除了,使用库函数来设置将更直接,但这种中断方式保存
下来,这样中断函数更自由,写中断函数时也不用考虑太多东西,只负责自己要做的东西。
从上代码可以看到,增加了一个全局变量OSIntNeedSW。这个变量的使用是判断退出中断的时候需不需要任务调度,因为你在中断里没有做改变任务优先
级的事,在退出的时候就无需重新调试,如需调度,只需加一个语句 OSIntNeedSW =OSIntSW_Enable;
当然这是临界代码,需关中断。
这一函数必须在开中断前调用一次,初始化必要的变量。
还有两个系统函数必须改动,以实现这功能。在滴答时钟中断中,
-
void OS_CPU_SysTickHandler (void)
-
{
-
OS_CPU_SR cpu_sr;
-
-
-
OS_ENTER_CRITICAL();
-
OSIntNesting++;
-
OSIntNeedSW = OSIntSW_Enable;
-
OS_EXIT_CRITICAL();
-
-
OSTimeTick();
-
-
OSIntExit();
-
}
最后需改动的一个函数是OSIntExit(),
-
void OSIntExit (void)
-
{
-
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
-
OS_CPU_SR cpu_sr = 0u;
-
#endif
-
-
if (OSRunning == OS_TRUE) {
-
OS_ENTER_CRITICAL();
-
if (OSIntNesting > 0u) {
-
OSIntNesting--;
-
}
-
if (OSIntNesting == 0u) {
-
if(OSIntNeedSW == OSIntSW_Enable){
-
OSIntNeedSW = OSIntSW_Disable;
-
if (OSLockNesting == 0u) {
-
OS_SchedNew();
-
OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
-
if (OSPrioHighRdy != OSPrioCur) {
-
#if OS_TASK_PROFILE_EN > 0u
-
OSTCBHighRdy->OSTCBCtxSwCtr++;
-
#endif
-
OSCtxSwCtr++;
-
OSIntCtxSw();
-
}
-
}
-
}
-
}
-
OS_EXIT_CRITICAL();
-
}
-
}
最终目的,通过增加一个OSIntNeedSW全局变量,来判断退出中断时是否需要进行任务调试切换。这样的话,在一般的中断处理函数处理的退出过程更快,缩短无改变任务优先级中断的处理时间。其实这功能在新的版本ucos III中已经实现了。
之前使用的版本我还按网上一些人的做法更改了ucos的移植文件,如下图,这是任务切换的时候,如果不使用OSTaskSwHook可以屏蔽下面四行汇编。,省四条语句。
-
; At this point, entire context of process has been saved
-
PU_PendSVHandler_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 ; Ensure exception return uses process stack
-
CPSIE I
-
BX LR ; Exception return will restore
强烈推荐在调试阶段加入,并开启这宏定义
-
#ifdef USE_FULL_ASSERT
-
-
-
-
-
-
-
-
-
-
-
-
void assert_failed(uint8_t* file, uint32_t line)
-
{
-
-
-
-
-
-
while (1)
-
{}
-
}
-
#endif
阅读(2196) | 评论(0) | 转发(0) |