#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<bufLen;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<feedLen;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<multi_len;j++)
 InfoPrintf("%02X",frame[j]); 
 InfoPrintf("\r\n");
 
 for(j=0;j<multi_len;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<inbuf_len;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<inbuf_len;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<inbuf_len)
 {
  *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<inbuf_len;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<remain_len;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;
}

协议解析-串口协议解析相关推荐

  1. FPGA解析串口协议帧3.0版本,增加了错误重发功能,提供仿真文件以及源码

    FPGA解析串口协议帧已经发布2个版本了,分别如下: 版本1:点击查看版本1 版本1详细介绍了串口协议帧的帧组成和设计思想,但设计粗糙,注释不详细: 版本1:点击查看版本2 版本2优化了代码,添加了详 ...

  2. UART串口协议基础1

    Louis kaly.liu@163.com 串口协议基础 1 串口概述 串口由收发器组成.发送器是通过TxD引脚发送串行数据,接收器是通过RxD引脚接收串行数据. 发送器和接收器都利用了一个移位寄存 ...

  3. 超详细解析 | 一致性协议算法-2PC、3PC、Paxos、Raft、ZAB、NWR

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 来源:r6d.cn/VMW9 背景 在常见的分布式系统中, ...

  4. 【网络通信与信息安全】之深入解析HTTP协议的实现和原理

    一.计算机网络体系结构分层 计算机网络体系结构分层示例图 计算机网络体系结构说明: 二.TCP/IP 通信传输流 ① TCP/IP 分层管理 TCP/IP 构成 应用层:决定了向用户提供应用服务时通信 ...

  5. 解析HTTP协议六种请求方法,get,head,put,delete,post有什么区别

    转载自  解析HTTP协议六种请求方法,get,head,put,delete,post有什么区别 标准Http协议支持六种请求方法,即: 1.GET 2.POST 3.PUT 4.Delete 5. ...

  6. 协议簇:TCP 解析:TCP 数据传输

    简介 前面,我们分别介绍了 TCP 基础知识以及连接的建立和关闭,以及最重要的 Sequence Number 的概念. 本篇文章,我们来介绍一下 TCP 如何传输数据. 系列文章 协议簇:TCP 解 ...

  7. 协议簇:TCP 解析: Sequence Number

    简介 序列号(Sequence Number) 是 TCP 协议中非常重要的一个概念,以至于不得不专门来学习一下.这篇文章我们就来解开他的面纱. 在 TCP 的设计中,通过TCP协议发送的每个字节都对 ...

  8. 协议簇:TCP 解析: 连接断开

    简介 接前文 协议簇:TCP 解析: 建立连接, 我们这篇文章来看看 TCP 连接断开的过程,也就是众所周知的"四次挥手"的具体流程. 系列文章 协议簇:TCP 解析:基础 协议簇 ...

  9. 协议簇:TCP 解析: 建立连接

    简介 接前文 协议簇:TCP 解析: 基础, 我们这篇文章来看看 TCP 连接建立的过程,也就是众所周知的"三次握手"的具体流程. 系列文章 协议簇:TCP 解析:基础 协议簇:T ...

  10. 协议簇:TCP 解析: 基础

    简介 本文我们将从 RFC 学习一下 RFC793 中描述的 TCP 协议. 这将区别于通常讲解计算机网络书籍中所描述的 TCP. 但他们必然是相统一的,不会互相冲突. 系列文章 协议簇:TCP 解析 ...

最新文章

  1. IBM中国开发中心吉燕勇: 通过Cloud Data Services打造新型认知计算数据分析云平台...
  2. 宝典9.2——海量数据的基本处理方法
  3. [论文泛读]Web服务组合综述相关论文1(3篇)
  4. iOS 10 之后权限设置
  5. win10一按右键就闪屏_升级Win10正式版后屏幕一直闪烁正确的解决办法
  6. Hadoop精华问答 | 关于Hadoop核心技术的精华问答
  7. mysql置信度支持度,支持度 置信度 提升度
  8. 关于python列表去重复后按照元列表序列输出
  9. 64位整数乘法(类快速幂)
  10. 地址解析协议(ARP)
  11. 分布式 | zabbix 监控 dble
  12. CSP内容安全策略基础版
  13. 手机照片误删怎么找回
  14. 使用Docker部署Spring-Boot-项目,带劲!
  15. 微信小程序座位预约,微信小程序实现订座位,餐厅座位预约小程序毕设作品
  16. 2017年苹果开发者账号申请——注册苹果账号
  17. 微信小程序之添加文章功能
  18. MAC Python环境配置
  19. mysql 存放byte_mysql 存储byte数组
  20. Glide加载不出图片

热门文章

  1. ubuntu挂载移动硬盘时提示Unable to mount
  2. skype在线代码 skype在线代码怎么弄?
  3. 易语言数字指令编程大全(发送信息代码数据集合)
  4. asp.net mvc 学习总结
  5. 马化腾的马氏建议:“小步快跑 快速迭代”
  6. elasticsearch学习一:了解 ES,版本之间的对应。安装elasticsearch,kibana,head插件、elasticsearch-ik分词器。
  7. 数据可视化--实验三:空间可视化
  8. linux脚本 加密失效,shell脚本加密(使用shc)
  9. 关闭 电脑 ctrl +alt +方向键 旋转屏幕快捷键
  10. Win10 Ctrl+Alt+方向键 屏幕显示翻转解决办法