cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_I2C_GetState does not work after task creation and before osKernelStart()

JulienD
Senior

Hello

Using FreeRTOS on F412.

Considering this simple function:

void initFromEEprom(void) {
    uint8_t data[10];
    HAL_StatusTypeDef err = HAL_I2C_Mem_Read_DMA(&hi2c1,
                            160, 8,
                            16,
                            (uint8_t*)data,
                            7);
    assert(err == HAL_OK);
    while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY) {
    }
}
 

It works when called within a running task.

It works when called before osKernelStart() AND before creation of any task.

Now, if I do something like this:

int main(void)
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_I2C1_Init();
 
  osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128);
  defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
 
    initFromEEprom();
 
    osKernelStart();
   
    while (1) {
    }
  }

In this case the HAL_I2C_GetState() always returns HAL_I2C_STATE_BUSY_RX.

btw, It took me some hours to understand that this was the reason of my big project failure...

Now, I can do a workaround but looking as osThreadCreate code, I was not able to figure out why this behaviour.

Can anybody explain?

Thanks

Julien

1 REPLY 1
Piranha
Chief II

Posted by richardbarry on February 16, 2012

In the general case, it is not good to allow interrupts to execute before the kernel is started. That is because there is potential for a crash if the ISR attempts to call a FreeRTOS API function before the scheduler has started – or even worse, attempts a context switch (the latter case will definitely cause a crash). Therefore, FreeRTOS API functions will return with interrupts masked to the defined max syscall priority when they are called before the scheduler is started. For example, calling xTaskCreate() before the scheduler is started will result in interrupts being masked.  

You can manually unmask the interrupt by calling taskENABLE_INTERRUPTS(), but interrupts will be masked again if another FreeRTOS API function is called before vTaskStartScheduler().  

Regards.

https://www.freertos.org/FreeRTOS_Support_Forum_Archive/February_2012/freertos_PIC32_using_ISR_before_the_scheduler_start_5040095.html

Also xTaskGetSchedulerState() can be of use for some pre-OS code because of this.