协议解析-串口协议解析

#define MU_IN_BF_LEN (150)
#define MU_OUT_BF_LEN (150)
uint8_t inbuf[MU_IN_BF_LEN]={0};  //用于保存:从RX中断缓冲buffer中读出的数据
uint8_t outbuf[MU_OUT_BF_LEN]={0};//用于保存:提取出的一个完整帧

#define UART1_RX_RINGBUF_LEN    (250)
static uint8_t uart1_rx_ringbuf[UART1_RX_RINGBUF_LEN]={0};
static struct rt_ringbuffer uart1_rx_ringbuffer_controller={0};

#define UART1_TX_RINGBUF_LEN    (250)
static uint8_t uart1_tx_ringbuf[UART1_TX_RINGBUF_LEN]={0};
static struct rt_ringbuffer uart1_tx_ringbuffer_controller={0};

int init_uart1_link(void)
{
 rt_ringbuffer_init(&uart1_rx_ringbuffer_controller,
      uart1_rx_ringbuf,
      UART1_RX_RINGBUF_LEN);
 
 rt_ringbuffer_init(&uart1_tx_ringbuffer_controller,
       uart1_tx_ringbuf,
       UART1_TX_RINGBUF_LEN);
 
 uart1_send_state=UART1_SEND_IDLE;

 return 0;
}


/*
direct : 0->left move(low bytes out) ,1->right move(high bytes out)
len    : move len                              */
void buffShift(unsigned char *buf,int bufLen,unsigned char direct,int moveLen)
{
 int i=0;
 if(direct==0)
 {//left move
  for(i=0;i   {
   if(i+moveLen>=bufLen)
   {
    buf[i]=0;
   }
   else
   {
    buf[i]=buf[i+moveLen];
   }
  }
 }
 else
 {//right move
  for(i=bufLen-1;i>=0;i--) 
  {
   if(i-moveLen<0)
   {
    buf[i]=0;
   }
   else
   {
    buf[i]=buf[i-moveLen];
   }
  }
 }
}

/*
start feed at buf[StartFeedAddr],StartFeedAddr++, total feedLen Bytes,
cycle loop mode

return :the real feed bytes ,should not over the DstbufMax;
*/
uint16_t buffFeed(unsigned char *Dstbuf,
      unsigned char *Srcbuf,
      uint16_t StartFeedAddr,
       uint16_t feedLen,
       uint16_t DstbufMax
    )
{
 uint16_t i=0;
 for(i=0;i  {
  Dstbuf[StartFeedAddr+i]=Srcbuf[i];
  if(StartFeedAddr+i>=DstbufMax)
  {
   return i;
  }
 }
 return 0;
}

/*
 brief: write one byte to the rx linkbuf

 input:
   databyte: UART1 rx reg data
 return:
   0:failed
   1:success
*/
rt_inline int uart1_wr_rx_link_buffer(uint8_t *buf, int len)
{  
 //return rt_ringbuffer_putchar(&uart1_rx_ringbuffer_controller,databyte);
 return rt_ringbuffer_put(&uart1_rx_ringbuffer_controller,buf,len);
}

/*
 brief: read data from rx link buffer
 input:
   len: bytes amount that want to read out
 output:
   buf: contain the read out datas
 return:
   the really read out bytes amount
note:
  APP call this function to read UART1 rx datas

*/
int uart1_rd_rx_link_buffer(uint8_t *buf,int len)

 return rt_ringbuffer_get(&uart1_rx_ringbuffer_controller,buf,(rt_uint16_t)len);
}

static int multi_parse_one_multi_frame(uint8_t *frame,int multi_len)
{
 OS_ERR os_err;
 int j;
 int dlci;
 int len;
 uint8_t *ptr=NULL;

 //InfoPrintf("\r\n\r\n********************解析长度为%d的帧\r\n");
 //--------提取出一个完整帧--------------------
 #if 0
 InfoPrintf("解析长度为%d的帧:",multi_len);
 
 for(j=0;j  InfoPrintf("%02X",frame[j]); 
 InfoPrintf("\r\n");
 
 for(j=0;j  InfoPrintf("%c",frame[j]);
 InfoPrintf("\r\n");
 #endif
}

/* 
brief: extract one frame from the ringbuffer

input:
   buf    : wait for extract buf
   buf_len: wait buf`s len
 output:
   outbuf   : contain one right extracted multi frame if extract successful
   outbuf_len : out buffer len,if >0 : extract one frame ok
 return:
   -1  : out buf length is error
   others : need_shift_out_amount
*/
int multi_extract_one_rx_frame(uint8_t *buf,   int inbuf_len,
          uint8_t *outbuf,int *outbuf_len,
          int outbuf_max_len,
          int *remain_len
         )
{
 enum extract_multi_stp_t ems_extract_step=EMS_SEARCH_HEAD;
 int i=0;
 uint8_t info_len,outbuf_ptr=0;
 
 uint8_t rx_crc,counting_crc=0;
 //uint8_t add_f,ctl_f,len_f=0;

 int unuseful_amount=0;
 int need_shift_out_amount=0;
 
 //InfoPrintf("当前step=%d\r\n",ems_extract_step);
 
/* InfoPrintf("内部读出\r\n");
 InfoPrintf("当前step=%d\r\n",ems_extract_step);
 InfoPrintf("将处理%d个字节:",inbuf_len);
 for(i=0;i  {
  InfoPrintf("%02X",buf[i]);
  //PrintHex(buf[i]);
 }
 InfoPrintf("\r\n");*/
 

 if(outbuf_max_len < 134 || inbuf_len==0)//(134=4+128+1+1) head,addr,control,length,infoMAX...,crc,tail
 {
  return -1;
 }

 for(i=0;i  { 
  if((ems_extract_step==EMS_SEARCH_HEAD)&&(buf[i]==EMS_HEAD))
  {
   info_len=0;
   outbuf_ptr=0;
   outbuf[outbuf_ptr++]=buf[i];
   ems_extract_step=EMS_SEARCH_ADDR_FIELD;
  }
  else if(ems_extract_step==EMS_SEARCH_ADDR_FIELD)
  {
   outbuf[outbuf_ptr++]=buf[i];
   ems_extract_step=EMS_SEARCH_CTL_FIELD;
   //add_f=buf[i];
  }
  else if(ems_extract_step==EMS_SEARCH_CTL_FIELD)
  {
   outbuf[outbuf_ptr++]=buf[i];
   ems_extract_step=EMS_SEARCH_LEN_FIELD;
   //ctl_f=buf[i];
  }
  else if(ems_extract_step==EMS_SEARCH_LEN_FIELD)
  {
   outbuf[outbuf_ptr++]=buf[i];
   ems_extract_step=EMS_SEARCH_INFO;
   //len_f=buf[i];
   
   info_len=buf[i]>>1;
   //InfoPrintf("消息体长度=%d\r\n",info_len);
  }
  else if(ems_extract_step==EMS_SEARCH_INFO)
  {
   outbuf[outbuf_ptr++]=buf[i];
   if(info_len)
   {
    if(info_len==1)
    {
     ems_extract_step=EMS_SEARCH_CRC;
    }
    info_len--;
   }
  }
  else if(ems_extract_step==EMS_SEARCH_CRC)
  {
   outbuf[outbuf_ptr++]=buf[i];
   
   ems_extract_step=EMS_SEARCH_TAIL;
   rx_crc=buf[i];
   counting_crc=mux_cal_fcs(outbuf+unuseful_amount+1,3);
   //InfoPrintf("校验码=%02X\r\n",counting_crc);
   if(rx_crc==counting_crc)// && rx_crc!=0x5F)//0xA9
   {
    //InfoPrintf("校验码正确=%02X\r\n",counting_crc);
   }
   else
   {
    //InfoPrintf("校验码错误,rx=%02X,count=%02X\r\n",rx_crc,counting_crc);
    ems_extract_step=EMS_SEARCH_HEAD;

    need_shift_out_amount=unuseful_amount+1;//+1:means shift out EMS_HEAD(0xF9)
    return need_shift_out_amount;
   }
  }
  else if(ems_extract_step==EMS_SEARCH_TAIL)
  {
   outbuf[outbuf_ptr++]=buf[i];
   if(buf[i]==EMS_TAIL)
   {
    ems_extract_step=EMS_SEARCH_HEAD;
    *outbuf_len=outbuf_ptr;
    
    need_shift_out_amount=unuseful_amount+outbuf_ptr;
    return need_shift_out_amount;
   }
   else
   {
    //TAIL ERROR
    ems_extract_step=EMS_SEARCH_HEAD;
    need_shift_out_amount=unuseful_amount+1;//+1:means shift out EMS_HEAD(0xF9)
    return need_shift_out_amount;
   }
  }
  else
  {//unuseful bytes
   unuseful_amount++;
  }
 }

 //all inbuf data has been pro

 if(unuseful_amount  {
  *remain_len=inbuf_len-unuseful_amount;
  //InfoPrintf("======分析完毕,存在未完整的有效数据%d字节...=====\r\n",*remain_len);
  
  need_shift_out_amount=unuseful_amount;
  return need_shift_out_amount;
 }
 else
 {
  *remain_len=0;  
  //InfoPrintf("======分析完毕,无有效帧=====\r\n");
  
  need_shift_out_amount=inbuf_len;
  return need_shift_out_amount;
 }
}

//#define multi_pro_rx_data_print
/*
在main()中循环调用此函数:
功能:
读出RX中断的缓冲buffer里的数据,提取完整帧。
提取出完整帧后,剩余的有效数据要保留在inbuf中,下一次从RX中断的缓冲buffer里读出的
数据,将跟在上一次保留的数据后面.
*/
int multi_pro_rx_data(void)
{
 int inbuf_len;
 int outbuf_len;
 int shift_len=0;
 static int remain_len=0;//当剩余有效的数据,但未构成一个完整帧,需要下一次从ringbuffer
         //读取到后续的数据后,才能构成一个完整帧时,remain_len返回>0,
         //其他情况返回 0 !!!! 
 
 inbuf_len=uart1_rd_rx_link_buffer(inbuf+remain_len,MU_IN_BF_LEN-remain_len);

 if(inbuf_len>0)  
 {  
  inbuf_len+=remain_len;//本次读出+上次剩余
  
  #ifdef multi_pro_rx_data_print
  InfoPrintf("读取到+上次剩余,共%d字节有效数据:\r\n",inbuf_len);
  #endif
  while(1) 
  {
   #ifdef multi_pro_rx_data_print
   InfoPrintf("待处理%d字节:",inbuf_len);
   for(j=0;j    {
    InfoPrintf("%02X",inbuf[j]);
   } 
   InfoPrintf("=====\r\n");
   #endif
   
   outbuf_len=0;
   remain_len=0;
   shift_len=multi_extract_one_rx_frame(  inbuf,inbuf_len,outbuf,&outbuf_len,
                MU_OUT_BF_LEN,
                &remain_len//>0 表示:剩余不到一个完整帧的数据
                     //=0 表示:剩余超过一个完整帧的数据 或 剩余0字节 
               );
   if(shift_len>=0)
   {
    if(outbuf_len>0)
    {//提取出完整帧
     multi_parse_one_multi_frame(outbuf,outbuf_len);
    }
    
    #ifdef multi_pro_rx_data_print
    InfoPrintf("左移--%d--字节\r\n",shift_len);
    #endif
    buffShift(inbuf,MU_IN_BF_LEN,0,shift_len);

    inbuf_len=inbuf_len-shift_len;

    if(remain_len>0 || inbuf_len<=0)
    {
     #ifdef multi_pro_rx_data_print
     InfoPrintf("处理完毕(剩余%d字节):",remain_len);
     for(j=0;j      {
      InfoPrintf("%02X",inbuf[j]);
     } 
     InfoPrintf("重新读取...\r\n\r\n\r\n"); 
     #endif
     
     break;
    }
    else
    {
     #ifdef multi_pro_rx_data_print
     InfoPrintf("左移后,剩余-%d-字节,继续处理...\r\n",inbuf_len);
     #endif
     
    }
   }
   else
   {
    InfoPrintf("MULTI参数错误!!!!\r\n");
    break;
   }  
  }
 }
 return 0;
}

你可能感兴趣的:(C,基础)