Multithreading 当被不同的线程使用时,xSemaphoreGive()会被卡住

Multithreading 当被不同的线程使用时,xSemaphoreGive()会被卡住,multithreading,semaphore,stm32,freertos,cmsis,Multithreading,Semaphore,Stm32,Freertos,Cmsis,我正在与FreeRTOS合作开发STM32F756ZG。我有一个网络线程,它是使用osThreadDef()生成的,osThreadDef()是CMSIS-RTOS API的一部分。我还运行了使用xTaskCreate()创建的其他任务,xTaskCreate()是freeRTOS API的一部分 我有一个由tempSensor和EEPROM共享的信号量。在网络线程中,我尝试使用I2C协议从EEPROM获取IP地址的值。它使用xSemaphoreTake()成功地获取了信号量,但当使用xSema

我正在与FreeRTOS合作开发STM32F756ZG。我有一个网络线程,它是使用osThreadDef()生成的,osThreadDef()是CMSIS-RTOS API的一部分。我还运行了使用xTaskCreate()创建的其他任务,xTaskCreate()是freeRTOS API的一部分

我有一个由tempSensor和EEPROM共享的信号量。在网络线程中,我尝试使用I2C协议从EEPROM获取IP地址的值。它使用xSemaphoreTake()成功地获取了信号量,但当使用xSemaphoreGive()放弃信号量时,它会丢失,当我点击pause时,它会停留在I2C_WaitOnFlagUntilTimeout()中。因此,它不会加载网页

其他任务运行正常,同时使用I2c和sempahore的温度传感器正确返回值

所以我的问题是,这个问题是否是因为在两个线程之间使用信号量造成的,每个线程都是由不同的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()返回信号量。

首先,确保信号量已正确初始化,如下所示:

if ((SemId_I2C1_Rx  = xSemaphoreCreateBinary()) == NULL) { goto InitFailed; };
其次,确保您使用了适当的函数来提供信号量

如果是从中断发出的,则必须使用

xSemaphoreGiveFromISR(SemId_I2C1_Rx, NULL);

我没有看到任何相关代码。问题哪一个不能回答你想要实现什么?@P_uj_u我想从EEPROM中读取值,这样我就可以得到IP地址值并加载网页。现在,我只能让温度传感器或Webage工作,而不是两者。所以基本上我有两个线程,一个从EEPROM读取值并启动网页,另一个从温度传感器获取值。两者都使用I2c并共享相同的信号量。您不需要计算信号量。您需要互斥量或二进制信号量。@P_uj_uu我正在使用xSemaphoreCreateMutex()创建信号量,并使用count进行调试。此外,如果我使用调试器自己运行应用程序,我可以访问EEPROM以及温度传感器。当我从引导加载程序跳转时,我无法同时访问它们。我的引导加载程序有自己的网页,也可以使用I2C访问EEPROM。在跳到应用程序之前,我否认一切。很长一段时间以来,我一直在坚持这一点,我真的非常感谢任何帮助。非常感谢。如果你没有看到任何与信号量相关的代码,你能给我什么建议呢?谢谢你的劝阻,我再也不会浪费时间帮助这里的任何人了。只要用正确的方式回答问题就行了。这个问题无法回答,因为没有代码&没有实际的问题。所以,@P_uj_u_u________________________________。我已经补充了一些细节。如果有任何帮助,我将不胜感激。谢谢