This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

FreeRTOS on nRF52810

Hello,

Does anyone know if the FreeRTOS port that's distributed with the nRF5_SDK_14.2.0 is intended to support nRF52810 chips (which have no hardware FPU)? I started working on an application that would be easier to implement using FreeRTOS but can't get it to work. I was unable to find any mention of it in the existing documentation. SDK 14.2 contains FreeRTOS examples for the other dev boards, but "pca10040e" FreeRTOS examples are missing...

I am getting the following compiler error after including the FreeRTOS files in my project:

Compile output:


Compiling ‘port_cmsis_systick.c’
Compiling ‘queue.c’
Compiling ‘port.c’
     Assembler messages:
        selected processor does not support `vstmdbeq r0!,{s16-s31}' in Thumb mode
        instruction not allowed in IT block -- `stmdb r0!,{r4-r11,r14}'
        selected processor does not support `vldmiaeq r0!,{s16-s31}' in Thumb mode
        instruction not allowed in IT block -- `msr psp,r0'
Compiling ‘tasks.c’
Build failed

  • I don't think so - I get that from

     

    Our port was built using ARM_CM4F port provided by FreeRTOS itself where they have have the same behavior. I guess that the normal approach with freeRTOS would be to use CM3 port for CM4 without FPU if…
    By in Nordic DevZone > Nordic Q&A

    that thread which discussed disabling FPU on FreeRTOS on the nRF52840.  The port used was the M4 port which naturally comes with FPU support enabled. This ought not to be that hard to fix yourself but I don't think the Nordic port out of the box will work for you. 

  • Thanks @RK...

    I think this info confirms that the FreeRTOS port will not work for nRF52810 as is in SDK14.2.... If anyone has pointers on how to fix this, please share the wisdom.. :)  It will be appreciated.

  • Nordic FreeRTOS port does not use FPU for anything. All it does is push the FPU context of the task that is using it to the stack when it is starting the scheduler using PendSV interrupt handler. The best would have been to fence under a macro.

    Comment out below in port_cmsis.c

    #if !(__FPU_USED) && !(__LINT__)
        #error This port can only be used when the project options are configured to enable hardware floating point support.
    #endif

    replace xPortPendSVHandler in port.c with this

    __asm void xPortPendSVHandler( void )
    {
        extern uxCriticalNesting;
        extern pxCurrentTCB;
        extern vTaskSwitchContext;
    
        PRESERVE8
    
        mrs r0, psp
        isb
        /* Get the location of the current TCB. */
        ldr r3, =pxCurrentTCB
        ldr r2, [r3]
    
        /* Is the task using the FPU context?  If so, push high vfp registers. */
    #if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
        tst r14, #0x10
        it eq
        vstmdbeq r0!, {s16-s31}
    #endif
        
        /* Save the core registers. */
        stmdb r0!, {r4-r11, r14}
    
        /* Save the new top of stack into the first member of the TCB. */
        str r0, [r2]
    
        stmdb sp!, {r3}
        mov r0, #(configMAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS))
        msr basepri, r0
        dsb
        isb
        bl vTaskSwitchContext
        mov r0, #0
        msr basepri, r0
        ldmia sp!, {r3}
    
        /* The first item in pxCurrentTCB is the task top of stack. */
        ldr r1, [r3]
        ldr r0, [r1]
    
        /* Pop the core registers. */
        ldmia r0!, {r4-r11, r14}
    
        /* Is the task using the FPU context?  If so, pop the high vfp registers
        too. */
    #if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
        tst r14, #0x10
        it eq
        vldmiaeq r0!, {s16-s31}
    #endif
        msr psp, r0
        isb
    
        bx r14
    
        ALIGN
    }

    The rest of the port is independent of FPU. This should work, given that you have enough space in that chip to run freertos and your appliction

  • Thanks Aryan,

    With your input above, I was able to get FreeRtos to run on nRF52810.... with the following additional changes:

    * Made the same changes you have above to the corresponding port files for the GCC compiler (since that's what I am using)

    * After including the softDevice (running s112) and the FreeRtos files, I ran into a couple of double function definitions that I had to resolve.... One of the double definitions was the "SD_EVT_IRQHandler" function which is in both the nrf_sdh.c and nrf_sdh_frertos.c. Can't remember the other, but it should be obvious if anyone else runs into this....

    Again, thanks for your help!!

  • awesome..  thanks for confirming that it worked. 

Related