我正在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保持接通两次之后,仅在两次上下文切换中起作用。
当我在两次切换后进行调试时,断点未达到任务的要求
考虑“任务A”为LedOn
,“任务B”为LedOff
。或者,也可以相反,因为与问题无关紧要。
假设任务B已获取互斥锁。
您的问题是任务A的xSemaphoreTake
正在[可能]超时,而没有获取互斥锁。
您应检查返回码。
原因是它的超时值为5000 ticks。但是,任务B做一个vTaskDelay(5000)
。并且,在执行此操作时,它具有互斥锁locked
因此,很有可能任务A的xSemaphoreTake
将超时之前任务B释放互斥锁。
然后,您翻转LED值并进行延迟。但是,然后您在互斥锁上执行xSemaphoreGive
,表明任务A确实已not已锁定。
换句话说,您有比赛条件。
或者在接听电话中设置无限超时,或者至少设置一个比您赋予延迟功能的值更大的值。
尝试采用(例如10000)的取值
优先级计划好的RTOS的通常前提是,准备运行的优先级最高的任务/线程优先于运行优先级较低的任务/线程。
LedOff
和LedOn
任务都是用相同优先级
当上下文切换并尝试再次获取信号量时,可能会发生上下文切换。现在有两个任务要解决。
谁赢了本质上是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);
}
}