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

Bus Fault after calling __get_FPSCR in FreeRTOS configPRE_SLEEP_PROCESSING(x)

I'm trying to set up a project with SDK 16.0.0 using FreeRTOS with the softdevice.  The device will be battery powered and therefore power management capabilities are required.

My freeRTOSConfig.h is the same as in the ble_app_hrs_freertos_pca10040_s132 with the following additions:

#if ( __FPU_PRESENT)
#define PWR_MGMT_FPU_SLEEP_PREPARE() pwr_mgmt_fpu_sleep_prepare()
extern void pwr_mgmt_fpu_sleep_prepare(void);
#else
#define PWR_MGMT_FPU_SLEEP_PREPARE()
#endif // NRF_PWR_MGMT_CONFIG_FPU_SUPPORT_ENABLED

#define configPRE_SLEEP_PROCESSING(x) PWR_MGMT_FPU_SLEEP_PREPARE()

#define configSUPPORT_STATIC_ALLOCATION

Based on this thread I tried to add pwr_mgmt_fpu_sleep_prepare in main.c, however my code gets a busfault any time I use the __get_FPSCR() or __set_FPSCR() macro.

My application works as expected except not sleeping when I comment out the FPSCR macros.

When I uncomment the macro's the busfault breakpoint triggers and the PC is stopped at address 0xA60.

Do I need to implement this sleep prepare step?

Why do these FPSCR macro's cause a bus fault?

Given:

1) I'm not even using the FPU.

2) This example only performs some I2C operations once per second

3) I have RTC2 enabled and operating at 32KHz with only overflow interrupt enabled ( for tracking time independent from freeRTOS )

4) I have an idle task hook that does NRF_LOG_FLUSH with NRF_LOG_ENABLED

Then will it be reasonable to expect the sd_app_evt_wait() call to sleep for some amount of time?  It seems at the moment it will never sleep despite every task being blocked/suspended.

  • Hi,

    Access to these registers should not be restricted. Are you not able to enter sleep with sd_app_evt_wait()? Are you experiencing immediate wakes, since it looks like you try to implement the workaround for FPU errata?

    Do you have a sample project that we can use to reproduce this behavior?

    Best regards,
    Jørgen

  • Yes based on the many issues reported here on devzone, I implemented the workaround for FPU errata. 

    Yes I am experiencing immediate wakes... the call to sd_app_evt_wait returns with no time passed.

    My project contains proprietary code that I cannot release publicly.  

    Is there an example project that demonstrates low power operation with freertos on nrf52832 while using ble and nrf log library with an RTT backend?   

  • I did a test with the HRS FreeRTOS example. The only modifications I made was to enable RTT logging and disable UART logging:

    //==========================================================
    // <e> NRF_LOG_BACKEND_RTT_ENABLED - nrf_log_backend_rtt - Log RTT backend
    //==========================================================
    #ifndef NRF_LOG_BACKEND_RTT_ENABLED
    #define NRF_LOG_BACKEND_RTT_ENABLED 1
    #endif
    
    // <e> NRF_LOG_BACKEND_UART_ENABLED - nrf_log_backend_uart - Log UART backend
    //==========================================================
    #ifndef NRF_LOG_BACKEND_UART_ENABLED
    #define NRF_LOG_BACKEND_UART_ENABLED 0
    #endif

    And add a call to sd_app_evt_wait() in the application idle hook:

    void vApplicationIdleHook( void )
    {
    #if NRF_LOG_ENABLED
         vTaskResume(m_logger_thread);
    #endif
        if (nrf_sdh_is_enabled())
        {
            uint32_t err_code = sd_app_evt_wait();
            APP_ERROR_CHECK(err_code);
        }
    }

    This is the current that I measure (average over 24 seconds, and average IDLE current between BLE events):

    Are you sure that you are not in debug mode when you measure the current? This could happen if you read the logs over RTT/SWD.

  • After modifying the freertos example to eliminate the vApplicationIdleHook and instead unblock the logger task from a hook in the logger library, I have been able to see the freertos port sleep as expected.

    The immediate wakes were caused by the idle hook resuming the logger task.  This causes freertos to always have a task to run and never sleep.  Nordic should remove this from the example, it doesn't work and causes customers to waste engineering time.  

    I will implement FPU interrupt to handle FPU errors next and I may still have some questions.

  • what exact change did you make to eliminate the vApplicationIdleHook and where exactly did you unblock the logger task?

    Did you understand why it was keeping your system awake if unblocking in idleHook? It is the safest way to run the logs when rest of the rtos tasks are not running. 

    The change that you said does not make sense unless you have changed the priority of the logger task so high that it is not allowing any other task to run. 

    Nordic should remove this from the example, it doesn't work and causes customers to waste engineering time.  

    The example is done correctly in terms of how logging is handled. It very much looks like this was caused due to choosing of wrong priorities of the tasks. 

Related