This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

关于M4内的DSP的疑问



你好!

       按规格书上说,现在的M4内带有DSP。

       我在程序的初始化的时候,利用ROM_FPULazyStackingEnable();使能了浮点运算,那么如果我在做些浮点或是整形的运算,或是一些算法的时候,M4 自己会用DSP做运算,还是需要人为干预?还是有库可用?

       谢谢。

  • 你的问题其实是两个问题:

    1. cortex-M4的内核带有一个FPU的运算单元,当你开启了该运算单元后,编译器会把你需要做浮点运算的自动用浮点汇编指令来编译,你可以用汇编的窗口来观察,如果启动了FPU单元,你的运算会被编译成用V开头的汇编指令,这就是FPU单元的汇编指令。不需要你做其他工作。

    2. 至于DSP功能,其实是厂家开发的DSP算法库,你可以在工程中添加IQmath的lib文件,在代码中调用DSP的算法函数。具体的用法你需要看相关的用户手册。

  • 补充一点,如果要用FPU单元,不光要在代码中使能FPU,而且还要在编译器的选项开启FPU单元功能,这样编译出来的汇编代码才会有带V开头的FPU单元汇编代码.

     

  • 你好!

    为了验证CORTEX-M4的FPU运算单元,我做了以下测试,建立了一个函数:

    static float data_test[512];   // data_test[512]在main里面已经初始化了

    float test_fpu(void)
    {
     float return_data;
      short int i;
     for (i = 0; i<510;i++)
     {
      return_data += data_test[i]*data_test[i+1]*data_test[i+2];
      return_data = return_data/0.000569;
     }

    void main(void)

    {

            把某一管脚置高;

            test_fpu();

            把某一管脚置低;

    }

    我发现如下情况:

    1.     系统在初始化的时候,如果调用

        MAP_FPUEnable();
        MAP_FPULazyStackingEnable();

    那么,这个函数执行时间是10.4ms

    2.     初始化的时候,不调用上面两个函数,那么时间是8.4ms。

    3.      你说的编译器使能FPU,是不是在"build -->  ARM Compiler --> processor options ---> "Specify floating point support 这里选FPv4SPD16",我这个地方选了,但是发现没有什么作用。(还是说我设错了,应该设定其它地方)。

    在上面的三个实验里,都没有看到带V的汇编指令。

  • 您好,我做了FPU的实验,但是还是没有看到有带V开头的FPU单元汇编代码。

  • 下面是CCS编译楼主提供的程序, test_fpu函数,得到的结果,使用浮点的代码我标记出来了。

    除了使用带V的指令以外,使用Sx寄存器也是使用浮点单元的特征。

    ;*****************************************************************************

    ;* FUNCTION NAME: test_fpu                                                   *

    ;*                                                                           *

    ;*   Regs Modified     : A1,A2,A3,A4,V1,V9,SP,LR,SR,D0,D0_hi,D1,FPEXC,FPSCR  *

    ;*   Regs Used         : A1,A2,A3,A4,V1,V9,SP,LR,SR,D0,D0_hi,D1,FPEXC,FPSCR  *

    ;*   Local Frame Size  : 0 Args + 8 Auto + 8 Save = 16 byte                  *

    ;*****************************************************************************

    test_fpu:

    ;* --------------------------------------------------------------------------*

    .dwcfi        cfa_offset, 0

            PUSH      {A3, A4, V1, LR}      ; [DPU_3_PIPE]

    .dwcfi        cfa_offset, 4

    .dwcfi        save_reg_to_mem, 14, -4

    .dwcfi        cfa_offset, 8

    .dwcfi        save_reg_to_mem, 4, -8

    .dwcfi        cfa_offset, 12

    .dwcfi        save_reg_to_mem, 3, -12

    .dwcfi        cfa_offset, 16

    .dwcfi        save_reg_to_mem, 2, -16

    .dwcfi        cfa_offset, 16

    $C$DW$3        .dwtag  DW_TAG_variable, DW_AT_name("return_data")

    .dwattr $C$DW$3, DW_AT_TI_symbol_name("return_data")

    .dwattr $C$DW$3, DW_AT_type(*$C$DW$T$16)

    .dwattr $C$DW$3, DW_AT_location[DW_OP_breg13 0]

    $C$DW$4        .dwtag  DW_TAG_variable, DW_AT_name("i")

    .dwattr $C$DW$4, DW_AT_TI_symbol_name("i")

    .dwattr $C$DW$4, DW_AT_type(*$C$DW$T$8)

    .dwattr $C$DW$4, DW_AT_location[DW_OP_breg13 4]

    .dwpsn        file "../main.c",line 7,column 7,is_stmt,isa 1

            MOVS      A1, #0                ; [DPU_3_PIPE] |7|

            STRH      A1, [SP, #4]          ; [DPU_3_PIPE] |7|

    .dwpsn        file "../main.c",line 7,column 14,is_stmt,isa 1

            LDRSH     A1, [SP, #4]          ; [DPU_3_PIPE] |7|

            CMP       A1, #510              ; [DPU_3_PIPE] |7|

            BGE       ||$C$L2||             ; [DPU_3_PIPE] |7|

            ; BRANCHCC OCCURS {||$C$L2||}    ; [] |7|

    ;* --------------------------------------------------------------------------*

    ;*   BEGIN LOOP ||$C$L1||

    ;*

    ;*   Loop source line                : 7

    ;*   Loop closing brace source line  : 11

    ;*   Known Minimum Trip Count        : 1

    ;*   Known Maximum Trip Count        : 4294967295

    ;*   Known Max Trip Count Factor     : 1

    ;* --------------------------------------------------------------------------*

    ||$C$L1||:   

    $C$DW$L$test_fpu$2$B:

    .dwpsn        file "../main.c",line 9,column 3,is_stmt,isa 1

            LDRSH     A2, [SP, #4]          ; [DPU_3_PIPE] |9|

            LDR       A1, $C$CON1           ; [DPU_3_PIPE] |9|

            ADD       A1, A1, A2, LSL #2    ; [DPU_3_PIPE] |9|

            LDRSH     A2, [SP, #4]          ; [DPU_3_PIPE] |9|

            VLDR.32   S0, [A1, #0]          ; [DPU_LIN_PIPE] |9|

            MOVS      A1, #4                ; [DPU_3_PIPE] |9|

            ADD       A1, A1, A2, LSL #2    ; [DPU_3_PIPE] |9|

            LDR       A2, $C$CON1           ; [DPU_3_PIPE] |9|

            ADDS      A2, A2, A1            ; [DPU_3_PIPE] |9|

            VLDR.32   S1, [A2, #0]          ; [DPU_LIN_PIPE] |9|

            MOVS      A1, #8                ; [DPU_3_PIPE] |9|

            LDRSH     A2, [SP, #4]          ; [DPU_3_PIPE] |9|

            VMUL.F32  S0, S1, S0            ; [DPU_LIN_PIPE] |9|

            ADD       A1, A1, A2, LSL #2    ; [DPU_3_PIPE] |9|

            LDR       A2, $C$CON1           ; [DPU_3_PIPE] |9|

            VLDR.32   S1, [SP, #0]          ; [DPU_LIN_PIPE] |9|

            ADDS      A2, A2, A1            ; [DPU_3_PIPE] |9|

            VLDR.32   S2, [A2, #0]          ; [DPU_LIN_PIPE] |9|

            VMLA.F32  S1, S2, S0            ; [DPU_LIN_PIPE] |9|

            VSTR.32   S1, [SP, #0]          ; [DPU_LIN_PIPE] |9|

    .dwpsn        file "../main.c",line 10,column 3,is_stmt,isa 1

            LDR       A1, [SP, #0]          ; [DPU_3_PIPE] |10|

    $C$DW$5        .dwtag  DW_TAG_TI_branch

    .dwattr $C$DW$5, DW_AT_low_pc(0x00)

    .dwattr $C$DW$5, DW_AT_name("__aeabi_f2d")

    .dwattr $C$DW$5, DW_AT_TI_call

            BL        __aeabi_f2d           ; [DPU_3_PIPE] |10|

            ; CALL OCCURS {__aeabi_f2d }     ; [] |10|

            ADR       V1, $C$FL1            ; [DPU_3_PIPE] |10|

            LDMIA     V1, {A3,A4}           ; [DPU_3_PIPE] |10|

    $C$DW$6        .dwtag  DW_TAG_TI_branch

    .dwattr $C$DW$6, DW_AT_low_pc(0x00)

    .dwattr $C$DW$6, DW_AT_name("__aeabi_ddiv")

    .dwattr $C$DW$6, DW_AT_TI_call

            BL        __aeabi_ddiv          ; [DPU_3_PIPE] |10|

            ; CALL OCCURS {__aeabi_ddiv }    ; [] |10|

    $C$DW$7        .dwtag  DW_TAG_TI_branch

    .dwattr $C$DW$7, DW_AT_low_pc(0x00)

    .dwattr $C$DW$7, DW_AT_name("__aeabi_d2f")

    .dwattr $C$DW$7, DW_AT_TI_call

            BL        __aeabi_d2f           ; [DPU_3_PIPE] |10|

            ; CALL OCCURS {__aeabi_d2f }     ; [] |10|

            VMOV      S0, A1                ; [DPU_LIN_PIPE] |10|

            VSTR.32   S0, [SP, #0]          ; [DPU_LIN_PIPE] |10|

    .dwpsn        file "../main.c",line 7,column 20,is_stmt,isa 1

            LDRSH     A1, [SP, #4]          ; [DPU_3_PIPE] |7|

            ADDS      A1, A1, #1            ; [DPU_3_PIPE] |7|

            STRH      A1, [SP, #4]          ; [DPU_3_PIPE] |7|

    .dwpsn        file "../main.c",line 7,column 14,is_stmt,isa 1

            LDRSH     A1, [SP, #4]          ; [DPU_3_PIPE] |7|

            CMP       A1, #510              ; [DPU_3_PIPE] |7|

            BLT       ||$C$L1||             ; [DPU_3_PIPE] |7|

            ; BRANCHCC OCCURS {||$C$L1||}    ; [] |7|

    $C$DW$L$test_fpu$2$E:

    ;* --------------------------------------------------------------------------*

    .dwpsn        file "../main.c",line 12,column 1,is_stmt,isa 1

    ;* --------------------------------------------------------------------------*

    ||$C$L2||:   

    .dwcfi        cfa_offset, 16

    $C$DW$8        .dwtag  DW_TAG_TI_branch

    .dwattr $C$DW$8, DW_AT_low_pc(0x00)

    .dwattr $C$DW$8, DW_AT_TI_return

            POP       {A3, A4, V1, PC}      ; [DPU_3_PIPE]

            ; BRANCH OCCURS                  ; []