https://github.com/Tuotaba/air_protocol
air_protocol提供一套应用于嵌入式设备的通讯协议。协议涉及协议完整性的验证,长短数据的灵活调整,以及数据过滤等。适合设备的数据传输、文件传输等。
- #include "air_protocol.h"
- #include "fifo_buffer.h"
- #include
- #include
-
- #define MAX_BUFFER_LEN 256
- static uint8_t pUartData[MAX_BUFFER_LEN];
- static buffer_list_t UartBuf;
-
- static uint8_t air_buffer[MAX_BUFFER_LEN];
-
- void send_uart(uint8_t cmd,uint8_t *buf,uint16_t len)
- {
- air_result_t result;
- air_ret_t ret;
-
- ret = air_alloc_pack(cmd,buf,len,&result);
- if(ret == AIR_FAIL)
- return;
- printf("send:\n");
- air_show_log(result.pdata,result.len);
- printf("\n");
- buffer_append(&UartBuf,result.pdata,result.len);
- free(result.pdata);
- }
-
- void uart_data_parser(void)
- {
- air_result_t result;
- air_ret_t ret;
- air_header_t air_header;
- uint8_t *pdata;
- int i,len;
-
- air_header.tag = AIR_TAG;
- i = buffer_find(&UartBuf,(uint8_t *)&air_header.tag,sizeof(air_header.tag));
- if(i >= 0)
- {
- if(i>0)
- buffer_pop(&UartBuf,NULL,i);
- if(get_data_length(&UartBuf) > AIR_HEADER_LEN)
- {
- pdata = (uint8_t *)&air_header;
- for(i=0;i
- pdata[i] = buffer_get(&UartBuf,i);
- len = (AIR_HEADER_LEN+air_header.len+1);
- if(get_data_length(&UartBuf) >= len)
- {
- buffer_pop(&UartBuf,air_buffer,len);
- ret = air_data_parser(air_buffer,len,&result);
- if(ret == AIR_SUCCESS)
- {
- printf("recv:cmd = %02X,len =%d\n",result.cmd,result.len);
- air_show_log(result.pdata,result.len);
- printf("\n");
- }
- }
- }
- }
- }
-
- int main()
- {
- int i,len;
-
- uint8_t data[] = {0xAA ,0xAA ,0xAA ,0xAA ,0xAA ,0xAA ,0xAA ,0xAA ,0xAA ,0xAA ,0xAA ,0xAA ,0xAA ,0xAA ,0xAA};
-
- buffer_init(&UartBuf,pUartData,MAX_BUFFER_LEN);
-
- send_uart(0x0A,data,sizeof(data));
- uart_data_parser();
- return 0;
- }
一般数据的收发,数据完整性验证,结果:
send:
8D 7C 6B 5A 0A 00 0F 00 AA AA AA AA AA AA AA AA
AA AA AA AA AA AA AA DD
recv:cmd = 0A,len =15
AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA
例2 运动数据解析
- #include "air_protocol.h"
- #include "fifo_buffer.h"
- #include
- #include
-
- #define MAX_BUFFER_LEN 256
- static uint8_t pUartData[MAX_BUFFER_LEN];
- static buffer_list_t UartBuf;
-
- static uint8_t air_buffer[MAX_BUFFER_LEN];
-
- typedef struct
- {
- uint32_t calories;
- uint32_t speed;
- uint32_t distance;
- uint32_t time;
- }_sport_data_t;
-
- #define CMD_SPORT_DATA 0x10
-
- void send_uart(uint8_t cmd,uint8_t *buf,uint16_t len)
- {
- air_result_t result;
- air_ret_t ret;
-
- ret = air_alloc_pack(cmd,buf,len,&result);
- if(ret == AIR_FAIL)
- return;
- buffer_append(&UartBuf,result.pdata,result.len);
- free(result.pdata);
- }
-
- static void command_handler(uint8_t cmd,uint8_t *buf,uint16_t len)
- {
- _sport_data_t *p_sport_data;
-
- switch(cmd)
- {
- case CMD_SPORT_DATA:
- p_sport_data = (_sport_data_t *)buf;
- printf("calories : %d\n",p_sport_data->calories);
- printf("speed : %d\n",p_sport_data->speed);
- printf("distance : %d\n",p_sport_data->distance);
- printf("time : %d\n",p_sport_data->time);
- break;
- default:break;
- }
- }
-
- void uart_data_parser(void)
- {
- air_result_t result;
- air_ret_t ret;
- air_header_t air_header;
- uint8_t *pdata;
- int i,len;
-
- air_header.tag = AIR_TAG;
- i = buffer_find(&UartBuf,(uint8_t *)&air_header.tag,sizeof(air_header.tag));
- if(i >= 0)
- {
- if(i>0)
- buffer_pop(&UartBuf,NULL,i);
- if(get_data_length(&UartBuf) > AIR_HEADER_LEN)
- {
- pdata = (uint8_t *)&air_header;
- for(i=0;i
- pdata[i] = buffer_get(&UartBuf,i);
- len = (AIR_HEADER_LEN+air_header.len+1);
- if(get_data_length(&UartBuf) >= len)
- {
- buffer_pop(&UartBuf,air_buffer,len);
- ret = air_data_parser(air_buffer,len,&result);
- if(ret == AIR_SUCCESS)
- {
- command_handler(result.cmd,result.pdata,result.len);
- }
- }
- }
- }
- }
-
- int main()
- {
- int i,len;
-
- _sport_data_t data = {322,23,1000,30};
-
- buffer_init(&UartBuf,pUartData,MAX_BUFFER_LEN);
-
- send_uart(CMD_SPORT_DATA,(uint8_t*)&data,sizeof(_sport_data_t));
- uart_data_parser();
- return 0;
- }
收到对方发来的CMD_SPORT_DATA命令,附带_sport_data_t数据包,进行解析,解析出结果:
calories : 322
speed : 23
distance : 1000
time : 30
例3 文件传输
- #include "air_protocol.h"
- #include "fifo_buffer.h"
- #include
- #include
- #include
- #include
-
- #define MAX_BUFFER_LEN 512
- static uint8_t pUartData[MAX_BUFFER_LEN];
- static buffer_list_t UartBuf;
-
- static uint8_t air_buffer[MAX_BUFFER_LEN];
-
- typedef struct
- {
- uint32_t addr;
- uint32_t len;
- uint8_t data[256];
- }_file_data_t;
-
- #define CMD_FILE_BEGIN 0x10
- #define CMD_FILE_DATA 0x11
- #define CMD_FILE_END 0x12
-
- void send_uart(uint8_t cmd,uint8_t *buf,uint16_t len)
- {
- air_result_t result;
- air_ret_t ret;
-
- ret = air_alloc_pack(cmd,buf,len,&result);
- if(ret == AIR_FAIL)
- return;
- buffer_append(&UartBuf,result.pdata,result.len);
- free(result.pdata);
- }
-
- static void command_handler(uint8_t cmd,uint8_t *buf,uint16_t len)
- {
- _file_data_t file_data;
- static uint32_t require_addr = 0;
-
- switch(cmd)
- {
- case CMD_FILE_BEGIN:
- require_addr = 0;
- break;
- case CMD_FILE_DATA:
- memcpy(&file_data,buf,len);
- printf("%08X :\n",file_data.addr);
- if(file_data.addr == require_addr){
- air_show_log(file_data.data,file_data.len);
- require_addr += file_data.len;
- }
- else{
- printf("please resend addr %08X\n",require_addr);
- }
- break;
- case CMD_FILE_END:
- printf("file is done\n");
- break;
- default:break;
- }
- }
-
- void uart_data_parser(void)
- {
- air_result_t result;
- air_ret_t ret;
- air_header_t air_header;
- uint8_t *pdata;
- int i,len;
-
- air_header.tag = AIR_TAG;
- do{
- i = buffer_find(&UartBuf,(uint8_t *)&air_header.tag,sizeof(air_header.tag));
- if(i >= 0)
- {
- if(i>0)
- buffer_pop(&UartBuf,NULL,i);
- if(get_data_length(&UartBuf) > AIR_HEADER_LEN)
- {
- pdata = (uint8_t *)&air_header;
- for(i=0;i
- pdata[i] = buffer_get(&UartBuf,i);
- len = (AIR_HEADER_LEN+air_header.len+1);
- if(get_data_length(&UartBuf) >= len)
- {
- buffer_pop(&UartBuf,air_buffer,len);
- ret = air_data_parser(air_buffer,len,&result);
- if(ret == AIR_SUCCESS)
- {
- command_handler(result.cmd,result.pdata,result.len);
- }
- continue;
- }
- }
- }
- break;
- }while(1);
- }
-
- int main()
- {
- int len;
- FILE *fp = NULL;
-
- _file_data_t file_data;
-
- buffer_init(&UartBuf,pUartData,MAX_BUFFER_LEN);
-
- file_data.addr = 0;
-
- fp = fopen("./test.bin","r");
- if(fp == NULL)
- {
- printf("not found test.bin\n");
- return 0;
- }
- send_uart(CMD_FILE_BEGIN,NULL,0);
- while(1){
- len = fread(file_data.data,1,256,fp);
- if(len <= 0)
- break;
- file_data.len = len;
- send_uart(CMD_FILE_DATA,(uint8_t*)&file_data,file_data.len+8);
- uart_data_parser();
- file_data.addr += len;
- }
- send_uart(CMD_FILE_END,NULL,0);
- uart_data_parser();
- fclose(fp);
- return 0;
- }
将test.bin读出,并进行传输,结果:
00000000 :
61 61 61 61 61 61 61 61 0A
file is done
如果文件足够大,会打印出更多的信息。
因为协议有对每帧数据进行完整性验证,所以不怕数据会出错,也不需要收全文件再进行检验。
-
相关阅读:
Linux入门-网络基础|网络协议|OSI七层模型|TCP/IP五层模型|网络传输基本流程
Java集合框架面试指南
elasticsearch实现聚合后两个字段相除相加相减相乘运算
CCF走进高校
SaaS CRM系统的优势,与本地部署相比哪个更方便?
解决因d3dx9_30.dll丢失程序无法运行,电脑缺失d3dx9_30.dll报错解决方案
LeetCode热题100——贪心算法
【CSDN】如何开启CSDN文章下的显示微信公众号、微信号、官方网站、QQ号、QQ群 ?
wpf资源Resources探究性学习(一)
4、React组件三大核心属性
-
原文地址:https://blog.csdn.net/skdev/article/details/126609367