I am working on STM32F756ZG with FreeRTOS. I have one network thread that is made using osThreadDef() which is a part of the CMSIS-RTOS API. I also have other tasks running that are created using xTaskCreate() which is a part of the freeRTOS API.
I have a Semaphore that is shared by a tempSensor and EEPROM. In the network thread, the I try to get the values for IP address from the EEPROM using I2C protocol. It successfully takes the Semaphore using xSemaphoreTake() but when its time to give up the Semaphore using xSemaphoreGive() it gets lost and when I hit pause it stays in I2C_WaitOnFlagUntilTimeout().As a result it never loads the webpage.
The other tasks run fine and the temp sensor that also uses I2c and sempahore returns the values correctly.
So my question is if this problem is created because of using semaphore between two threads each generated by different OS API. I am really struggling with this and any help would be really appreciated. Thanks a lot!
I am adding a little code snippet here.
/* Init networking thread */
osThreadDef(Start, StartNetworkThread, osPriorityNormal, 0, configMINIMAL_STACK_SIZE * 2);
osThreadCreate (osThread(Start), NULL);
start_threads(3);
HAL_ADC_Start_DMA(&hadc1, (uint32_t*) adc1vals, 1);
HAL_ADC_Start_DMA(&hadc2, (uint32_t*) adc2vals, 1);
xTaskCreate (vADC1, "vADC1", configMINIMAL_STACK_SIZE, NULL, uxPriority + 3, ( TaskHandle_t * ) NULL );
xTaskCreate (vADC2, "vADC2", configMINIMAL_STACK_SIZE, NULL, uxPriority + 3, ( TaskHandle_t * ) NULL );
xTaskCreate (vPIDloop, "vPIDloop", configMINIMAL_STACK_SIZE + 100, NULL, uxPriority + 2, ( TaskHandle_t * ) NULL );
xTaskCreate (vIO, "vIO", configMINIMAL_STACK_SIZE + 512, NULL, uxPriority + 1, ( TaskHandle_t * ) NULL ); //Run IO at least important priority
xTaskCreate (vControl, "vControl", configMINIMAL_STACK_SIZE + 512, NULL, uxPriority + 1, ( TaskHandle_t * ) NULL ); //Run control at least important priority
This is how my Semaphore is initialized:
// Initialize the semaphore that controls eeprom access
xI2C3Semaphore = xSemaphoreCreateMutex();
if( xI2C3Semaphore ==NULL)
{
while(1);
}
Following is the code for when I am reading the EEPROM:
int result = 0;
NvVarsEeprom_t eepromVar;
memset( &eepromVar, 0xff, sizeof(eepromVar) );
if( xI2C3Semaphore != NULL )
{
// Wait forever for semaphore
if( xSemaphoreTake( xI2C3Semaphore, (TickType_t)10 ) == pdTRUE )
{
// count = uxSemaphoreGetCount(xI2C3Semaphore);
// Read from EEPROM
if( nvdata_read((char *)&eepromVar, sizeof(eepromVar), addr) != HAL_OK )
{
//vTaskDelay(5);
if( nvdata_read((char *)&eepromVar, sizeof(eepromVar), addr) != HAL_OK )
{
return ERR_EEPROM;
}
}
//count = uxSemaphoreGetCount(xI2C3Semaphore);
// Give up the semaphore
if(xSemaphoreGive( xI2C3Semaphore ) != pdTRUE)
{
while(1);
}
// count = uxSemaphoreGetCount(xI2C3Semaphore);
}
}
if( result == 0 )
{
eepromVar.valid = NVP_VALID;
}
if( eepromVar.valid == NVP_VALID )
{
strncpy( buf, eepromVar.str, EepromVarSize-1 );
buf[EepromVarSize-1] = '\0';
}
else
{
return ERR_EEPROM;
}
return result;
The next code snippet is when I am reading from the temp sensor:
int tempC = 0;
if( xI2C3Semaphore != NULL )
{
// Wait forever for semaphore
if( xSemaphoreTake( xI2C3Semaphore, (TickType_t)10 ) == pdTRUE )
{
// Read from I2C3
tempC = heatSink_read();
// Give up the semaphore
if(xSemaphoreGive( xI2C3Semaphore ) != pdTRUE)
{
while(1);
}
}
}
return tempC;
When I jump from the bootloader to the application and try to read values from the EEPROM, I can take the Semaphore but I does not give it back using xSemaphoreGive().