stm32f407 官方ucos-iii 不支持FPU 导致haltfault错误的处理办法

由于官方提供的μCOS-III移植工程中对于浮点寄存器的入栈和出栈处理是错误的,所以网上就流传了

各种修正版本。但是这些修正的代码只能在 MDK4.7 以下版本中可以正常的运行,MDK4.7 及其以上的版

本无法正常运行。下面针对高版本的MDK进行修正处理

处理方法如下:

为了解决 FPU 的问题,有两个函数需要修改:一个是 CPU_STK  *OSTaskStkInit(),另一个是 PendSV

中断。 最后需要在工程选项中开启FPU的支持

修改函数CPU_STK  *OSTaskStkInit()

函数所在的在:

uCOS-III\Ports\ARM-Cortex-M4\Generic\RealView\os_cpu_c.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                                     */
                                                            /* Align the stack to 8-bytes.                            */
    p_stk = (CPU_STK *)((CPU_STK)(p_stk) & 0xFFFFFFF8);
                                                            /* Registers stacked as if auto-saved on exception        */ 

    *--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                                          */
                                                        /* Remaining registers saved on process stack             */
    *--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 ENABLE_FPU
    *--p_stk = (CPU_STK)0xFFFFFFFDUL;                                                                                 (1)
 ;endif
   return (p_stk);
} 

1.  这句话最重要,这里是将 EXC_RETURN也进行了入栈处理。

修改函数OS_CPU_PendSVHandler

函数所在的位置在:

uCOS-III\Ports\ARM-Cortex-M4\Generic\RealView\os_cpu_a.asm

修改后的内容

<pre name="code" class="cpp">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
 ;if enable the FPU

	TST LR, #0x10
	IT EQ
	VSTMDBEQ R0!, {S16-S31}
	MOV R3, LR
	STMDB R0!,{R3-R11}

    LDR     R1, =OSTCBCurPtr                                    ; OSTCBCurPtr->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}

    LDR     R0, =OSPrioCur                                      ; OSPrioCur   = OSPrioHighRdy;
    LDR     R1, =OSPrioHighRdy
    LDRB    R2, [R1]
    STRB    R2, [R0]

    LDR     R0, =OSTCBCurPtr                                    ; OSTCBCurPtr = OSTCBHighRdyPtr;
    LDR     R1, =OSTCBHighRdyPtr
    LDR     R2, [R1]
    STR     R2, [R0]

    LDR     R0, [R2]                                            ; R0 is new process SP; SP = OSTCBHighRdyPtr->StkPtr;

	LDMIA R0!,{R3-R11}
	MOV LR, R3
	TST LR, #0x10
	IT EQ
	VLDMIAEQ R0!, {S16-S31}

    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 remaining context

    END



1.  通过检测 EXC_RETURN(LR)的 bit4 来看这个任务是否使用

的 16 个浮点寄存器入栈。

2.  这里比较好理解,只不过也将 EXC_RETURN进行了入栈。

3.  参考上面的第二条,只不过这里是出栈。

4.  参考上面的第一条,只不过这里是出栈。

开启FPU

修改了上面的两个地方后别忘了开启 FPU:

开启FPU的优劣

开启FPU的好处就是加快浮点运算的执行速度,缺点就是增加任务堆栈的大小,因为34个浮点寄存器也需要入栈。同时也增加了任务的切换时间

stm32f407 官方ucos-iii 不支持FPU 导致haltfault错误的处理办法,布布扣,bubuko.com

时间: 2024-08-01 06:32:45

stm32f407 官方ucos-iii 不支持FPU 导致haltfault错误的处理办法的相关文章

cocos2d-x VS2012 UTF8码导致的错误的解决办法

如果代码的格式是UTF8,那么用VS2012编译的时候,会导致如下的错误: \classes\gameview.cpp(65): error C2001: 常量中有换行符 \classes\gameview.cpp(66): error C2143: 语法错误 : 缺少")"(在"}"的前面) 解决的办法就是转码,把UTF8转换为GB2312码, 有两种办法: 1.网上下载转码工具. 2.用VS2012的转码功能: 步骤1:点击要转码的文件 步骤2:选择菜单: 文件

UCOS iii 钩子函数 中断服务函数 临界区 延时函数

钩子函数 功能: 扩展任务功能,被其他任务调用  算是消息机制 1.OSIdleTaskHook(),空闲任务调用这个函数,可以用来让CPU进入低功耗模式 2.OSInitHook(), 系统初始化函数OSInit()调用此函数. 3.OSStatTaskHook(),统计任务每秒中都会调用这个函数,此函数允许你向统计任务中添加自己的应用函数. 4.OSTaskCreateHook(),任务创建的钩子函数. 5.OSTaskDelHook(), 任务删除的钩子函数. 6.OSTaskReturn

SQL Server中TOP子句可能导致的问题以及解决办法

原文:SQL Server中TOP子句可能导致的问题以及解决办法 简介      在SQL Server中,针对复杂查询使用TOP子句可能会出现对性能的影响,这种影响可能是好的影响,也可能是坏的影响,针对不同的情况有不同的可能性.      关系数据库中SQL语句只是一个抽象的概念,不包含任何逻辑.很多元数据都会影响执行计划的生成,SQL语句本身并不作为生成执行计划所参考的元数据(提示除外),但TOP关键字却是直接影响执行计划的一个关键字,因此在某些情况下使用TOP会导致性能受到影响,下面我们来

thinkphp nginx php-fpm url rewrite 导致 404 错误

thinkphp nginx php-fpm url rewrite 导致 404 错误 之前thinkphp的系统部署在apache上,考虑到在并发性能nginx比apache强悍得多,所以在centos上以 nginx+php-fpm模式重新部署了thinkphp系统,结果发现诸如 1 /index.php/home/user/verify 此类的url nginx会报404错误,但是改成 1 /index.php?s=/home/user/verify 之后却能够访问,这说明前一种url

升级CUDA版本导致VS2010错误:未找到导入的项目XXX,请确认&lt;Import&gt;声明中的路径正确,且磁盘上存在该文件。。。。

VS2010错误:未找到导入的项目XXX,请确认<Import>声明中的路径正确,且磁盘上存在该文件. E:\IGSNRR\dev\PhDThesisCode_CUDA\gtcg\gtcg.vcxproj : error : 未找到导入的项目“C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\BuildCustomizations\CUDA 5.5.props”.请确认 <Import> 声明中的路径正确,且磁盘上存在该文件. E:

中兴U960E修改系统文件导致无法开机的解决办法

中兴的手机开启飞行模式时不能开启wifi,用惯了三星手机之后真的不习惯这一点.昨晚躺着床上终于忍受不了,照着网上的教程修改了一下.教程复制如下:------------------------------------------------------------------------------------------------------[转]中兴的手机开启飞行模式时无法开启WIFI.蓝牙很蛋疼!我喜欢开飞行,但却还会用手机开WIFI上会网.玩游戏1.手机安装RE管理器:2.手机安装SQ

关于一些由于apache配置不而导致的错误和其它

1.如果你想将www放在apache默认的配置下,那么将它放在别的文件的时候,一定要放在其它盘符的根目录下,否则可以会应该其它莫名的报错(当然,也要修改配置文件): 2.再给网站做了重定向之后(配置httpd_vhosts.conf文件和host文件文件后),一定还在加载httpd_vhosts.conf文件,具体做法是:将httpd.conf文件的466行代码前面的#去掉: 如果加载了httpd_vhosts.conf文件,当你地址栏中输入重定向的网址后,你的网站根路径将直接指向你的网站的根目

WPF循环加载图片导致内存溢出的解决办法

程序场景:一系列的图片,从第一张到最后一张依次加载图片,形成"动画". 生成BitmapImage的方法有多种: 1. var source=new BitmapImage(new Uri("图片路径",UriKind.xxx)); 一般的场景使用这种方法还是比较方便快捷,但是对于本场景,内存恐怕得爆. 2. var data =File.ReadAllBytes("图片路径"); var ms = new System.IO.MemoryStr

nginx open files limits 导致大量错误信息

nginx  error.log 中出现大量如下错误信息: [[email protected] nginx]# grep -aP '^20.* \[crit\]' error.log 2017/03/14 12:06:31 [crit] 3549#0: accept4() failed (24: Too many open files) [[email protected] nginx]# grep -aP '^20.* \[alert\]' error.log 2017/03/14 16:0