赞
踩
最近在工作过程中 使用stm32f4 + ucosiii开发
在使用sqrt的时候 发现总会跑进hardfault
一开始以为是没有使用FPU 导致浮点运算不了 后来单独实验 在不使能FPU 的情况下 浮点也可正常运算
然后发现裸机的话可以正常运行 跑系统就不行
将问题定位到ucos端 寻找资料 是ucosiii 代码问题 现mark一下
UCOSIII版本为V3.03
主要修改3个点,红色为修改内容。
1.stm32f4的启动文件
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
LDR R0,=0xE000ED88 ;使能FPU CP10 CP11
LDR R1,[R0]
ORR R1,R1,#(0XF << 20)
STR R1,[R0]
DSB
LDR.W R0,=0xE000EF34
LDR R1,[R0]
AND R1,R1,#(0x3FFFFFFF)
STR R1,[R0]
ISB
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
2.修改os_cpu.c
CPU_STK *OSTaskStkInit (OS_TASK_PTR p_task,
void *p_arg,
CPU_STK *p_stk_base,
CPU_STK *p_stk_limit,
CPU_STK_SIZE stk_size,
OS_OPT opt)
{
CPU_STK *p_stk;
(void)opt; /* Prevent compiler warning */
p_stk = &p_stk_base[stk_size]; /* Load stack pointer */
/* Registers stacked as if auto-saved on exception */
//#if (__FPU_PRESENT==1)&&(__FPU_USED==1) /* Registers stacked as if auto-saved on exception */
*(--p_stk) = (CPU_STK)0x00000000u; //No Name Register
*(--p_stk) = (CPU_STK)0x00001000u; //FPSCR
*(--p_stk) = (CPU_STK)0x00000015u; //s15
*(--p_stk) = (CPU_STK)0x00000014u; //s14
*(--p_stk) = (CPU_STK)0x00000013u; //s13
*(--p_stk) = (CPU_STK)0x00000012u; //s12
*(--p_stk) = (CPU_STK)0x00000011u; //s11
*(--p_stk) = (CPU_STK)0x00000010u; //s10
*(--p_stk) = (CPU_STK)0x00000009u; //s9
*(--p_stk) = (CPU_STK)0x00000008u; //s8
*(--p_stk) = (CPU_STK)0x00000007u; //s7
*(--p_stk) = (CPU_STK)0x00000006u; //s6
*(--p_stk) = (CPU_STK)0x00000005u; //s5
*(--p_stk) = (CPU_STK)0x00000004u; //s4
*(--p_stk) = (CPU_STK)0x00000003u; //s3
*(--p_stk) = (CPU_STK)0x00000002u; //s2
*(--p_stk) = (CPU_STK)0x00000001u; //s1
*(--p_stk) = (CPU_STK)0x00000000u; //s0
//#endif
*--p_stk = (CPU_STK)0x01000000u; /* xPSR */
*--p_stk = (CPU_STK)p_task; /* Entry Point */
*--p_stk = (CPU_STK)OS_TaskReturn; /* R14 (LR) */
*--p_stk = (CPU_STK)0x12121212u; /* R12 */
*--p_stk = (CPU_STK)0x03030303u; /* R3 */
*--p_stk = (CPU_STK)0x02020202u; /* R2 */
*--p_stk = (CPU_STK)p_stk_limit; /* R1 */
*--p_stk = (CPU_STK)p_arg; /* R0 : argument */
/* Remaining registers saved on process stack */
//#if (__FPU_PRESENT==1)&&(__FPU_USED==1)
*(--p_stk) = (CPU_STK)0x00000031u; //s31
*(--p_stk) = (CPU_STK)0x00000030u; //s30
*(--p_stk) = (CPU_STK)0x00000029u; //s29
*(--p_stk) = (CPU_STK)0x00000028u; //s28
*(--p_stk) = (CPU_STK)0x00000027u; //s27
*(--p_stk) = (CPU_STK)0x00000026u; //s26
*(--p_stk) = (CPU_STK)0x00000025u; //s25
*(--p_stk) = (CPU_STK)0x00000024u; //s24
*(--p_stk) = (CPU_STK)0x00000023u; //s23
*(--p_stk) = (CPU_STK)0x00000022u; //s22
*(--p_stk) = (CPU_STK)0x00000021u; //s21
*(--p_stk) = (CPU_STK)0x00000020u; //s20
*(--p_stk) = (CPU_STK)0x00000019u; //s19
*(--p_stk) = (CPU_STK)0x00000018u; //s18
*(--p_stk) = (CPU_STK)0x00000017u; //s17
*(--p_stk) = (CPU_STK)0x00000016u; //s16
//#endif
*--p_stk = (CPU_STK)0x11111111u; /* R11 */
*--p_stk = (CPU_STK)0x10101010u; /* R10 */
*--p_stk = (CPU_STK)0x09090909u; /* R9 */
*--p_stk = (CPU_STK)0x08080808u; /* R8 */
*--p_stk = (CPU_STK)0x07070707u; /* R7 */
*--p_stk = (CPU_STK)0x06060606u; /* R6 */
*--p_stk = (CPU_STK)0x05050505u; /* R5 */
*--p_stk = (CPU_STK)0x04040404u; /* R4 */
#if (OS_CPU_ARM_FP_EN == DEF_ENABLED)
if ((opt & OS_OPT_TASK_SAVE_FP) != (CPU_INT16U)0) {
*--p_stk = (CPU_STK)0x02000000u; /* FPSCR */
/* Initialize S0-S31 floating point registers */
*--p_stk = (CPU_STK)0x41F80000u; /* S31 */
*--p_stk = (CPU_STK)0x41F00000u; /* S30 */
*--p_stk = (CPU_STK)0x41E80000u; /* S29 */
*--p_stk = (CPU_STK)0x41E00000u; /* S28 */
*--p_stk = (CPU_STK)0x41D80000u; /* S27 */
*--p_stk = (CPU_STK)0x41D00000u; /* S26 */
*--p_stk = (CPU_STK)0x41C80000u; /* S25 */
*--p_stk = (CPU_STK)0x41C00000u; /* S24 */
*--p_stk = (CPU_STK)0x41B80000u; /* S23 */
*--p_stk = (CPU_STK)0x41B00000u; /* S22 */
*--p_stk = (CPU_STK)0x41A80000u; /* S21 */
*--p_stk = (CPU_STK)0x41A00000u; /* S20 */
*--p_stk = (CPU_STK)0x41980000u; /* S19 */
*--p_stk = (CPU_STK)0x41900000u; /* S18 */
*--p_stk = (CPU_STK)0x41880000u; /* S17 */
*--p_stk = (CPU_STK)0x41800000u; /* S16 */
*--p_stk = (CPU_STK)0x41700000u; /* S15 */
*--p_stk = (CPU_STK)0x41600000u; /* S14 */
*--p_stk = (CPU_STK)0x41500000u; /* S13 */
*--p_stk = (CPU_STK)0x41400000u; /* S12 */
*--p_stk = (CPU_STK)0x41300000u; /* S11 */
*--p_stk = (CPU_STK)0x41200000u; /* S10 */
*--p_stk = (CPU_STK)0x41100000u; /* S9 */
*--p_stk = (CPU_STK)0x41000000u; /* S8 */
*--p_stk = (CPU_STK)0x40E00000u; /* S7 */
*--p_stk = (CPU_STK)0x40C00000u; /* S6 */
*--p_stk = (CPU_STK)0x40A00000u; /* S5 */
*--p_stk = (CPU_STK)0x40800000u; /* S4 */
*--p_stk = (CPU_STK)0x40400000u; /* S3 */
*--p_stk = (CPU_STK)0x40000000u; /* S2 */
*--p_stk = (CPU_STK)0x3F800000u; /* S1 */
*--p_stk = (CPU_STK)0x00000000u; /* S0 */
}
#endif
return (p_stk);
}
3.修改os_cpu_a.asm
PendSV_Handler
CPSID I ; Prevent interruption during context switch
MRS R0, PSP ; PSP is process stack pointer
CBZ R0, PendSV_Handler_nosave ; Skip register save the first time
SUBS R0, R0, #0x40
VSTM R0, {S16-S31}
SUBS R0, R0, #0x20 ; Save remaining regs r4-11 on process stack
STM R0, {R4-R11}
LDR R1, =OSTCBCurPtr ; 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, =OSTCBCurPtr ; OSTCBCur = OSTCBHighRdy;
LDR R1, =OSTCBHighRdyPtr
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
VLDM R0, {S16-S31}
ADDS R0, R0, #0x40
MSR PSP, R0 ; Load PSP with new process SP
ORR LR, LR, #0xF4 ; Ensure exception return uses process stack
CPSIE I
BX LR ; Exception return will restore remaining context
END
这三个地方修改完就可以正常使用FPU了
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。