Hi @EduardoZamora
I investigated the issue further and found a difference between the HIF demo and our application.
The HIF demo is running with the NULL OS implementation, whereas our application is running with FreeRTOS. After starting the I2C transaction, the driver waits for an event to be posted from the I2C ISR when the transfer completes.
In our application, the I2C ISR eventually calls:
phStatus_t phOsal_EventPost(phOsal_Event_t * eventHandle,
phOsal_EventOpt_t options,
phOsal_EventBits_t FlagsToPost,
phOsal_EventBits_t *pCurrFlags)
{
BaseType_t HigherPriorityTaskWoken;
phOsal_EventBits_t CurrentFlags;
if((eventHandle == NULL) || ((*eventHandle) == NULL))
{
return (PH_OSAL_ERROR | PH_COMP_OSAL);
}
HigherPriorityTaskWoken = pdFALSE;
if (xPortIsInsideInterrupt() == pdTRUE)
{
CurrentFlags = xEventGroupSetBitsFromISR(
*eventHandle,
FlagsToPost,
&HigherPriorityTaskWoken);
if(CurrentFlags == pdPASS)
{
portYIELD_FROM_ISR(HigherPriorityTaskWoken);
}
}
else
{
CurrentFlags = xEventGroupSetBits(
*eventHandle,
FlagsToPost);
}
if (pCurrFlags != NULL)
{
*pCurrFlags = CurrentFlags;
}
return PH_OSAL_SUCCESS;
}While debugging, the execution flow is:
I2C ISR
-> phOsal_EventPost()
-> xEventGroupSetBitsFromISR()
-> xTimerPendFunctionCallFromISR()
-> xQueueSendFromISR()Inside FreeRTOS:
BaseType_t xTimerPendFunctionCallFromISR(
PendedFunction_t xFunctionToPend,
void * pvParameter1,
uint32_t ulParameter2,
BaseType_t * pxHigherPriorityTaskWoken )
{
DaemonTaskMessage_t xMessage;
BaseType_t xReturn = pdPASS;
xMessage.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR;
xMessage.u.xCallbackParameters.pxCallbackFunction = xFunctionToPend;
xMessage.u.xCallbackParameters.pvParameter1 = pvParameter1;
xMessage.u.xCallbackParameters.ulParameter2 = ulParameter2;
xReturn = xQueueSendFromISR(
xTimerQueue,
&xMessage,
pxHigherPriorityTaskWoken );
return xReturn;
}At this point, xTimerQueue is NULL.
xQueueSendFromISR() checks the queue handle using:
configASSERT(pxQueue);
and our assert is defined as:
#define configASSERT(x) \
if((x) == 0) \
{ \
taskDISABLE_INTERRUPTS(); \
for(;;); \
}Since xTimerQueue is NULL, the code enters the infinite loop. When running normally, it eventually results in a HardFault.
For comparison, the NULL OS implementation of phOsal_EventPost() is:
phStatus_t phOsal_EventPost(
phOsal_Event_t * eventHandle,
phOsal_EventOpt_t options,
phOsal_EventBits_t FlagsToPost,
phOsal_EventBits_t *pCurrFlags)
{
if((eventHandle == NULL) || ((*eventHandle) == NULL))
{
return PH_OSAL_ADD_COMPCODE(PH_OSAL_ERROR, PH_COMP_OSAL);
}
phOsal_EnterCriticalSection();
(*((uint32_t *)(*eventHandle))) |= FlagsToPost;
if (pCurrFlags != NULL)
{
*pCurrFlags = (*((uint32_t *)(*eventHandle)));
}
phOsal_ExitCriticalSection();
phOsal_WakeUp();
return PH_OSAL_SUCCESS;
}This implementation does not use Event Groups, Timer Service Tasks, or Timer Queues, so it works correctly in the HIF demo.
Could you please advise whether additional FreeRTOS timer service initialization is required before using the I2C/HIF drivers, or if there is a recommended FreeRTOS configuration for this use case?
Thanks.