Tilak Sai
Tilak Sai

Reputation: 21

vTaskResume not resuming the task in freertos

I am just learning freertos on stm32f411 DISCO board and keil uVision5. I am trying the function "vTaskResume()" to resume a suspended task and it is not working properly. What the code does is I Suspend the blue led toggle task using the suspend_monitor variable and resume the same task using the resume_monitor variable.

#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);   
}

Upvotes: 0

Views: 1262

Answers (2)

Tilak Sai
Tilak Sai

Reputation: 21

Thank you @QuatCoder for responding but I have found an anomaly around this. I have flashed the previous code and the vBlueLEDControllerTask was suspended successfully but the same task was not resumed. Later when I reset the microcontroller the LEDs showed expected behaviour i.e. the suspended task resumed perfectly.

TaskHandle_t blue_Handle,green_Handle,orange_Handle,red_Handle;

The wierd thing I found was When I declare a dummy handler before blue_Handle was declared like this

TaskHandle_t Dummy_Handle, blue_Handle,green_Handle,orange_Handle,red_Handle;

The tasks resumes perfectly without resetting. I have scratched my around this for a day. I haven't found an explanation for this yet.

Upvotes: 0

QuatCoder
QuatCoder

Reputation: 242

My guess is that your use of these waitloops:

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

is the problem. Instead of the waiting loop try using vTaskDelay to make a useful delay.

Explanation:

The optimiser will usually see that nothing is happening in the loop and ignore it, You can do something 'volatile' in the loop, but even then a microcontroller such as stm32f4 is running around 100-180MHz clock and your 100,000 iterations will still be too fast to see any LED activity, and since FreeRTOS usually uses a granularity of around 1 millisecond for task switching etc, so wont react to anything under this sort of timescale

Upvotes: 1

Related Questions