Я работаю на STM32F756ZG с FreeRTOS. У меня есть один сетевой поток, созданный с помощью osThreadDef (), который является частью CMSIS-RTOS API. У меня также выполняются другие задачи, созданные с помощью xTaskCreate (), который является частью API freeRTOS.
У меня есть семафор, который используется совместно с tempSensor и EEPROM. В сетевом потоке я пытаюсь получить значения для IP-адреса из EEPROM, используя протокол I2 C. Он успешно использует семафор с помощью xSemaphoreTake (), но когда пора отказаться от семафора с помощью xSemaphoreGive (), он теряется, а когда я нажимаю паузу, он остается в I2C_WaitOnFlagUntilTimeout (). В результате он никогда не загружает веб-страницу.
Другие задачи работают нормально, и датчик температуры, который также использует I2 c и sempahore, возвращает значения правильно.
Таким образом, мой вопрос заключается в том, создана ли эта проблема из-за использования семафора между двумя потоками, каждый из которых генерируется различным API ОС. Я действительно борюсь с этим, и любая помощь будет очень признательна. Большое спасибо!
Я добавляю сюда небольшой фрагмент кода.
/* 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
Вот как инициализируется мой семафор:
// Initialize the semaphore that controls eeprom access
xI2C3Semaphore = xSemaphoreCreateMutex();
if( xI2C3Semaphore ==NULL)
{
while(1);
}
Ниже приведен код, когда я читаю 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;
Следующий фрагмент кода - это когда я читаю с датчика температуры:
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;
Когда я прыгаю с загрузчика в приложение и пытаюсь прочитать значения из ЭСППЗУ, я могу взять Семафор, но я не возвращаю его с помощью xSemaphoreGive ().