痛苦!数据流过大?数据转换各种组包拆包?指针及数组你试过没!
今天的是干货,是真的干。作为一个从业4年,工龄6年的嵌入式开发程序员,在做通讯设备领域时最痛苦的事莫过于数据流过大问题,以及数据转换时各种组包拆包等问题,特别是在控制器内存资源有限时。这种问题更加突出。
以太网数据收发时以太网的协议栈占用内存约20Kbyte,单个SOCKET传输数据时最少预留了532byte字节的缓存空间,当取出网络下传的数据时,需要拆掉网络传输头并在末尾增加CRC,串口上行数据时,需要增加网络传输数据头以及去掉末尾CRC值,如果此时碰到惯用for循环copy数据或者使用memcpy函数进行数据组包的大佬,内存空间基本就是捉襟见肘。
解决以上问题的办法之一就是使用指针配合数组进行组包与拆包,如下图;
预留包头46字节 | 数据部分536字节 | 末尾预留10字节 |
网络端向串口发送:声明数组时申明比实际数据所需空间更大的数组unsigned char Buff[592],以及一个指针unsigned char *datapoint;将datapoint指向Buff[46]的位置,读入数据,将数据从指针datapoint指向的位置开始存入数组,同时使用另外的变量unsigned int length存储当次读入的数据的长度,进行数据拆包操作时(去包头6字节),直接将指针datapoint指向Buff[52]的位置,随后将计算所得CRC(2byte)值从Buff[46 + length]位置存入数组,并得出最终需要传输的长度length+2,串口发送数据只需要输入起始地址datapoint,长度length,将数据存入串口发送环形队列即可完成发送。
代码如下
unsigned char Buff[592];
unsigned char *datapoint;
unsigned int length;
datapoint = & Buff[46];//指针指向数组中间
net_dataread(datapoint,& length);//读取数据,获得数据长度
CRC(&Buff[46+length],datapoint,& length);//获取校验值并存入数组
Uart_send(datapoint,length+2);
串口向网络发送时,数据从环形队列读出,需要加上TCP modbus协议的包头部分(6byte),去掉CRC校验,同样声明数组以及指针、长度变量,将datapoint指向Buff[46]的位置,读入数据,将数据从指针datapoint指向的位置开始存入数组;将指针指向当前指向地址的前6个地址位置存入6字节,然后按照新的datapoint位置,长度length+4将数据从网络发出;
代码如下
unsigned char Buff[592];
unsigned char *datapoint;
unsigned int length;
datapoint = & Buff[46];//指针指向数组中间
uart_read(datapoint,& length);//读取数据,获得数据长度
datapoint = datapoint-6;
memcpy(datapoint,包头暂存数组首地址,6);
Uart_send(datapoint,length+4);
以上实例简单说明了利用指针组包的简单应用,但是在实际应用中可能由于设备需要使用多种协议,组包方式不同,例如包头之前加入注册包等,数据实际读取完成之后不是直接操作而是直接传入子函数,进行组包与拆包,此时仅需要传入datapoint与长度,进子函数,由于datapoint指向的数组前后均有预留空间,子函数内依然可以使用指针,且在Buff[]数组的范围内,指针可以前后自由移动,在不需要进行大量数据拷贝的前提下完成数组的拆组包过程,同时也避免了反复拷贝数据对空间的浪费。
以上就是指针的简单应用之一,指针除了对数组,还可以对函数操作,结合结构体,基本上可以在C语言中实现类似C++中类功能。
今天的分享就到这里啦,EBYTE每一天都致力于更好的助力物联化、智能化、自动化的发展,提升资源利用率,更多产品及相关资料,感兴趣的小伙伴可以登录我们的太阳集团tcy8722官网进行了解,也可以直接拨打400电话咨询技术专员!
7 X 24 销售服务热线
4000-330-990深圳办事处柯经理:18218726658 杭州办事处戴经理:17512568697
常州办事处崔经理:15906110783 南京办事处葛经理:17626012283
业务邮箱:support@cdhanzaichips.com
全国销售投诉电话:19934352316
地址:四川省成都市高新西区西区大道199号B5栋(前台座机:028-61543675)
©© 成都太阳集团tcy8722电子科技有限公司【版权所有】 蜀ICP备27697263号-3