【问题标题】:vTaskResume not resuming the task in freertosvTaskResume 不恢复 freertos 中的任务
【发布时间】:2021-06-05 01:23:27
【问题描述】:

我只是在 stm32f411 DISCO board 和 keil uVision5 上学习 freertos。我正在尝试使用“vTaskResume()”函数来恢复暂停的任务,但它无法正常工作。 代码的作用是我使用 suspend_monitor 变量暂停蓝色 LED 切换任务,并使用 resume_monitor 变量恢复相同的任务。

#include "stm32f4xx_hal.h"              // Keil::Device:STM32Cube HAL:Common
#include "FreeRTOS.h"                   // ARM.FreeRTOS::RTOS:Core
#include "task.h"                       // ARM.FreeRTOS::RTOS:Core
#include <stdbool.h>

#define GREEN  GPIO_PIN_12
#define ORANGE GPIO_PIN_13
#define RED    GPIO_PIN_14
#define BLUE   GPIO_PIN_15

void GPIO_Init(void);

void  vBlueLedControllerTask(void *pvParameters);
void  vRedLedControllerTask(void *pvParameters);
void  vOrangeLedControllerTask(void *pvParameters);
void  vGreenLedControllerTask(void *pvParameters);

TaskHandle_t blue_Handle,green_Handle,orange_Handle,red_Handle;

uint32_t suspend_monitor;
uint32_t resume_monitor;
bool   _suspended =false;

int main()
{
     GPIO_Init();
    
     xTaskCreate(vBlueLedControllerTask,
                             "Blue Led Controller",
                                100,
                                NULL,
                                1,
                                &blue_Handle
                                );
     xTaskCreate(vRedLedControllerTask,
                             "Red Led Controller",
                                100,
                                NULL,
                                1,
                                &red_Handle
                                );
     xTaskCreate(vOrangeLedControllerTask,
                             "Orange Led Controller",
                                100,
                                NULL,
                                1,
                                &orange_Handle
                                );
     xTaskCreate(vGreenLedControllerTask,
                             "Green Led Controller",
                                100,
                                NULL,
                                1,
                                &green_Handle
                                );

   vTaskStartScheduler();
     
     while(1){};
}



void  vBlueLedControllerTask(void *pvParameters)
{
    int i;
    while(1){
        HAL_GPIO_TogglePin(GPIOD, BLUE);
        for(i = 0; i<100000; i++){}
            suspend_monitor++;
            if(suspend_monitor >=10){
                suspend_monitor = 0;
                _suspended = true;
                vTaskSuspend(NULL);
    }
}
}



void  vRedLedControllerTask(void *pvParameters)
{
    int i;
    while(1){
        HAL_GPIO_TogglePin(GPIOD, RED);
        for(i = 0; i<100000; i++){};
        if(_suspended){
            resume_monitor++;
            if(resume_monitor >=10){
                vTaskResume(blue_Handle);
                resume_monitor = 0;
                _suspended = false;
            }
        }
    }
}

void  vOrangeLedControllerTask(void *pvParameters)
{
int i;
    while(1){
        HAL_GPIO_TogglePin(GPIOD, ORANGE);
        for(i = 0; i<100000; i++);
    }
}

void  vGreenLedControllerTask(void *pvParameters)
{
    int i;
    while(1){
        HAL_GPIO_TogglePin(GPIOD, GREEN);
        for(i = 0; i<100000; i++);
    }
}

void GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct;

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_RESET);

  /*Configure GPIO pins : PD12 PD13 PD14 PD15 */
  GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);   
}

【问题讨论】:

  • 在我按下重置开关后似乎工作正常。

标签: c++ stm32 freertos


【解决方案1】:

我的猜测是您对这些等待循环的使用:

for(i = 0; i<100000; i++){};

是问题所在。我尝试使用vTaskDelay代替等待循环来进行有用的延迟。

解释:

优化器通常会看到循环中没有发生任何事情并忽略它, 你可以在循环中做一些“不稳定”的事情,但即便如此,像 stm32f4 这样的微控制器运行在 100-180MHz 时钟左右,你的 100,000 次迭代仍然太快而看不到任何 LED 活动,而且由于 FreeRTOS 通常使用大约任务切换等 1 毫秒,所以在这种时间尺度下不会对任何事情做出反应

【讨论】:

    【解决方案2】:

    感谢@QuatCoder 的回复,但我发现了一个异常情况。我已经刷新了之前的代码,并且 vBlueLEDControllerTask 已成功挂起,但未恢复相同的任务。后来,当我重置微控制器时,LED 显示出预期的行为,即暂停的任务完美恢复。

    TaskHandle_t blue_Handle,green_Handle,orange_Handle,red_Handle;
    

    我发现的奇怪的事情是当我在这样声明 blue_Handle 之前声明一个虚拟处理程序时

    TaskHandle_t Dummy_Handle, blue_Handle,green_Handle,orange_Handle,red_Handle;
    

    任务无需重置即可完美恢复。我已经花了一天时间来解决这个问题。我还没有找到对此的解释。

    【讨论】:

    • 不知道。也许尝试定期检查 Dummy_Handle 的值是否为 0?
    猜你喜欢
    • 2016-12-25
    • 1970-01-01
    • 2016-08-07
    • 1970-01-01
    • 2020-12-17
    • 1970-01-01
    • 2011-07-05
    • 2017-07-02
    • 2023-03-03
    相关资源
    最近更新 更多