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.

Parents
  • 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

  • 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.

Reply
  • 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.

Children
Related