Gatekeeper

hyeony·2025년 8월 31일

RTOS

목록 보기
6/8

1. Gatekeeper

가. Introduction to Gatekeeper

임베디드 시스템에서 여러 Tasks가 동시에 UART, LCD, 네트워크 소켓 등 출력 장치에 접근하면 결과가 뒤섞이거나 깨져버리는 경우가 잦다. FreeRTOS에서는 이러한 문제를 해결하기 위해 Gatekeeper 패턴을 자주 사용한다.

Gatekeeper 패턴은 자원에 직접 접근하는 Task을 하나만 두고, 나머지 Task는 Queue을 통해 요청만 전달하는 방식이다.

나. Code Implementation

① 큐 생성

	xPrintQueue = xQueueCreate(5, sizeof(char *));

각 Task는 문자열 포인터를 Queue에 넣고, Gatekeeper Task가 이를 소비한다.

② 출력 태스크

	xTaskCreate(OutputTask,"Printer 1", 100,(void *)0,1,NULL );
	xTaskCreate(OutputTask,"Printer 2", 100,(void *)1,2,NULL );
  • pvParameters로 인덱스(0 또는 1)를 전달한다.
  • Task는 주기적으로 자신의 문자열 포인터를 Queue에 넣는다.
  • vTaskDelay(pdMS_TO_TICKS(100)) 덕분에 약 100 ms 간격으로 메시지가 생성된다.

③ Gatekeeper Task

xQueueReceive(xPrintQueue, &pcMessageToPrint, portMAX_DELAY);
Serial.println(pcMessageToPrint);
  • Queue에서 메시지가 도착할 때까지 기다린다.
  • 메시지를 받으면, Serial.println()으로 출력한다.
  • 모든 출력이 이 태스크에서만 이루어지므로, 출력이 섞이지 않고 깔끔하게 나온다.

④ 전체 코드

#include <Arduino_FreeRTOS.h>
#include"semphr.h"


static const char *pcStringToPrint[] =
{
  "Task 1 ############################## Task1 \r\n",
  "Task 2 ------------------------------ Task2 \r\n",
  "TICK HOOK&&&&&&&&&&&&&&&&&&&&&&&&&&&& TICK HOOK \r\n"
  
};

QueueHandle_t xPrintQueue;
void setup()
{
   Serial.begin(9600);
  xPrintQueue = xQueueCreate(5,sizeof(char *));

  xTaskCreate(OutputTask,"Printer 1", 100,(void *)0,1,NULL );
  xTaskCreate(OutputTask,"Printer 2", 100,(void *)1,2,NULL );

  xTaskCreate(GateKeeperTask, "GateKeeper", 100,NULL,0,NULL);
  
}
void OutputTask(void *pvParameters)
{
  int indexToString ;
  indexToString = (int)pvParameters;

  while(1)
  {
   xQueueSend(xPrintQueue,&(pcStringToPrint[indexToString]),portMAX_DELAY); 
   vTaskDelay(pdMS_TO_TICKS(100));

  }
  
}

void GateKeeperTask(void *pvParameters)
{
  char *pcMessageToPrint;
  while(1)
  {
   xQueueReceive(xPrintQueue,&pcMessageToPrint,portMAX_DELAY);
   Serial.println(pcMessageToPrint); 
  }
}

//void vApplicationTickHook(void)
//{
//  static int counter =0;
//  counter++;
//  if(counter >=200)
//  {
//    xQueueSendToFrontFromISR(xPrintQueue,&(pcStringToPrint[2]),NULL);
//    counter =0;
//  }
//}

void loop(){}

⑤ 결과
시리얼 모니터(9600bps)에 다음과 같이 출력된다.

Task 1 ############################## Task1 
Task 2 ------------------------------ Task2 
Task 1 ############################## Task1 
Task 2 ------------------------------ Task2 
...

Tick Hook을 활성화하면 주기적으로 다음 메시지도 출력된다.

TICK HOOK&&&&&&&&&&&&&&&&&&&&&&&&&&&& TICK HOOK

<참고 자료>
https://www.udemy.com/course/arduino-freertos/

profile
Chung-Ang Univ. EEE.

0개의 댓글