본문 바로가기

FreeRTOS/FreeRTOS 기본 학습

Create Task & Delete Task , Delay

 

먼저 CubeMX를 이용해서 STM32F4 Discovery 보드 환경설정을 해준다.

https://www.youtube.com/watch?v=CsMUmFLNTok&list=LLnJ3dJnBdwC2gZZdKionReg&index=4&t=169s

다음의 영상을 보면 FreeRTOS 코드를 다운로드해서 따로 설정하지 않아도 MiddleWare로 바로 FreeRTOS를 껴넣을 수있다. 최근에는 FreeRTOS CMSIS_V2 도 사용 할 수 있게 되었는데 더 좋은 성능을 내는 것 같다. 하지만 교육영상에서는 V1을 사용했으므로 V1으로 설정해주자.

 

 

Create Task

 

/* Private user code ---------------------------------------------------------*/ 
/* USER CODE BEGIN 0 */

void Led_GateKeeper(void *pvParameters) 
{ 

	TickType_t xDelay = 500 / portTICK_PERIOD_MS; 

	for(;;) 
	{ 

      HAL_GPIO_WritePin(GPIOD, LD4_Pin|LD3_Pin|LD5_Pin|LD6_Pin, GPIO_PIN_RESET); 
      vTaskDelay(xDelay); 
      HAL_GPIO_WritePin(GPIOD, LD4_Pin|LD3_Pin|LD5_Pin|LD6_Pin, GPIO_PIN_SET); 
      vTaskDelay(xDelay); 

    } 
} 


/* USER CODE END 0 */


int main(void) 
{

...



...



  /* USER CODE BEGIN 2 */ 

  xTaskCreate(Led_GateKeeper, //Task Pointer 
     		(const char* const)"led_gate", //Task Name 
  			configMINIMAL_STACK_SIZE, //Stack Depth , Task에서 printf 문을 사용할 때 HardFault 에러가 날 수 있다. 이때는 Stack Depth를 더 많이 줘야 한다. 
  			0, //Parameters to pass to task 
  			2, //Task Priority 
  			0); //Pass Handle to created task 



  /* USER CODE END 2 */

...



  /* Create the thread(s) */ 
  /* definition and creation of defaultTask */ 
  
  osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128); 
  defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL); 

  /* USER CODE BEGIN RTOS_THREADS */ 
  /* add threads, ... */ 
  
  vTaskStartScheduler();  //이 부분도 꼭 써주자.
  
  /* USER CODE END RTOS_THREADS */ 

  /* Start scheduler */ 
  
  osKernelStart();



.....

 

 

Delete Task

TaskHandle_t Led_GateKeeperHandle = NULL; 

void Led_GateKeeper(void *pvParameters) 
{ 

      int count = (int*) pvParameters; 


      //TickType_t xDelay = 1000 / portTICK_PERIOD_MS; 
      TickType_t xDelay = pdMS_TO_TICKS(1000); 
      TickType_t myLastUnblock; 
      myLastUnblock = xTaskGetTickCount(); 

      for(;;) 
      { 

      HAL_GPIO_WritePin(GPIOD, LD4_Pin|LD3_Pin|LD5_Pin|LD6_Pin, GPIO_PIN_RESET);

      //vTaskDelay(xDelay); //ms가 아닌 number of ticks, (the number of CPU takes that the kernel runs on) 

 

FreeRTOSConfig.h 에서

#define configTICK_RATE_HZ                       ((TickType_t)1000) 로 설정했다면 1000Hz이므로 1Tick은

0.001 sec 즉 1msec가 된다. TickType_t xDelay = pdMS_TO_TICKS(1000); 의 의미는 configTICK_RATE_HZ에 상관없이 

넘겨주는 parameter (msec) 만큼 xDelay를 해준다라는 의미이다.

ex) TickType_t xDelay = pdMS_TO_TICKS(2000); 이면 configTICK_RATE_HZ가 1000이던 5000이던 상관없이

2초간 Delay 해준다는 뜻.

 

vTaskDelayUntil( &myLastUnblock, xDelay ); 

//vTaskDelay 보다 더 안정적인 Delay 함수 사용하려면 FreeRTOSConfig.h 에서 #define INCLUDE_vTaskDelayUntil             1 으로 설정해줘야 함


HAL_GPIO_WritePin(GPIOD, LD4_Pin|LD3_Pin|LD5_Pin|LD6_Pin, GPIO_PIN_SET); 
//vTaskDelay(xDelay); 
vTaskDelayUntil( &myLastUnblock, xDelay ); 


if(count == 12){ vTaskDelete(Led_GateKeeperHandle); //Handler 반환 } 

count++; 

	} 
}



int main(void) 
{



...



  /* USER CODE BEGIN 2 */

int pass = 8;  //Task에 건네 줄 parameter

  //printf("count : %d\r\n", pass); 

  xTaskCreate(Led_GateKeeper, //Task Pointer 
                 (const char* const)"led_gate", //Task Name 
                 configMINIMAL_STACK_SIZE + 200, //Stack Depth 
                 (void *)pass, //Parameters to pass to task 
                 2, //Task Priority 
                 &Led_GateKeeperHandle); //Pass Handle to created task

  /* USER CODE END 2 */



//이 때 Task가 2개인 상태에서 1개의 Task가 Delay에 들어가면 남은 Task들중 priority가 제일 높은 Task가 실행된다. 



    osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128);     //CubeMX가 만들어주는 코드
    defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);       //CubeMX가 만들어주는 코드

    /* USER CODE BEGIN RTOS_THREADS */ 
    /* add threads, ... */ 
    vTaskStartScheduler(); 
    /* USER CODE END RTOS_THREADS */ 

    /* Start scheduler */ 
    osKernelStart();