ucos-II在44b0上的移植(解决不断重启问题)
2011-08-23 17:22
267 查看
前一段时间移植UCOS-II到三星的44b0处理器上(源代码使用配套光碟的代码),发现处理器不断重启,找错找了大概一个星期(汗一个),上网找了很久,才找到解决方案。下面说明一下问题所在以及解决方法:
在时钟节拍中断中进行任务切换时,需要用到一个零时存储单元 SAVED_LR 来存储返回地址 lr 。 而 SAVED_LR 原来在 OS_CPU_A.S 中是这样定义的 SAVED_LR DCD 0, 注意没有任何指明 SAVED_LR 在存储空间中的位置的相关代码。这样 SAVED_LR 将被定义在程序代码段中。 当在仿真器上调试时,所有程序代码段都在 SDRAM 中,这样当需要将 lr 保存在 SAVED_LR 中时,实际上是对 SDRAM 进行写操作,该操作成功,程序可以正常运行。
当将生成的 BIN 文件烧写到 FLASH 中后运行是,程序代码段在 FLASH 中,这样当需要将 lr 保存在 SAVED_LR 中时,实际上是对 FLASH 进行写操作,该操作当然不会成功,导致程序不会正常运 行。由 SAVED_LR 定义时知,SAVED_LR 中的内容固化为0,所以对任务堆栈压栈操作时,没有将正确的返回地址压栈,而将返回地址0压栈。最后当第二次调用 OSTimeDlyHMSM() 进行任务切换时,返回地址0弹出到 lr 寄存器,导致系统重启。 解决方法: 将 SAVED_LR 定义到数据段即可。具体操作有多种方法。我是这样做的:在 ucos_ii.h
中定义全局变量OS_EXT INT32U SAVED_LR;, 在OS_CPU_A.S 中引用(加入 IMPORT SAVED_LR),部分代码如下:(SAVED_LR 在内存分配的地址可以用ADS编译软件查看,步骤如下:在DebugRel Settings中选择ARM Linker,然后选择Listings选项卡,在Listings中勾选Symbols即可,最后重新编译工程。在弹出的Errors & Warnings窗口中可查看SAVED_LR 在内存中的地址。)
_CON_SW
LDMIA sp!,{r0-r11,lr}
SUB lr, lr, #4
stmfd sp!, {r0} ;tufei add
ldr r0, =SAVED_LR ;tufei add
STR lr, [r0] ;tufei modify
;STR lr, SAVED_LR ;STR lr, [pc, #SAVED_LR-.-8]
ldmfd sp!, {r0} ;tufei add ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Change Supervisor mode ;!!!r12 register don't preserved. (r12 that PC of task)
MRS lr, SPSR
AND lr, lr, #0xFFFFFFE0
ORR lr, lr, #0x13
MSR CPSR_cxsf, lr ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Now Supervisor mode ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
STR r12, [sp, #-8] ; saved r12
LDR r12, =SAVED_LR ;tufei modify
;LDR r12, SAVED_LR ;LDR r12, [pc, #SAVED_LR-.-8]
ldr r12, [r12] ;tufei add
STMFD sp!, {r12} ; r12 that PC of task
SUB sp, sp, #4 ; inclease stack point
LDMIA sp!, {r12} ; restore r12
STMFD sp!, {lr} ; save lr
STMFD sp!, {r0-r12} ; save register file and ret address
MRS r4, CPSR
STMFD sp!, {r4} ; save current PSR
MRS r4, SPSR ; YYY+
STMFD sp!, {r4} ; YYY+ save SPSR ; OSPrioCur = OSPrioHighRdy
LDR r4, addr_OSPrioCur
LDR r5, addr_OSPrioHighRdy
LDRB r6, [r5]
STRB r6, [r4] ; Get current task TCB address
LDR r4, addr_OSTCBCur
LDR r5, [r4]
STR sp, [r5] ; store sp in preempted tasks's TCB ; Get highest priority task TCB address
LDR r6, addr_OSTCBHighRdy
LDR r6, [r6]
LDR sp, [r6] ; get new task's stack pointer ; OSTCBCur = OSTCBHighRdy
STR r6, [r4] ; set new current task TCB address
LDMFD sp!, {r4} ; YYY+ ;
AND r4, r4, #0xFFFFFF20 ;
ORR r4, r4, #0x13
MSR SPSR_cxsf, r4 ; YYY+
LDMFD sp!, {r4} ; YYY+ ;
AND r4, r4, #0xFFFFFF20 ;
ORR r4, r4, #0x13
MSR CPSR_cxsf, r4 ; YYY+
LDMFD sp!, {r0-r12, lr, pc} ; YYY+
;SAVED_LR DCD 0 ; 注释掉这里的代码
在时钟节拍中断中进行任务切换时,需要用到一个零时存储单元 SAVED_LR 来存储返回地址 lr 。 而 SAVED_LR 原来在 OS_CPU_A.S 中是这样定义的 SAVED_LR DCD 0, 注意没有任何指明 SAVED_LR 在存储空间中的位置的相关代码。这样 SAVED_LR 将被定义在程序代码段中。 当在仿真器上调试时,所有程序代码段都在 SDRAM 中,这样当需要将 lr 保存在 SAVED_LR 中时,实际上是对 SDRAM 进行写操作,该操作成功,程序可以正常运行。
当将生成的 BIN 文件烧写到 FLASH 中后运行是,程序代码段在 FLASH 中,这样当需要将 lr 保存在 SAVED_LR 中时,实际上是对 FLASH 进行写操作,该操作当然不会成功,导致程序不会正常运 行。由 SAVED_LR 定义时知,SAVED_LR 中的内容固化为0,所以对任务堆栈压栈操作时,没有将正确的返回地址压栈,而将返回地址0压栈。最后当第二次调用 OSTimeDlyHMSM() 进行任务切换时,返回地址0弹出到 lr 寄存器,导致系统重启。 解决方法: 将 SAVED_LR 定义到数据段即可。具体操作有多种方法。我是这样做的:在 ucos_ii.h
中定义全局变量OS_EXT INT32U SAVED_LR;, 在OS_CPU_A.S 中引用(加入 IMPORT SAVED_LR),部分代码如下:(SAVED_LR 在内存分配的地址可以用ADS编译软件查看,步骤如下:在DebugRel Settings中选择ARM Linker,然后选择Listings选项卡,在Listings中勾选Symbols即可,最后重新编译工程。在弹出的Errors & Warnings窗口中可查看SAVED_LR 在内存中的地址。)
_CON_SW
LDMIA sp!,{r0-r11,lr}
SUB lr, lr, #4
stmfd sp!, {r0} ;tufei add
ldr r0, =SAVED_LR ;tufei add
STR lr, [r0] ;tufei modify
;STR lr, SAVED_LR ;STR lr, [pc, #SAVED_LR-.-8]
ldmfd sp!, {r0} ;tufei add ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Change Supervisor mode ;!!!r12 register don't preserved. (r12 that PC of task)
MRS lr, SPSR
AND lr, lr, #0xFFFFFFE0
ORR lr, lr, #0x13
MSR CPSR_cxsf, lr ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Now Supervisor mode ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
STR r12, [sp, #-8] ; saved r12
LDR r12, =SAVED_LR ;tufei modify
;LDR r12, SAVED_LR ;LDR r12, [pc, #SAVED_LR-.-8]
ldr r12, [r12] ;tufei add
STMFD sp!, {r12} ; r12 that PC of task
SUB sp, sp, #4 ; inclease stack point
LDMIA sp!, {r12} ; restore r12
STMFD sp!, {lr} ; save lr
STMFD sp!, {r0-r12} ; save register file and ret address
MRS r4, CPSR
STMFD sp!, {r4} ; save current PSR
MRS r4, SPSR ; YYY+
STMFD sp!, {r4} ; YYY+ save SPSR ; OSPrioCur = OSPrioHighRdy
LDR r4, addr_OSPrioCur
LDR r5, addr_OSPrioHighRdy
LDRB r6, [r5]
STRB r6, [r4] ; Get current task TCB address
LDR r4, addr_OSTCBCur
LDR r5, [r4]
STR sp, [r5] ; store sp in preempted tasks's TCB ; Get highest priority task TCB address
LDR r6, addr_OSTCBHighRdy
LDR r6, [r6]
LDR sp, [r6] ; get new task's stack pointer ; OSTCBCur = OSTCBHighRdy
STR r6, [r4] ; set new current task TCB address
LDMFD sp!, {r4} ; YYY+ ;
AND r4, r4, #0xFFFFFF20 ;
ORR r4, r4, #0x13
MSR SPSR_cxsf, r4 ; YYY+
LDMFD sp!, {r4} ; YYY+ ;
AND r4, r4, #0xFFFFFF20 ;
ORR r4, r4, #0x13
MSR CPSR_cxsf, r4 ; YYY+
LDMFD sp!, {r0-r12, lr, pc} ; YYY+
;SAVED_LR DCD 0 ; 注释掉这里的代码
相关文章推荐
- ucos-II在44b0上的移植(解决不断重启问题)
- 【转载】关于2440的MDK平台下移植ucOS2,遇到的问题,及解决办法
- 44B0下ucos-ii的移植
- NodeMCU教程 不断重启问题解决
- stm32移植UCOSIII的空间不足问题解决
- ucos-ii的移植及rtos下的应用API FOR 44B0.txt
- uCOS-II移植 (B OSStartHang)问题 和 多任务不能切换问题
- h-jtag帮我解决ucos-gui在2440上的移植问题
- uCOS-II 移植及遇到的问题
- STM32F103移植UCOS-II时任务切换问题
- linux下的应用程序:关于解决线程的不断重启问题
- uCOS-II 移植及遇到的问题
- 关于联想Y500(美版) win8 用 VMware 9.0 装系统失败,物理机不断重启问题解决
- 记一次Windows Server不断自动重启的问题的解决
- JBOSS Seam 部署时,web不断重启问题的解决
- uCOS-II移植过程出现的问题
- Matlab 7.0不断重启问题解决方法
- 双目视觉嵌入式移植中Opencv程序移植时问题及解决,移植成功啦,哈哈
- Genymotion+VitualBox安装问题解决(个人版+不断总结更新)
- 故障的机器修好后重启,狂拉主库binlog,导致网络问题的解决方法