I'm porting a project from CW that uses the floating point ability of the K20F120 and it's crashing at the first float move instruction. So I checked startup.c and I don't see any initialization of the VFP anywhere.
In CW you have:
#ifdef __VFPV4__
__fp_init();
#endif
Which I tried but it's not in the KDS libraries...
Am I missing something or is something missing?
解決済! 解決策の投稿を見る。
Hi Marc,
your original report had uncovered an issue in the FreeRTOS port: that
str r1,[r0] \n" /* store to new value back */
was missing there, so that's why on your system with FreeRTOS the FPU is not enabled.
I fixed this issue this morning already: fixed setting FPU registers · 0aa2dbe · GitHub
You could make the same change on your end too. Or use the attached component.
Erich
Hi.
For me it is working normally.
i had problem when working with printf and i had to add.
-u _printf_float -u _scanf_float -nanolibc at other link flags.
so does your startup.c have something to initialize the VFP?
I should mention the project is using ProcessorExpert, so it's generating startup.c, and I'm not using nanolib, and am linking in libc and libm
Hi.
mine has at
void SystemInit (void) {
#if ((__FPU_PRESENT == 1) && (__FPU_USED == 1))
SCB->CPACR |= ((3UL << 10*2) | (3UL << 11*2)); /* set CP10, CP11 Full Access */
#endif /* ((__FPU_PRESENT == 1) && (__FPU_USED == 1)) */
Yes, you are fine because there is a different startup code which takes care of it if you are not using Processor Expert. The problem is with Processor Expert projects.
Hi Marc,
I confirm the problem: the startup code with Processor Expert project for K64F does not enable floating point support.
Erich
Thanks for the verification Erich!
I was hoping I could locate the source for fp_init() from CW but I can't find it... hoping to hack that in to get this project going. Any ideas how to move foward?
Hi Marc,
Here is the code I use:
void vPortEnableVFP(void) {
/* The FPU enable bits are in the CPACR. */
__asm volatile (
" ldr.w r0, =0xE000ED88 \n" /* CAPCR, 0xE000ED88 */
" ldr r1, [r0] \n" /* read CAPR */
" orr r1, r1, #(0xf<<20) \n" /* Enable CP10 and CP11 coprocessors */
" str r1,[r0] \n" /* store to new value back */
: /* no output */
: /* no input */
: "r0","r1" /* clobber */
);
}
Call that in main() e.g. after PE_low_level_init(), just before you are using any floating point.
you might call this in your startup code too.
I hope this helps,
Erich
Hi Erich,
That code is in port.c generated by your FreeRTOS bean, FreeRTOS v8.0.1, which I'm using in the project.
vPortEnableVFP is called from within xPortStartScheduler so it's being called before any tasks run and my FP is happening inside a task... I need to investigate further what's going on. FYI the task calls the function below, which crashes on the instruction assigning 'val'. The assembly is a vmov instruction.
int SetOutputLevel(int db)
{
float val;
db = abs(db);
val = (float)db / 0.375;
db = (int)round(val);
db = LIMIT(db, 0, 0xff);
return adau1966WriteParam(REG_DACMSTR_VOL_ADAU1966_ADDR, db);
}
Hi Marc,
your original report had uncovered an issue in the FreeRTOS port: that
str r1,[r0] \n" /* store to new value back */
was missing there, so that's why on your system with FreeRTOS the FPU is not enabled.
I fixed this issue this morning already: fixed setting FPU registers · 0aa2dbe · GitHub
You could make the same change on your end too. Or use the attached component.
Erich
Hi Erich,
OK I see that. I hacked the instruction in there and that worked, thanks. So I'll update my bean. Thanks for your help!
So I guess there were 2 bugs:
1. no bare metal support for FPU (should be in startup.c) from PE
2. bug in FreeRTOS FPU startup code.
Yes, your guesses are correct ;-)