본문 바로가기

Firmware/RTOS

임베디드 OS 개발 프로젝트 16(메시징-2)

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에서는 저장된 데이터만 출력한다.