我正在使用 FreeRTOS 开发 STM32F756ZG。我有一个使用 osThreadDef() 制作的网络线程,它是 CMSIS-RTOS API 的一部分。我还有其他正在运行的任务,这些任务是使用 xTaskCreate() 创建的,它是 freeRTOS API 的一部分。
我有一个由 tempSensor 和 EEPROM 共享的信号量。在网络线程中,我尝试使用 I2C 协议从 EEPROM 中获取 IP 地址的值。它使用 xSemaphoreTake() 成功获取了 Semaphore,但是当它使用 xSemaphoreGive() 放弃 Semaphore 时它会丢失,当我点击暂停时,它会停留在 I2C_WaitOnFlagUntilTimeout() 中。因此它永远不会加载网页。
其他任务运行良好,也使用 I2c 和信号量的温度传感器正确返回值。
所以我的问题是,如果这个问题是因为在两个线程之间使用信号量而产生的,每个线程都是由不同的 OS 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;
当我从引导加载程序跳转到应用程序并尝试从 EEPROM 中读取值时,我可以获取信号量,但我不会使用 xSemaphoreGive() 将其返回。