Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

twi manager perform causes hardfault error

Hi,

I have this generic register read function to handle communicating with my sensor, and during initialisation, it works fine. However, when I try and request a transfer from within a FreeRTOS task (triggered by a semaphore linked interrupt) it causes a hard fault error. I've seen this post https://devzone.nordicsemi.com/f/nordic-q-a/17031/avoiding-hardfault-and-optimizing-code-size-with-twi-transaction-manager saying that my transfer should be static but setting this causes an initialiser not constant errors and surely it's wasteful to have a different function to do every possible function.

Do you know how to stop the manager from causing a hard fault error?

void ppgReadReg(uint8_t *p_buffer,
    uint8_t *p_reg,
    uint8_t length) {

    nrf_twi_mngr_transfer_t const transfers[] =
        {
            NRF_TWI_MNGR_WRITE(MAX_ADDR, p_reg, 1, NRF_TWI_MNGR_NO_STOP),
            NRF_TWI_MNGR_READ(MAX_ADDR, p_buffer, length, 0)};

    APP_ERROR_CHECK(nrf_twi_mngr_perform(&I2C_mngr, NULL, transfers, 2, NULL));
};

Thanks in advance

Parents
  • George,

    It is not the matter of const vs static, or creating a different function to every task. The idea here is the arguments given to the TWI transaction needs to still own the memory space when the TWI manager runs. This is because TWI manager is not a synchronous operation and for every asynchronous operation, you as a programmer should make sure that it runs on a valid memory pointers when it is working on its queue and the memory space pointed by the pointers.

    A simple solution can be below?

    void ppgReadReg(uint8_t *p_buffer,
        uint8_t *p_reg,
        uint8_t length) {
    
        static uint8_t *sp_buffer, *sp_reg, slength = 0;
        sp_buffer = p_buffer;
        sp_reg    = p_reg;
        slength   = length;
    
        nrf_twi_mngr_transfer_t const transfers[] =
            {
                NRF_TWI_MNGR_WRITE(MAX_ADDR, sp_reg, 1, NRF_TWI_MNGR_NO_STOP),
                NRF_TWI_MNGR_READ(MAX_ADDR, sp_buffer, slength, 0)};
    
        APP_ERROR_CHECK(nrf_twi_mngr_perform(&I2C_mngr, NULL, transfers, 2, NULL));
    };

    The assignments in the beginning of the function is necessary to transfer the data from stack memory space to static.

  • When i try compiling this example I get an 'Initialiser element is not constant' error on the assignments at the beginning.

Reply Children
Related