http://www.yes24.com/Product/Goods/84909414
TREE 생략
이전에 이어서 메시징 테스트를 위해 작성한Task#0 알고리즘이다.
Task#0 FlowChart
User_Task#0
void User_task0(void)
{
uint8_t cmdBuf[16];
uint8_t recvBuf[16];
uint8_t recv_length = 0;
uint8_t recv_index = 0;
uint8_t fail_index = 0;
while(true)
{
debug_printf("User Task #0\n");
KernelEventFlag_t handle_event = Kernel_wait_events(KernelEventFlag_UartIn);
switch(handle_event)
{
case KernelEventFlag_UartIn:
debug_printf("Uart Event Handle \n");
recv_length = MsgQ_recv_length(KernelMsgQ_Task0);
Kernel_recv_msg(KernelMsgQ_Task0,recvBuf,recv_length);
if ((recvBuf[recv_length-1] == '\r'))
{
recv_index = Buffer_push_msg(&recv_index,&recv_length,recvBuf,cmdBuf);
Kernel_send_msg(KernelMsgQ_Task1, &recv_index, 1);
Kernel_send_msg(KernelMsgQ_Task1, cmdBuf, recv_index);
Kernel_send_events(KernelEventFlag_CmdOut);
memclr(cmdBuf, 16);
recv_index = 0;
}
else
{
fail_index = recv_index;
recv_index = Buffer_push_msg(&recv_index,&recv_length,recvBuf,cmdBuf);
if(recv_index == fail_index)
{
debug_printf("data save fail.\n");
}
else
{
debug_printf("data saved \n");
}
}
break;
}
delay(1000);
Kernel_yield();
}
}
책에 있는 코드에서 좀더 붙인 코드이다. 코드는 Flow chart를 보면서 따라가면 된다.
이전글에 언급한 burst 부분은 들어온 recv_length를 구하여 Kernel_recv_msg 호출 할 때 recv_length를 argument로 사용하여 burst 한다.
Task#1 FlowChart
User_task#1
void User_task1(void)
{
uint8_t cmdlen = 0;
uint8_t cmd[16] = {0};
while(true)
{
debug_printf("User Task #1\n");
KernelEventFlag_t handle_event = Kernel_wait_events(KernelEventFlag_CmdOut);
switch(handle_event)
{
case KernelEventFlag_CmdOut:
memclr(cmd, 16);
Kernel_recv_msg(KernelMsgQ_Task1, &cmdlen, 1);
Kernel_recv_msg(KernelMsgQ_Task1, cmd, cmdlen);
debug_printf("receive Message: %s\n",cmd);
break;
}
delay(1000);
Kernel_yield();
}
}
Task#0에서 setting 한 cmd event로 판단하여 Message queue 에 쌓인 데이터를 받아 읽는다.
MsgQ_recv_length
uint8_t MsgQ_recv_length(KernelMsgQ_t Qname)
{
uint8_t data;
if(Kernel_msgQ_is_full(Qname))
{
return 16;
}
if( sMsgQ[Qname].rear > sMsgQ[Qname].front )
{
data = (sMsgQ[Qname].rear - sMsgQ[Qname].front);
if( data < 17 )
{
return data;
}
return 0;
}
else
{
data = ((sMsgQ[Qname].rear)+16 - sMsgQ[Qname].front);
if( data < 17 )
{
return data;
}
return 0;
}
}
Message queue에 쌓인 데이터 길이를 구하는 함수이다.
만약 message queue 버퍼가 full 일경우 16을 return 하여 buffer push msg 함수에서 더이상 데이터를 저장하지 못하도록 한다.
Buffer_push_msg
uint8_t Buffer_push_msg(uint8_t* index, uint8_t* length, uint8_t* sendBuf, uint8_t* recvBuf)
{
uint8_t sIndex = *index;
uint8_t sLength = *length;
if((sIndex + sLength) < 16)
{
for(int i = sIndex; i < (sIndex + sLength); i++)
{
recvBuf[i] = *(sendBuf +i - sIndex);
}
sIndex += sLength;
return sIndex;
}
else
{
return sIndex;
}
}
Task#0에서 데이터가 저장 될 때마다 사용하는 함수이다.
index 와 length를 더했을 때 16이 초과 되면 message buffer가 full 이므로 index를 그대로 return 하여
fail message를 호출한다.
실제 실행 화면
123 입력후 enter를 치지 않아 Task#0 에서 data가 저장 되었고 aa는 입력이 16개가 넘어 저장에 실패하였다.
다시 456 입력후 enter를 입력하여 Task#1에 메시지를 보냈고 Task#1에서는 저장된 데이터만 출력한다.
'Firmware > RTOS' 카테고리의 다른 글
임베디드 OS 개발 프로젝트 18(뮤텍스) - 마지막 장 (1) | 2020.03.26 |
---|---|
임베디드 OS 개발 프로젝트 17(세마포어) (0) | 2020.03.20 |
임베디드 OS 개발 프로젝트 15(메시징) (0) | 2020.03.15 |
임베디드 OS 개발 프로젝트 14(Event 처리) (0) | 2020.03.11 |
임베디드 OS 개발 프로젝트 13(Context Switching - Priority) (0) | 2020.03.10 |