FreeRTOS中与互斥量的两个任务同步

问题描述 投票:2回答:2

我正在IAR Workbench IDE中的STM32 F401RE MCU上使用FreeRTOS来打开和关闭LED。

led属于STM32核板。有两个任务,一个打开LED,另一个任务关闭相同的LED。

这里是代码:

主要代码:

SemaphoreHandle_t xMutex;
int main()
{  

  if ( xMutex == NULL )  
  {
      xMutex = xSemaphoreCreateMutex();  

      if ( ( xMutex ) != NULL )
        xSemaphoreGive( ( xMutex ) ); 

   }

   xTaskCreate(LedOn, "Led On", 100, NULL,  1, NULL);
   xTaskCreate(LedOff, "Led Off", 100, NULL, 1, NULL);
   vTaskStartScheduler();
   while(1){}

}

任务:

void LedOn(void *argument)
{
   for(;;)
   {  
      xSemaphoreTake( xMutex, ( TickType_t )5000 ) ;     
      HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET);
      vTaskDelay(5000); 
      xSemaphoreGive(xMutex);
    }
}

void LedOff(void *argument)
{
   for(;;)
   {  
      xSemaphoreTake( xMutex, ( TickType_t )5000 ) ;     
      HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);
      vTaskDelay(5000); 
      xSemaphoreGive(xMutex);
    }
}

我的意思是:

领导任务负责领导领导5秒钟

Led off任务负责将Led转向5s

因此,这种情况将一直持续到断电

我的问题是:

[在最初的情况下,LED在LED保持5s断开后保持5s接通,在LED保持接通两次之后,仅在两次上下文切换中起作用。

当我在两次切换后进行调试时,断点未达到任务的要求

c synchronization mutex stm32 freertos
2个回答
2
投票

考虑“任务A”为LedOn,“任务B”为LedOff。或者,也可以相反,因为与问题无关紧要。

假设任务B已获取互斥锁。

您的问题是任务A的xSemaphoreTake正在[可能]超时,而没有获取互斥锁。

您应检查返回码。

原因是它的超时值为5000 ticks。但是,任务B做一个vTaskDelay(5000)。并且,在执行此操作时,它具有互斥锁locked

因此,很有可能任务A的xSemaphoreTake将超时之前任务B释放互斥锁。

然后,您翻转LED值并进行延迟。但是,然后您在互斥锁上执行xSemaphoreGive,表明任务A确实已not已锁定。

换句话说,您有比赛条件。

或者在接听电话中设置无限超时,或者至少设置一个比您赋予延迟功能的值更大的值。

尝试采用(例如10000)的取值


1
投票

优先级计划好的RTOS的通常前提是,准备运行的优先级最高的任务/线程优先于运行优先级较低的任务/线程。

LedOffLedOn任务都是用相同优先级

创建的,因此当发信号量时,上下文切换不会立即发生。

当上下文切换并尝试再次获取信号量时,可能会发生上下文切换。现在有两个任务要解决。

谁赢了本质上是FreeRTOS的实现细节-尤其是对信号量的信号量获取操作是否以严格的FIFO顺序发生-ISTR,VxWorks(FreeRTOS似乎被大量仿效)可以选择执行此操作。

POSIX线程(FreeRTOS也支持)中看到的另一种方法是唤醒等待的线程,并且首先调度要使用的信号量-可以肯定它已经在运行。

更笼统地说,您使带有两个状态的有限状态机变得过于复杂。实现这一目标的高度可靠的方法是:

void LedFlasher(void *argument)
{
   for(;;)
   {      
      HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET);
      vTaskDelay(5000); 
      HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);
      vTaskDelay(5000); 
   }
}
© www.soinside.com 2019 - 2024. All rights reserved.