
임베디드 시스템에서 여러 Tasks가 동시에 UART, LCD, 네트워크 소켓 등 출력 장치에 접근하면 결과가 뒤섞이거나 깨져버리는 경우가 잦다. FreeRTOS에서는 이러한 문제를 해결하기 위해 Gatekeeper 패턴을 자주 사용한다.
Gatekeeper 패턴은 자원에 직접 접근하는 Task을 하나만 두고, 나머지 Task는 Queue을 통해 요청만 전달하는 방식이다.
① 큐 생성
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)를 전달한다.vTaskDelay(pdMS_TO_TICKS(100)) 덕분에 약 100 ms 간격으로 메시지가 생성된다.③ Gatekeeper Task
xQueueReceive(xPrintQueue, &pcMessageToPrint, portMAX_DELAY);
Serial.println(pcMessageToPrint);
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