你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【安富莱STM32F407之uCOS-III教程】第10章 μCOS-III在高版本MDK...

[复制链接]
baiyongbin2009 发布时间:2014-12-23 19:27
本帖最后由 baiyongbin2009 于 2014-12-23 19:30 编辑

特别说明:
1.  本教程是安富莱电子原创。
2.  安富莱STM32F407开发板资料已经全部开源,开源地址:地址链接

3.  当前共配套300多个实例,4套用户手册。

第10章  μCOS-III在高版本MDK开启FPU方案

    由于官方提供的μCOS-III移植工程中对于浮点寄存器的入栈和出栈处理是错误的,所以网上就流传了各种修正版本。但是这些修正的代码只能在MDK4.7以下版本中可以正常的运行,MDK4.7及其以上的版本无法正常运行。本期教程为此而生。本期教程提供的方案只有任务使用了浮点寄存器(也就是做了浮点运算)才需要将其入栈,没有使用浮点寄存器的任务不需要进行入栈,认识到这点很重要。此方案在MDK4.54、4.73、5.10以及IAR6.3、6.7上面测试均通过。
    10.1 官方移植方案
    10.2 开启FPU解决方案
    10.3 开启FPU的优劣
    10.4 总结

10.1  官方移植方案
    官方提供的移植工程里面,只有IAR工程里面才有浮点寄存器的入栈和出栈处理函数,MDK工程里面是没有的。下面这个是os_cpu_c.c文件夹中的函数:
  1. /*
  2. *********************************************************************************************************
  3. *                                        INITIALIZE A TASK'S STACK
  4. *
  5. * Description: This function is called by either OSTaskCreate() or OSTaskCreateExt() to initialize the
  6. *              stack frame of the task being created.  This function is highly processor specific.
  7. *
  8. * Arguments  : task          is a pointer to the task code
  9. *
  10. *              p_arg         is a pointer to a user supplied data area that will be passed to the task
  11. *                            when the task first executes.
  12. *
  13. *              ptos          is a pointer to the top of stack.  It is assumed that 'ptos' points to
  14. *                            a 'free' entry on the task stack.  If OS_STK_GROWTH is set to 1 then
  15. *                            'ptos' will contain the HIGHEST valid address of the stack.  Similarly, if
  16. *                            OS_STK_GROWTH is set to 0, the 'ptos' will contains the LOWEST valid address
  17. *                            of the stack.
  18. *
  19. *              opt           specifies options that can be used to alter the behavior of OSTaskStkInit().
  20. *                            (see uCOS_II.H for OS_TASK_OPT_xxx).
  21. *
  22. * Returns    : Always returns the location of the new top-of-stack once the processor registers have
  23. *              been placed on the stack in the proper order.
  24. *
  25. * Note(s)    : (1) Interrupts are enabled when task starts executing.
  26. *
  27. *              (2) All tasks run in Thread mode, using process stack.
  28. *
  29. *              (3) There are two different stack frames depending on whether the Floating-Point(FP)
  30. *                  co-processor is enabled or not.
  31. *
  32. *                  (a) The stack frame shown in the diagram is used when the FP co-processor is not present and
  33. *                      OS_TASK_OPT_SAVE_FP is disabled. In this case, the FP registers and FP Status Control
  34. *                      register are not saved in the stack frame.
  35. *
  36. *                  (b) If the FP co-processor is present but the OS_TASK_OPT_SAVE_FP is not set, then the stack
  37. *                      frame is saved as shown in diagram (a). Moreover, if OS_TASK_OPT_SAVE_FP is set, then the
  38. *                      FP registers and FP Status Control register are saved in the stack frame.
  39. *
  40. *                      (1) When enabling the FP co-processor, make sure to clear bits ASPEN and LSPEN in the
  41. *                          Floating-Point Context Control Register (FPCCR).
  42. *
复制代码
*                   +------------+      +------------+
*                    |            |       |            |
*                   +------------+      +------------+
*                    |    xPSR   |       |    xPSR   |
*                    +------------+       +------------+      
*                    |Return Addr|       |Return Addr |
*                   +------------+      +------------+
*                    |  LR(R14)  |       |   LR(R14) |
*                   +------------+      +------------+
*                    |    R12    |       |     R12   |
*                   +------------+      +------------+
*                    |    R3     |       |     R3    |
*                    +------------+       +------------+
*                    |    R2     |       |     R0    |
*                   +------------+      +------------+
*                    |    R1     |       |     R1    |
*                   +------------+       +------------+
*                    |    R0     |       |     R0    |
*                   +------------+      +------------+
*                    |    R11    |       |     R11   |
*                   +------------+      +------------+
*                    |    R10    |       |     R10   |
*                   +------------+      +------------+
*                    |    R9     |       |     R9    |
*                   +------------+      +------------+
*                    |    R8     |       |     R8    |
*                   +------------+      +------------+
*                    |    R7     |       |     R7    |
*                   +------------+      +------------+
*                    |    R6     |       |     R6    |
*                    +------------+       +------------+
*                    |    R5     |       |     R5    |
*                   +------------+      +------------+
*                    |    R4     |       |     R4    |
*                   +------------+       +------------+
*                         (a)             |  FPSCR    |
*                                        +------------+
*                                        |     S31    |
*                                        +------------+
*                                                .
*                                               .
*                                               .
*                                        +------------+
*                                        |     S1     |
                                          +------------+
*                                        |     S0     |
*                                        +------------+
*                                             (b)




收藏 评论6 发布时间:2014-12-23 19:27

举报

6个回答
baiyongbin2009 回答时间:2014-12-23 19:32:50
本帖最后由 baiyongbin2009 于 2014-12-23 19:36 编辑

(续)10.1  官方移植方案
  1. *
  2. *             (4) The SP must be 8-byte aligned in conforming to the Procedure Call Standard for the ARM architecture
  3. *
  4. *                    (a) Section 2.1 of the  ABI for the ARM Architecture Advisory Note. SP must be 8-byte aligned
  5. *                        on entry to AAPCS-Conforming functions states :
  6. *                    
  7. *                        The Procedure Call Standard for the ARM Architecture [AAPCS] requires primitive
  8. *                        data types to be naturally aligned according to their sizes (for size = 1, 2, 4, 8 bytes).
  9. *                        Doing otherwise creates more problems than it solves.
  10. *
  11. *                        In return for preserving the natural alignment of data, conforming code is permitted
  12. *                        to rely on that alignment. To support aligning data allocated on the stack, the stack
  13. *                        pointer (SP) is required to be 8-byte aligned on entry to a conforming function. In
  14. *                        practice this requirement is met if:
  15. *
  16. *                           (1) At each call site, the current size of the calling function抯 stack frame is a multiple of 8 bytes.
  17. *                               This places an obligation on compilers and assembly language programmers.
  18. *
  19. *                           (2) SP is a multiple of 8 when control first enters a program.
  20. *                               This places an obligation on authors of low level OS, RTOS, and runtime library
  21. *                               code to align SP at all points at which control first enters
  22. *                               a body of (AAPCS-conforming) code.
  23. *              
  24. *                       In turn, this requires the value of SP to be aligned to 0 modulo 8:
  25. *
  26. *                           (3) By exception handlers, before calling AAPCS-conforming code.
  27. *
  28. *                           (4) By OS/RTOS/run-time system code, before giving control to an application.
  29. *
  30. *                 (b) Section 2.3.1 corrective steps from the the SP must be 8-byte aligned on entry
  31. *                     to AAPCS-conforming functions advisory note also states.
  32. *
  33. *                     " This requirement extends to operating systems and run-time code for all architecture versions
  34. *                       prior to ARMV7 and to the A, R and M architecture profiles thereafter. Special considerations
  35. *                       associated with ARMV7M are discussed in ?.3.3"
  36. *
  37. *                     (1) Even if the SP 8-byte aligment is not a requirement for the ARMv7M profile, the stack is aligned
  38. *                         to 8-byte boundaries to support legacy execution enviroments.
  39. *
  40. *                 (c) Section 5.2.1.2 from the Procedure Call Standard for the ARM
  41. *                     architecture states :  "The stack must also conform to the following
  42. *                     constraint at a public interface:
  43. *
  44. *                     (1) SP mod 8 = 0. The stack must be double-word aligned"
  45. *
  46. *                 (d) From the ARM Technical Support Knowledge Base. 8 Byte stack aligment.
  47. *
  48. *                     "8 byte stack alignment is a requirement of the ARM Architecture Procedure
  49. *                      Call Standard [AAPCS]. This specifies that functions must maintain an 8 byte
  50. *                      aligned stack address (e.g. 0x00, 0x08, 0x10, 0x18, 0x20) on all external
  51. *                      interfaces. In practice this requirement is met if:
  52. *
  53. *                      (1) At each external interface, the current stack pointer
  54. *                          is a multiple of 8 bytes.
  55. *
  56. *                      (2) Your OS maintains 8 byte stack alignment on its external interfaces
  57. *                          e.g. on task switches"
  58. *
  59. **********************************************************************************************************
复制代码



baiyongbin2009 回答时间:2014-12-23 19:38:02
(续)10.1  官方移植方案
  1. */

  2. OS_STK *OSTaskStkInit (void (*task)(void *p_arg), void *p_arg, OS_STK *ptos, INT16U opt)
  3. {
  4. OS_STK *p_stk;


  5. p_stk = ptos + 1u; /* Load stack pointer */
  6. /* Align the stack to 8-bytes. */
  7. p_stk = (OS_STK *)((OS_STK)(p_stk) & 0xFFFFFFF8u);
  8. /* Registers stacked as if auto-saved on exception */
  9. *(--p_stk) = (OS_STK)0x01000000uL; /* xPSR */
  10. *(--p_stk) = (OS_STK)task; /* Entry Point */
  11. *(--p_stk) = (OS_STK)OS_TaskReturn; /* R14 (LR) */
  12. *(--p_stk) = (OS_STK)0x12121212uL; /* R12 */
  13. *(--p_stk) = (OS_STK)0x03030303uL; /* R3 */
  14. *(--p_stk) = (OS_STK)0x02020202uL; /* R2 */
  15. *(--p_stk) = (OS_STK)0x01010101uL; /* R1 */
  16. *(--p_stk) = (OS_STK)p_arg; /* R0 : argument */

  17. /* Remaining registers saved on process stack */
  18. *(--p_stk) = (OS_STK)0x11111111uL; /* R11 */
  19. *(--p_stk) = (OS_STK)0x10101010uL; /* R10 */
  20. *(--p_stk) = (OS_STK)0x09090909uL; /* R9 */
  21. *(--p_stk) = (OS_STK)0x08080808uL; /* R8 */
  22. *(--p_stk) = (OS_STK)0x07070707uL; /* R7 */
  23. *(--p_stk) = (OS_STK)0x06060606uL; /* R6 */
  24. *(--p_stk) = (OS_STK)0x05050505uL; /* R5 */
  25. *(--p_stk) = (OS_STK)0x04040404uL; /* R4 */

  26. #if (OS_CPU_ARM_FP_EN > 0u)
  27. if ((opt & OS_TASK_OPT_SAVE_FP) != (INT16U)0) {
  28. *--p_stk = (OS_STK)0x02000000u; /* FPSCR */
  29. /* Initialize S0-S31 floating point registers */
  30. *--p_stk = (OS_STK)0x41F80000u; /* S31 */
  31. *--p_stk = (OS_STK)0x41F00000u; /* S30 */
  32. *--p_stk = (OS_STK)0x41E80000u; /* S29 */
  33. *--p_stk = (OS_STK)0x41E00000u; /* S28 */
  34. *--p_stk = (OS_STK)0x41D80000u; /* S27 */
  35. *--p_stk = (OS_STK)0x41D00000u; /* S26 */
  36. *--p_stk = (OS_STK)0x41C80000u; /* S25 */
  37. *--p_stk = (OS_STK)0x41C00000u; /* S24 */
  38. *--p_stk = (OS_STK)0x41B80000u; /* S23 */
  39. *--p_stk = (OS_STK)0x41B00000u; /* S22 */
  40. *--p_stk = (OS_STK)0x41A80000u; /* S21 */
  41. *--p_stk = (OS_STK)0x41A00000u; /* S20 */
  42. *--p_stk = (OS_STK)0x41980000u; /* S19 */
  43. *--p_stk = (OS_STK)0x41900000u; /* S18 */
  44. *--p_stk = (OS_STK)0x41880000u; /* S17 */
  45. *--p_stk = (OS_STK)0x41800000u; /* S16 */
  46. *--p_stk = (OS_STK)0x41700000u; /* S15 */
  47. *--p_stk = (OS_STK)0x41600000u; /* S14 */
  48. *--p_stk = (OS_STK)0x41500000u; /* S13 */
  49. *--p_stk = (OS_STK)0x41400000u; /* S12 */
  50. *--p_stk = (OS_STK)0x41300000u; /* S11 */
  51. *--p_stk = (OS_STK)0x41200000u; /* S10 */
  52. *--p_stk = (OS_STK)0x41100000u; /* S9 */
  53. *--p_stk = (OS_STK)0x41000000u; /* S8 */
  54. *--p_stk = (OS_STK)0x40E00000u; /* S7 */
  55. *--p_stk = (OS_STK)0x40C00000u; /* S6 */
  56. *--p_stk = (OS_STK)0x40A00000u; /* S5 */
  57. *--p_stk = (OS_STK)0x40800000u; /* S4 */
  58. *--p_stk = (OS_STK)0x40400000u; /* S3 */
  59. *--p_stk = (OS_STK)0x40000000u; /* S2 */
  60. *--p_stk = (OS_STK)0x3F800000u; /* S1 */
  61. *--p_stk = (OS_STK)0x00000000u; /* S0 */
  62. }
  63. #endif

  64. return (p_stk);
  65. }
复制代码
    官方提供的这个堆栈初始化是错误的的,为什么是错误的?因为这个不符合浮点寄存器的入栈和出栈顺序。还有一部分代码在os_cpu_a.asm文件中,内容如下:
  1. #ifdef __ARMVFP__
  2.     PUBLIC  OS_CPU_FP_Reg_Push
  3.     PUBLIC  OS_CPU_FP_Reg_Pop
  4. #endif   

  5. ;********************************************************************************************************
  6. ;                                               EQUATES
  7. ;********************************************************************************************************

  8. NVIC_INT_CTRL   EQU     0xE000ED04                              ; Interrupt control state register.
  9. NVIC_SYSPRI14   EQU     0xE000ED22                              ; System priority register (priority 14).
  10. NVIC_PENDSV_PRI EQU           0xFF                              ; PendSV priority value (lowest).
  11. NVIC_PENDSVSET  EQU     0x10000000                              ; Value to trigger PendSV exception.


  12. ;********************************************************************************************************
  13. ;                                     CODE GENERATION DIRECTIVES
  14. ;********************************************************************************************************

  15.     RSEG CODE:CODE:NOROOT(2)
  16.     THUMB

  17. #ifdef __ARMVFP__
  18. ;********************************************************************************************************
  19. ;                                   FLOATING POINT REGISTERS PUSH
  20. ;                             void  OS_CPU_FP_Reg_Push (OS_STK  *stkPtr)
  21. ;
  22. ; Note(s) : 1) This function saves S0-S31, and FPSCR registers of the Floating Point Unit.
  23. ;
  24. ;           2) Pseudo-code is:
  25. ;              a) Get FPSCR register value;
  26. ;              b) Push value on process stack;
  27. ;              c) Push remaining regs S0-S31 on process stack;
  28. ;              d) Update OSTCBCur->OSTCBStkPtr;
  29. ;********************************************************************************************************

  30. OS_CPU_FP_Reg_Push
  31.     MRS     R1, PSP                                             ; PSP is process stack pointer
  32.     CBZ     R1, OS_CPU_FP_nosave                                ; Skip FP register save the first time
  33.    
  34.     VMRS    R1, FPSCR
  35.     STR R1, [R0, #-4]!
  36.     VSTMDB  R0!, {S0-S31}
  37.     LDR     R1, =OSTCBCur
  38.     LDR     R2, [R1]
  39.     STR     R0, [R2]
  40. OS_CPU_FP_nosave   
  41.     BX      LR

  42. ;********************************************************************************************************
  43. ;                                   FLOATING POINT REGISTERS POP
  44. ;                             void  OS_CPU_FP_Reg_Pop (OS_STK  *stkPtr)
  45. ;
  46. ; Note(s) : 1) This function restores S0-S31, and FPSCR registers of the Floating Point Unit.
  47. ;
  48. ;           2) Pseudo-code is:
  49. ;              a) Restore regs S0-S31 of new process stack;
  50. ;              b) Restore FPSCR reg value
  51. ;              c) Update OSTCBHighRdy->OSTCBStkPtr pointer of new proces stack;
  52. ;********************************************************************************************************

  53. OS_CPU_FP_Reg_Pop
  54.     VLDMIA  R0!, {S0-S31}
  55.     LDMIA   R0!, {R1}
  56.     VMSR    FPSCR, R1   
  57.     LDR     R1, =OSTCBHighRdy
  58.     LDR     R2, [R1]
  59.     STR     R0, [R2]
  60.     BX      LR
  61. #endif
复制代码
    如果不理解为什么这个浮点寄存的入栈和出栈是错误的,需要认真学习一下第5章:任务切换设计。第5章对于这个问题有深入的讲解。

baiyongbin2009 回答时间:2014-12-23 19:42:38
本帖最后由 baiyongbin2009 于 2014-12-23 19:48 编辑

10.2  开启FPU解决方案
    为了解决FPU的问题,有两个函数需要修改:一个是CPU_STK  *OSTaskStkInit(),另一个是PendSV中断。
10.2.1      修改函数CPU_STK  *OSTaskStkInit()
    函数所在的位置如下:
10.1.png

    下面是修改后的内容:
  1. CPU_STK  *OSTaskStkInit (OS_TASK_PTR    p_task,
  2.                          void          *p_arg,
  3.                          CPU_STK       *p_stk_base,
  4.                          CPU_STK       *p_stk_limit,
  5.                          CPU_STK_SIZE   stk_size,
  6.                          OS_OPT         opt)
  7. {
  8.     CPU_STK  *p_stk;


  9.     (void)opt;                                              /* Prevent compiler warning                               */

  10.     p_stk = &p_stk_base[stk_size];                          /* Load stack pointer                                     */
  11.                                                             /* Align the stack to 8-bytes.                            */
  12.     p_stk = (CPU_STK *)((CPU_STK)(p_stk) & 0xFFFFFFF8);
  13.                                                             /* Registers stacked as if auto-saved on exception        */

  14. *--p_stk = (CPU_STK)0x01000000u;                        /* xPSR                                                 */
  15.     *--p_stk = (CPU_STK)p_task;                             /* Entry Point                                            */
  16.     *--p_stk = (CPU_STK)OS_TaskReturn;                      /* R14 (LR)                                               */
  17.     *--p_stk = (CPU_STK)0x12121212u;                        /* R12                                                    */
  18.     *--p_stk = (CPU_STK)0x03030303u;                        /* R3                                                     */
  19.     *--p_stk = (CPU_STK)0x02020202u;                        /* R2                                                     */
  20.     *--p_stk = (CPU_STK)p_stk_limit;                        /* R1                                                     */
  21.     *--p_stk = (CPU_STK)p_arg;                              /* R0 : argument                                          */
  22.                                                             /* Remaining registers saved on process stack             */
  23.     *--p_stk = (CPU_STK)0x11111111u;                        /* R11                                                    */
  24.     *--p_stk = (CPU_STK)0x10101010u;                        /* R10                                                    */
  25.     *--p_stk = (CPU_STK)0x09090909u;                        /* R9                                                     */
  26.     *--p_stk = (CPU_STK)0x08080808u;                        /* R8                                                     */
  27.     *--p_stk = (CPU_STK)0x07070707u;                        /* R7                                                     */
  28.     *--p_stk = (CPU_STK)0x06060606u;                        /* R6                                                     */
  29.     *--p_stk = (CPU_STK)0x05050505u;                        /* R5                                                     */
  30.     *--p_stk = (CPU_STK)0x04040404u;                        /* R4                                                     */

  31.     *--p_stk = (CPU_STK)0xFFFFFFFDUL;                                                                                                                            (1)
  32.      
  33.       return (p_stk);
  34. }
复制代码
1.     这句话最重要,这里是将EXC_RETURN也进行了入栈处理。关于EXC_RETURN在前面4.2.5 特殊功能寄存器讲解。这里要补充一点,对于M4内核,EXC_RETURN的bit4也是有意义的。
    当bit4 = 1时,8个寄存器自动入栈,还有8个寄存器需要手动入栈
    当bit4 = 0时,18个浮点寄存器+8个寄存器自动入栈,还有16个浮点寄存器+8个寄存器需要手动入栈。
这些寄存器在第4章和第5章有详细的讲解,这里就不再赘述了。

10.2.png



10.2.2      修改函数OS_CPU_PendSVHandler
    函数所在的位置如下:
10.3.png

    PendSV中断需要修改的地方如下:
  1. OS_CPU_PendSVHandler
  2.     CPSID   I                                                   ; Prevent interruption during context switch
  3.     MRS     R0, PSP                                             ; PSP is process stack pointer
  4.     CBZ     R0, OS_CPU_PendSVHandler_nosave                     ; Skip register save the first time

  5.     TST      LR, #0x10                                                                                                                                                (1)
  6. IT       EQ
  7. VSTMDBEQ R0!, {S16-S31}
  8.    
  9. MOV      R3, LR                                                                                                                                                          (2)
  10. STMDB    R0!,{R3-R11}            

  11.     LDR     R1, =OSTCBCurPtr                                    ; OSTCBCurPtr->OSTCBStkPtr = SP;
  12.     LDR     R1, [R1]
  13.     STR     R0, [R1]                                            ; R0 is SP of process being switched out

  14.                                                                 ; At this point, entire context of process has been saved
  15. OS_CPU_PendSVHandler_nosave
  16.     PUSH    {R14}                                               ; Save LR exc_return value
  17.     LDR     R0, =OSTaskSwHook                                   ; OSTaskSwHook();
  18.     BLX     R0
  19.     POP     {R14}

  20.     LDR     R0, =OSPrioCur                                      ; OSPrioCur   = OSPrioHighRdy;
  21.     LDR     R1, =OSPrioHighRdy
  22.     LDRB    R2, [R1]
  23.     STRB    R2, [R0]

  24.     LDR     R0, =OSTCBCurPtr                                    ; OSTCBCurPtr = OSTCBHighRdyPtr;
  25.     LDR     R1, =OSTCBHighRdyPtr
  26.     LDR     R2, [R1]
  27.     STR     R2, [R0]
  28.     LDR     R0, [R2]                                            ; R0 is new process SP; SP = OSTCBHighRdyPtr->StkPtr;


  29.     LDMIA    R0!,{R3-R11}                                                                                                                                                  (3)
  30. MOV      LR, R3
  31.          
  32. TST      LR, #0x10                                                                                                                                                                (4)
  33. IT       EQ
  34. VLDMIAEQ R0!, {S16-S31}           
  35.    
  36.     MSR     PSP, R0                                             ; Load PSP with new process SP
  37.    
  38.     CPSIE   I
  39.     BX      LR                                                  ; Exception return will restore remaining context

  40.     END
复制代码
1.     通过检测EXC_RETURN(LR)的bit4来看这个任务是否使用了浮点寄存器,如果使用了需要将剩余的16个浮点寄存器入栈。
TST   LR,  #0x10
    TST指令通常与EQ,NE条件码配合使用。当所有测试位均为0时,EQ有效。而只要有一个测试位不为0,则NE有效。这里LR和0x10的值按位作逻辑“与”操作。
IT  EQ
    这里IT指令就是IF-THEN的缩写。IF‐THEN(IT)指令围起一个块,里面最多有4条指令,它里面的指令可以条件执行。 IT已经带了一个“T”,因此还可以最多再带3个“T”或者“E”。并且对T和E的顺序没有要求。其中T对应条件成立时执行的语句,E对应条件不成立时执行的语句。在If‐Then块中的指令必须加上条件后缀,且T对应的指令必须使用和IT指令中相同的条件,E对应的指令必须使用和IT指令中相反的条件。
    IT的使用形式总结如下:
IT<cond> ;围起1条指令的IF-THEN块
IT<x><cond> ;围起2条指令的IF-THEN块
IT<x><y>  <cond> ;围起3条指令的IF-THEN块
IT<x><y><z><cond> ;围起4条指令的IF-THEN块
    其中<x>,<y>, <z>的取值可以是“T”或者“E”。而<cond>则是在下表中列出的条件(AL除外)。
10.4.png



baiyongbin2009 回答时间:2014-12-23 19:45:29
(续)10.2.2  修改函数OS_CPU_PendSVHandler
    这么说还不够形象,下面举一个简单的例子,用IT指令优化C伪代码:
if(R0==R1)
{
R3= R4 + R5;
R3= R3 / 2;
}
else
{
R3= R6 + R7;
R3= R3 / 2;
}
    可以写作:
CMP  R0, R1     ; 比较R0和R1
ITTEEEQ          ; 如果R0== R1, Then-Then-Else-Else
ADDEQR3,R4, R5  ; 相等时加法
ASREQR3,R3, #1   ; 相等时算术右移
ADDNER3,R6, R7  ; 不等时加法
ASRNER3,R3, #1   ; 不等时算术右移
有了上面这些基础知识后再看下面的指令。
VSTMDBEQ R0!, {S16-S31}
    结合上面的IT EQ,这里的意思就是 if  LR & 0x10 == 0 then  VSTMDB R0!, {S16-S31}。也就是咱们前面所说的如果EXC_RETURN(LR)的bit4= 0就表示使用浮点寄存器了,这里需要入栈。
2.     这里比较好理解,只不过也将EXC_RETURN进行了入栈。
3.     参考上面的第二条,只不过这里是出栈。
4.     参考上面的第一条,只不过这里是出栈。
10.2.3      开启FPU
    修改了上面的两个地方后别忘了开启FPU:
10.5.png
                              
    通过上面这三部就完成了相关的修改。

baiyongbin2009 回答时间:2014-12-23 19:46:53
10.3  开启FPU的优劣
    开启FPU的好处就是加快浮点运算的执行速度,缺点就是增加任务堆栈的大小,因为34个浮点寄存器也需要入栈。同时也增加了任务的切换时间。下面是在μCOS-III的GUI任务和启动任务中使用了浮点运算的对比(App Task GUI和App Task Start)。
    第一个截图是开启了FPU:
10.6.png
    第二个截图是没有开启FPU:
10.7.png

    特别对比下使用了浮点运行的两个任务。
10.4  总结       

    本期教程提供的方案在MDK4.54、4.73、5.10以及IAR6.3、6.7上面测试均通过,用户只需按照上面讲的三个地方做修改即可。


pjzmj2012 回答时间:2020-3-3 14:48:23
有ucosIII 3。06.02在S32 Design Studio下的教程吗

所属标签

相似技术帖

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版