hgreen
Posts: 10
Joined: Tue Sep 04, 2012 1:32 am
Location: Perth, Australia

Floating point hanging

Fri Sep 13, 2013 7:34 am

Hi All,
I'm new to baremetal development and also without much experience on ARM as a whole.
I've managed to setup and get running the example program from briadwiddas here https://github.com/brianwiddas/pi-baremetal which includes driving the framebuffer.

I'm trying to modify this program to call some hardware floating point functions so I started by grabbing some assembler code I found at DWelch's float02 example (https://github.com/dwelch67/raspberrypi ... er/float02) as below to initialise the floating point unit

Code: Select all

	/* Enable the vector floating point (VFP) unit */
    mrc p15, 0, r0, c1, c0, 2		/* R0 = Access Control Register	*/
    orr r0,r0,#0x300000 			/* Single precision				*/
    orr r0,r0,#0xC00000 			/* Double precision				*/
    mcr p15, 0, r0, c1, c0, 2		/* Access Control Register = R0	*/
    mov r0,#0x40000000				/* Enable VFP					*/
    fmxr fpexc,r0					/* FPEXC = R0					*/
I inserted this just above the final branch ("b initsys") at the bottom of the assembler code here https://github.com/brianwiddas/pi-barem ... er/start.s

I have also added some entry points in assembler for all of the (single precision) floating point functions I need, like mult, add, subtract etc. here's an example of the multiply one (named "m4mul").

Code: Select all

/* multiply */
.global m4mul
m4mul:
    vmov s0,r0
    vmov s1,r1
    vmul.f32 s2,s0,s1
    vmov r0,s2
    bx lr
This is defined as an external function in C with

Code: Select all

extern unsigned int m4mul(unsigned int, unsigned int);
When run, the program initialises ok, but on calling this m4mul function it hangs. I'm calling it with a valid IEEE single precision value ...

Code: Select all

unsigned int fb = (unsigned int)0x41c80000;	// 25.0
unsigned int xc = m4mul(fb, fb);     // <== Program hangs here.  Expected result ... 25 * 25 = 625 = 0x441c4000
I'm sure I'm doing something stupid, probably in the assembler part, but have no idea what.
Is there something incompatible with how the floating point unit is called when used from this program?

Any help most appreciated, thanks.

Harvey

User avatar
DexOS
Posts: 876
Joined: Wed May 16, 2012 6:32 pm
Contact: Website

Re: Floating point hanging

Fri Sep 13, 2013 6:09 pm

There's some good FP example's here: https://github.com/PeterLemon/Raspberry ... master/VFP
Batteries not included, Some assembly required.

valtonia
Posts: 26
Joined: Wed Jul 04, 2012 9:09 pm

Re: Floating point hanging

Fri Sep 13, 2013 8:01 pm

You need to initialise the FPU before using it. What you're seeing is your code causing an unknown instruction exception.
The one I use is by D Welch.

Code: Select all

   mrc p15, 0, r0, c1, c0, 2
   orr r0, r0, #0x300000            @ single precision
   orr r0, r0, #0xC00000            @ double precision
   mcr p15, 0, r0, c1, c0, 2
   mov r0, #0x40000000
   fmxr fpexc,r0
Put this in your assembly startup just before you jump to your C main function.

hgreen
Posts: 10
Joined: Tue Sep 04, 2012 1:32 am
Location: Perth, Australia

Re: Floating point hanging

Mon Sep 16, 2013 7:11 am

DexOS wrote:There's some good FP example's here: https://github.com/PeterLemon/Raspberry ... master/VFP
Thanks I'll check that out. I did see the mandelbrot one already - amazing stuff.

hgreen
Posts: 10
Joined: Tue Sep 04, 2012 1:32 am
Location: Perth, Australia

Re: Floating point hanging

Mon Sep 16, 2013 7:14 am

Thanks although I have that code already in there - see my original post above - the code is included there. I think something else must be going on. When I get some time I'll clean up the project, upload it all to github including a makefile and post it again to see if anyone can work it out. Thanks anyway.
valtonia wrote:You need to initialise the FPU before using it. What you're seeing is your code causing an unknown instruction exception.
The one I use is by D Welch.

Code: Select all

   mrc p15, 0, r0, c1, c0, 2
   orr r0, r0, #0x300000            @ single precision
   orr r0, r0, #0xC00000            @ double precision
   mcr p15, 0, r0, c1, c0, 2
   mov r0, #0x40000000
   fmxr fpexc,r0
Put this in your assembly startup just before you jump to your C main function.

valtonia
Posts: 26
Joined: Wed Jul 04, 2012 9:09 pm

Re: Floating point hanging

Tue Sep 17, 2013 8:27 pm

Hi,

Sorry, I didn't spot that it was the same code! :D

The other thing you'll need is to include these assembler flags in your makefile

-mfpu=vfp -mhard-float

at least, if you're using the same gcc as me (I'm not sure what it's called but the path to looks like this: /usr/local/arm-bcm2708/x86-linux64-cross-arm-linux-hardfp/bin/arm-bcm2708hardfp-linux-gnueabi-gcc).

hgreen
Posts: 10
Joined: Tue Sep 04, 2012 1:32 am
Location: Perth, Australia

Re: Floating point hanging

Mon Sep 23, 2013 6:48 am

Thanks for the suggestion - I didn't have that -mhard-float option there so tried it but its still hanging at the same spot (when the first floating point instruction is executed). I already had the -mfpu=vfp option there. I think the mfpu option was for the assembler and the mhard-float option was for the compiler - looks that way to me anyway.

The compiler+linker I'm using are named arm-none-eabi-gcc and arm-none-eabi-as ... from the YAGARTO windows installer.

This program I'm trying to get working is a modified version of brianwiddas/pi-baremetal demo to add floating point. I'll try doing the opposite - adding brianwiddas framebuffer capabilities to the floating point example I have got working and take it from there ...
valtonia wrote:Hi,

Sorry, I didn't spot that it was the same code! :D

The other thing you'll need is to include these assembler flags in your makefile

-mfpu=vfp -mhard-float

at least, if you're using the same gcc as me (I'm not sure what it's called but the path to looks like this: /usr/local/arm-bcm2708/x86-linux64-cross-arm-linux-hardfp/bin/arm-bcm2708hardfp-linux-gnueabi-gcc).

valtonia
Posts: 26
Joined: Wed Jul 04, 2012 9:09 pm

Re: Floating point hanging

Tue Sep 24, 2013 11:12 pm

The other thing I found helped when I had this hanging issue was to just use gcc for everything, passing the same flags for both assembly and .c - rather then having separate lines in the makefile for each. It seems that by doing it this way gcc figures out what needs to be done and supplies the appropriate flags for each compile type.

fyi, my cflags are:

Code: Select all

CFLAGS=--std=c99 -O2 -ffreestanding -mcpu=arm1176jzf-s -mfpu=vfp -mhard-float

Return to “Bare metal, Assembly language”