Using Cortex-M4 Single Precision Floating point unit

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Using Cortex-M4 Single Precision Floating point unit

4,421 Views
d_shah
Contributor II

The Kinetis family is based on Cortex-M4 controller. Certain devices of Kinetis product family with cortex-M4 provides single precision floating point unit.

 

How can I leverage and make use of floating point unit in my application for efficient floating point operations? Do compiler take care of making use of floating point unit?

 

Any suggestions/Hints/links/application notes will be helpful.

 

Thank you,

d2v0

0 Kudos
3 Replies

1,597 Views
cortex_m4
Contributor I

I use Keil MDK-ARM V4.20.

 

file--Device Database...

Find  Freescale Semiconductor--MK60X256VMD100  and double click;

At "Options:" area, you can find "CPU=IRAM(0x1FFF8000-0x1FFFFFFF) IRAM2(0x20000000-0x20007FFF) IROM(0x0-0x3FFFF) IROM2(0x10000000-0x1003FFFF) CLOCK(12000000) CPUTYPE("Cortex-M4") ESEL ELITTLE"

 

Add "FPU2" at the end of this line,Then it become "CPU=IRAM(0x1FFF8000-0x1FFFFFFF) IRAM2(0x20000000-0x20007FFF) IROM(0x0-0x3FFFF) IROM2(0x10000000-0x1003FFFF) CLOCK(12000000) CPUTYPE("Cortex-M4") ESEL ELITTLE FPU2"

 

click "Update", close.(You may create a new device,with the copy of k60)

 

Then create a new project, select Freescale Semiconductor--MK60X256VMD100(have been changed ) . 

It can  generate FPU code when use floating point arithmetic in your C program.(You should enable the FPU first,if not it will hard fault).

Project--Options for Target 'Target1'..., at "Target" table,you can find "Use FPU" as default.

 

How to enable the FPU ?

ADD the code below in your startup.s

 

 

 ; CPACR is located at address 0xE000ED88
 LDR.W R0, =0xE000ED88
 ; Read CPACR
 LDR R1, [R0]
 ; Set bits 20-23 to enable CP10 and CP11 coprocessors
 ORR R1, R1, #(0xF << 20)
 ; Write back the modified value to the CPACR
 STR R1, [R0]

 

 

My test:

1.head.s

 

 IMPORT main AREA startup,CODE THUMB DCD 0x20000000 DCD resetreset PROC ENTRY ; CPACR is located at address 0xE000ED88 LDR.W R0, =0xE000ED88 ; Read CPACR LDR R1, [R0] ; Set bits 20-23 to enable CP10 and CP11 coprocessors ORR R1, R1, #(0xF << 20) ; Write back the modified value to the CPACR STR R1, [R0] push {r0-r1} LDR R0,=main BL main B . ENDP ALIGN END

 

 

2,main.c

 

int main(){ float a=1.0098; float b=1.9987; float c; c=a*b; return (int)c;}

 

the *.sct

 

ROMLOAD 0x0 0x4000{ EXEC_RO 0x0 {  head.o(startup, +first)  *(+RO)   } RAM 0x1FFF8000 {  *(+RW,+ZI) }}

 

 

 

 

result:

 

     3:         float a=1.0098; 0x00000028 EDDF1A08  VLDR          s3,[pc,#0x20]0x0000002C EEB00A61  VMOV.F32      s0,s3     4:         float b=1.9987;      5:         float c; 0x00000030 EDDF1A07  VLDR          s3,[pc,#0x1C]0x00000034 EEF00A61  VMOV.F32      s1,s3     6:         c=a*b; 0x00000038 EE601A20  VMUL.F32      s3,s0,s10x0000003C EEB01A61  VMOV.F32      s2,s3     7:         return (int)c; 0x00000040 EEFD1AC1  VCVT.S32.F32  s3,s20x00000044 EE110A90  VMOV          r0,s3

 

 

 

If I not use the fpu,the result is:

 

   3:         float a=1.0098; 0x0000002A 4806      LDR           r0,[pc,#24]  ; @0x000000440x0000002C 4604      MOV           r4,r0     4:         float b=1.9987;      5:         float c; 0x0000002E 4806      LDR           r0,[pc,#24]  ; @0x000000480x00000030 4605      MOV           r5,r0     6:         c=a*b; 0x00000032 4629      MOV           r1,r50x00000034 4620      MOV           r0,r40x00000036 F000F825  BL.W          _fmul (0x00000084)0x0000003A 4606      MOV           r6,r0     7:         return (int)c; 0x0000003C 4630      MOV           r0,r60x0000003E F000F805  BL.W          _ffix (0x0000004C)

 

 

 

 

 

 

 

 


0 Kudos

1,597 Views
immer48
Contributor II

Where do I insert the code in the startup.s? I have the startup_MK60N512MD100.s which is different from your example:

Spoiler
...
; Reset Handler

Reset_Handler   PROC
                EXPORT  Reset_Handler             [WEAK]
                IMPORT  SystemInit
                IMPORT  __main
                LDR     R0, =SystemInit
                BLX     R0
                LDR     R0, =__main
                BX      R0
                ENDP
...

The scatter-file is also different:

Spoiler
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************

LR_IROM1 0x00000000 0x00080000  {    ; load region size_region
  ER_IROM1 0x00000000 0x00080000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 0x1FFF0000 0x00010000  {  ; RW data
   .ANY (+RW +ZI)
  }
}

 



 

0 Kudos

1,597 Views
d_shah
Contributor II

Thank you for the informaiton. I will try as you said.

0 Kudos