KL25Z I2C RTOS api hangs forever (HardFault)

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

KL25Z I2C RTOS api hangs forever (HardFault)

Jump to solution
2,245 Views
jmsan
Contributor II

I am trying to port the KL25Z Accelerometer I2C example to FreeRTOS so that instead of using the SDK's I2C driver it uses the FreeRTOS's I2C driver.

After configuring I2C pins and release I2C bus I try to Init the IC2 RTOS driver.

I2C_MasterGetDefaultConfig(&masterConfig);

masterConfig.baudRate_Bps = I2C_BAUDRATE;

sourceClock = ACCEL_I2C_CLK_FREQ;

//I2C_MasterInit(BOARD_ACCEL_I2C_BSEADDR, &masterConfig, sourceClock);
NVIC_SetPriority(ACCEL_I2C_MASTER_IRQN, configMAX_PRIORITIES - 1);

status = I2C_RTOS_Init(&master_rtos_handle, ACCEL_I2C_MASTER, &masterConfig, sourceClock);

status reported to be 0x00

Then I configure the first transfer message

i2c_master_transfer_t masterXfer;
    memset(&masterXfer, 0, sizeof(masterXfer));

    masterXfer.slaveAddress = 0x1DU;
    masterXfer.direction = kI2C_Write;
    masterXfer.subaddress = 0;
    masterXfer.subaddressSize = 0;
    masterXfer.data = &who_am_i_reg;
    masterXfer.dataSize = 1;
    masterXfer.flags = kI2C_TransferNoStopFlag;

This message is only to check that the Accelerometer is there. The slave Adress direction is already set to 0x1DU because I want to jump the part of the example which tries a set of addresses to check devices.

Then I start the transfer:


    g_m_handle = &master_rtos_handle.drv_handle;
    status = I2C_RTOS_Transfer(&master_rtos_handle, &masterXfer);

The task goes inside the I2C_RTOS_Transfer  takes the semaphore and starts:

status = I2C_MasterTransferNonBlocking(handle->base, &handle->drv_handle, transfer);

if (status != kStatus_Success)
    {
        xSemaphoreGive(handle->mutex);
        return status;
    }

status again reported to be 0x00 so the transfer is a sucess.

But then the task tries to Take the semaphore again but the semaphore is never given.

  /* Wait for transfer to finish */
    xSemaphoreTake(handle->semaphore, portMAX_DELAY);

If I am not mistaken after the I2C_MasterTransferNonBlocking is completed the task should call I2C_RTOS_Callback which in turn should Give the Semaphore.

static void I2C_RTOS_Callback(I2C_Type *base, i2c_master_handle_t *drv_handle, status_t status, void *userData)
{

 i2c_rtos_handle_t *handle = (i2c_rtos_handle_t *)userData;
    BaseType_t reschedule;
    handle->async_status = status;
    xSemaphoreGiveFromISR(handle->semaphore, &reschedule);
    portYIELD_FROM_ISR(reschedule);

}

But the I2C_RTOS_Callback is never called so the semaphore is never given and so the code hangs in    

xSemaphoreTake(handle->semaphore, portMAX_DELAY);

I tried the code with a set of priorities higher and lower than 5, but none seem to work.The debugger trace shows that the program follows this path:

xSemaphoreTake -> xQueueGenericReceive --> vTaskPlaceOnEventList ---> vListInsert -->     pxNewListItem->pxNext = pxIterator->pxNext; --> ldr   r0,=HardFault_Handler

What on earth I am missing here?

Thank you.

0 Kudos
Reply
1 Solution
1,733 Views
jmsan
Contributor II

Hi, thank you for the reply, I just resolved this issue calling the RTOS code after initialitzating the RTOS environment and the scheduler.

It was a problem of design.

View solution in original post

0 Kudos
Reply
4 Replies
1,733 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Jm,

I have the FRDM board of Kl family, can you post your project here so that I can help to debug to track the cause of the hardfault event?

BR

Xiangjun Rong

0 Kudos
Reply
1,734 Views
jmsan
Contributor II

Hi, thank you for the reply, I just resolved this issue calling the RTOS code after initialitzating the RTOS environment and the scheduler.

It was a problem of design.

0 Kudos
Reply
1,733 Views
zvanende
Contributor II

Could you upload an example or explain detailed how you solved this? I have the same problem and can't seem to resolve it.

0 Kudos
Reply
1,733 Views
jmsan
Contributor II

Update 1: The problem seems to be that if I try to use (transfer - receive functions )  I2C RTOS driver at the main loop before creating the tasks and starting the scheduler the system seems to enter that hard fault in the xQueue.

I think that my design is incorrect due to whatever i am missing to allow me use I2C RTOS driver (transfer - receive functions) at the main function before starting the task scheduler. I think in the rtos examples provided by the SDK they all configure RTOS driver in the main loop and then use the transfer receive functions inside the task after starting the scheduler an the task themselves. 

I did that design only because I need to send and receive to configure the external devices before entering the reading tasks. That's it just wanting to configure things before starting all scheduler stuff.

How to allow the RTOS use IRQ - Callbacks at main before starting the scheduler?

0 Kudos
Reply