• Air protocol应用实战


    前言

    https://github.com/Tuotaba/air_protocol

    air_protocol提供一套应用于嵌入式设备的通讯协议协议涉及协议完整性的验证,长短数据的灵活调整,以及数据过滤等。适合设备的数据传输、文件传输等。

    例1 收发数据

    1. #include "air_protocol.h"
    2. #include "fifo_buffer.h"
    3. #include
    4. #include
    5. #define MAX_BUFFER_LEN 256
    6. static uint8_t pUartData[MAX_BUFFER_LEN];
    7. static buffer_list_t UartBuf;
    8. static uint8_t air_buffer[MAX_BUFFER_LEN];
    9. void send_uart(uint8_t cmd,uint8_t *buf,uint16_t len)
    10. {
    11. air_result_t result;
    12. air_ret_t ret;
    13. ret = air_alloc_pack(cmd,buf,len,&result);
    14. if(ret == AIR_FAIL)
    15. return;
    16. printf("send:\n");
    17. air_show_log(result.pdata,result.len);
    18. printf("\n");
    19. buffer_append(&UartBuf,result.pdata,result.len);
    20. free(result.pdata);
    21. }
    22. void uart_data_parser(void)
    23. {
    24. air_result_t result;
    25. air_ret_t ret;
    26. air_header_t air_header;
    27. uint8_t *pdata;
    28. int i,len;
    29. air_header.tag = AIR_TAG;
    30. i = buffer_find(&UartBuf,(uint8_t *)&air_header.tag,sizeof(air_header.tag));
    31. if(i >= 0)
    32. {
    33. if(i>0)
    34. buffer_pop(&UartBuf,NULL,i);
    35. if(get_data_length(&UartBuf) > AIR_HEADER_LEN)
    36. {
    37. pdata = (uint8_t *)&air_header;
    38. for(i=0;i
    39. pdata[i] = buffer_get(&UartBuf,i);
    40. len = (AIR_HEADER_LEN+air_header.len+1);
    41. if(get_data_length(&UartBuf) >= len)
    42. {
    43. buffer_pop(&UartBuf,air_buffer,len);
    44. ret = air_data_parser(air_buffer,len,&result);
    45. if(ret == AIR_SUCCESS)
    46. {
    47. printf("recv:cmd = %02X,len =%d\n",result.cmd,result.len);
    48. air_show_log(result.pdata,result.len);
    49. printf("\n");
    50. }
    51. }
    52. }
    53. }
    54. }
    55. int main()
    56. {
    57. int i,len;
    58. uint8_t data[] = {0xAA ,0xAA ,0xAA ,0xAA ,0xAA ,0xAA ,0xAA ,0xAA ,0xAA ,0xAA ,0xAA ,0xAA ,0xAA ,0xAA ,0xAA};
    59. buffer_init(&UartBuf,pUartData,MAX_BUFFER_LEN);
    60. send_uart(0x0A,data,sizeof(data));
    61. uart_data_parser();
    62. return 0;
    63. }

    一般数据的收发,数据完整性验证,结果:

    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 运动数据解析

    1. #include "air_protocol.h"
    2. #include "fifo_buffer.h"
    3. #include
    4. #include
    5. #define MAX_BUFFER_LEN 256
    6. static uint8_t pUartData[MAX_BUFFER_LEN];
    7. static buffer_list_t UartBuf;
    8. static uint8_t air_buffer[MAX_BUFFER_LEN];
    9. typedef struct
    10. {
    11. uint32_t calories;
    12. uint32_t speed;
    13. uint32_t distance;
    14. uint32_t time;
    15. }_sport_data_t;
    16. #define CMD_SPORT_DATA 0x10
    17. void send_uart(uint8_t cmd,uint8_t *buf,uint16_t len)
    18. {
    19. air_result_t result;
    20. air_ret_t ret;
    21. ret = air_alloc_pack(cmd,buf,len,&result);
    22. if(ret == AIR_FAIL)
    23. return;
    24. buffer_append(&UartBuf,result.pdata,result.len);
    25. free(result.pdata);
    26. }
    27. static void command_handler(uint8_t cmd,uint8_t *buf,uint16_t len)
    28. {
    29. _sport_data_t *p_sport_data;
    30. switch(cmd)
    31. {
    32. case CMD_SPORT_DATA:
    33. p_sport_data = (_sport_data_t *)buf;
    34. printf("calories : %d\n",p_sport_data->calories);
    35. printf("speed : %d\n",p_sport_data->speed);
    36. printf("distance : %d\n",p_sport_data->distance);
    37. printf("time : %d\n",p_sport_data->time);
    38. break;
    39. default:break;
    40. }
    41. }
    42. void uart_data_parser(void)
    43. {
    44. air_result_t result;
    45. air_ret_t ret;
    46. air_header_t air_header;
    47. uint8_t *pdata;
    48. int i,len;
    49. air_header.tag = AIR_TAG;
    50. i = buffer_find(&UartBuf,(uint8_t *)&air_header.tag,sizeof(air_header.tag));
    51. if(i >= 0)
    52. {
    53. if(i>0)
    54. buffer_pop(&UartBuf,NULL,i);
    55. if(get_data_length(&UartBuf) > AIR_HEADER_LEN)
    56. {
    57. pdata = (uint8_t *)&air_header;
    58. for(i=0;i
    59. pdata[i] = buffer_get(&UartBuf,i);
    60. len = (AIR_HEADER_LEN+air_header.len+1);
    61. if(get_data_length(&UartBuf) >= len)
    62. {
    63. buffer_pop(&UartBuf,air_buffer,len);
    64. ret = air_data_parser(air_buffer,len,&result);
    65. if(ret == AIR_SUCCESS)
    66. {
    67. command_handler(result.cmd,result.pdata,result.len);
    68. }
    69. }
    70. }
    71. }
    72. }
    73. int main()
    74. {
    75. int i,len;
    76. _sport_data_t data = {322,23,1000,30};
    77. buffer_init(&UartBuf,pUartData,MAX_BUFFER_LEN);
    78. send_uart(CMD_SPORT_DATA,(uint8_t*)&data,sizeof(_sport_data_t));
    79. uart_data_parser();
    80. return 0;
    81. }

    收到对方发来的CMD_SPORT_DATA命令,附带_sport_data_t数据包,进行解析,解析出结果:

    calories : 322

    speed : 23

    distance : 1000

    time : 30

    例3 文件传输

    1. #include "air_protocol.h"
    2. #include "fifo_buffer.h"
    3. #include
    4. #include
    5. #include
    6. #include
    7. #define MAX_BUFFER_LEN 512
    8. static uint8_t pUartData[MAX_BUFFER_LEN];
    9. static buffer_list_t UartBuf;
    10. static uint8_t air_buffer[MAX_BUFFER_LEN];
    11. typedef struct
    12. {
    13. uint32_t addr;
    14. uint32_t len;
    15. uint8_t data[256];
    16. }_file_data_t;
    17. #define CMD_FILE_BEGIN 0x10
    18. #define CMD_FILE_DATA 0x11
    19. #define CMD_FILE_END 0x12
    20. void send_uart(uint8_t cmd,uint8_t *buf,uint16_t len)
    21. {
    22. air_result_t result;
    23. air_ret_t ret;
    24. ret = air_alloc_pack(cmd,buf,len,&result);
    25. if(ret == AIR_FAIL)
    26. return;
    27. buffer_append(&UartBuf,result.pdata,result.len);
    28. free(result.pdata);
    29. }
    30. static void command_handler(uint8_t cmd,uint8_t *buf,uint16_t len)
    31. {
    32. _file_data_t file_data;
    33. static uint32_t require_addr = 0;
    34. switch(cmd)
    35. {
    36. case CMD_FILE_BEGIN:
    37. require_addr = 0;
    38. break;
    39. case CMD_FILE_DATA:
    40. memcpy(&file_data,buf,len);
    41. printf("%08X :\n",file_data.addr);
    42. if(file_data.addr == require_addr){
    43. air_show_log(file_data.data,file_data.len);
    44. require_addr += file_data.len;
    45. }
    46. else{
    47. printf("please resend addr %08X\n",require_addr);
    48. }
    49. break;
    50. case CMD_FILE_END:
    51. printf("file is done\n");
    52. break;
    53. default:break;
    54. }
    55. }
    56. void uart_data_parser(void)
    57. {
    58. air_result_t result;
    59. air_ret_t ret;
    60. air_header_t air_header;
    61. uint8_t *pdata;
    62. int i,len;
    63. air_header.tag = AIR_TAG;
    64. do{
    65. i = buffer_find(&UartBuf,(uint8_t *)&air_header.tag,sizeof(air_header.tag));
    66. if(i >= 0)
    67. {
    68. if(i>0)
    69. buffer_pop(&UartBuf,NULL,i);
    70. if(get_data_length(&UartBuf) > AIR_HEADER_LEN)
    71. {
    72. pdata = (uint8_t *)&air_header;
    73. for(i=0;i
    74. pdata[i] = buffer_get(&UartBuf,i);
    75. len = (AIR_HEADER_LEN+air_header.len+1);
    76. if(get_data_length(&UartBuf) >= len)
    77. {
    78. buffer_pop(&UartBuf,air_buffer,len);
    79. ret = air_data_parser(air_buffer,len,&result);
    80. if(ret == AIR_SUCCESS)
    81. {
    82. command_handler(result.cmd,result.pdata,result.len);
    83. }
    84. continue;
    85. }
    86. }
    87. }
    88. break;
    89. }while(1);
    90. }
    91. int main()
    92. {
    93. int len;
    94. FILE *fp = NULL;
    95. _file_data_t file_data;
    96. buffer_init(&UartBuf,pUartData,MAX_BUFFER_LEN);
    97. file_data.addr = 0;
    98. fp = fopen("./test.bin","r");
    99. if(fp == NULL)
    100. {
    101. printf("not found test.bin\n");
    102. return 0;
    103. }
    104. send_uart(CMD_FILE_BEGIN,NULL,0);
    105. while(1){
    106. len = fread(file_data.data,1,256,fp);
    107. if(len <= 0)
    108. break;
    109. file_data.len = len;
    110. send_uart(CMD_FILE_DATA,(uint8_t*)&file_data,file_data.len+8);
    111. uart_data_parser();
    112. file_data.addr += len;
    113. }
    114. send_uart(CMD_FILE_END,NULL,0);
    115. uart_data_parser();
    116. fclose(fp);
    117. return 0;
    118. }

    将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