You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

208 lines
5.0 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. #include "atcmd.h"
  2. #include "zport.h"
  3. #include <lwip/sockets.h>
  4. #include "config.h"
  5. #define at_processer_rx_buf_size 128
  6. #define at_processer_tx_buf_size 128
  7. // 接收到了多少数据
  8. volatile uint16_t s_at_cmd_uart_rx_off = 0;
  9. // 当前是否正在处理接收到的数据
  10. volatile bool s_at_cmd_uart_rx_buf_is_processing = false;
  11. static uint8_t at_rx_buf[at_processer_rx_buf_size];
  12. // static uint8_t at_tx_buf[at_processer_tx_buf_size];
  13. /* AT指令表 */
  14. const AT_cmd_func at_cmd_func[] = {
  15. {AT_CMD_TEST, "AT", at_cmd_test},
  16. {AT_CMD_IP, "AT+IP=", at_cmd_ip},
  17. {AT_CMD_GW, "AT+GW=", NULL},
  18. {AT_CMD_NETMASK, "AT+NETMASK=", NULL},
  19. {AT_CMD_NETMODULE, "AT+NETMODULE=", NULL},
  20. {AT_END, NULL, NULL}};
  21. unsigned int mstrlen(const char *s)
  22. {
  23. const char *ss = s;
  24. while (*ss)
  25. ss++;
  26. return ss - s;
  27. }
  28. int mstrncmp(const char *s1, const char *s2, int n)
  29. {
  30. const unsigned char *c1 = (const unsigned char *)s1;
  31. const unsigned char *c2 = (const unsigned char *)s2;
  32. unsigned char ch;
  33. int d = 0;
  34. while (n--)
  35. {
  36. d = (int)(ch = *c1++) - (int)*c2++;
  37. if (d || !ch)
  38. break;
  39. }
  40. return d;
  41. }
  42. /* 指令执行函数 */
  43. AT_STATUS at_cmd_test(unsigned char *p, unsigned char len)
  44. {
  45. printf("AT+OK\r\n");
  46. return AT_SUCCESS;
  47. }
  48. AT_STATUS at_cmd_ip(unsigned char *p, unsigned char len)
  49. {
  50. ip4_addr_t int_addr;
  51. char ip_address[16];
  52. if (*p == '?')
  53. {
  54. printf("config ip address:%s\r\n", inet_ntoa(config_get()->ip));
  55. }
  56. else
  57. {
  58. if (len >= sizeof(ip_address))
  59. {
  60. /* 长度判断 */
  61. printf("AT+ERR\r\n");
  62. return AT_ERR;
  63. }
  64. /* 拷贝len有效字符长度的字符串到ip_address中 */
  65. strncpy(ip_address, (const char *)p, len);
  66. ip_address[len] = 0; /* 这个必须要加,否则转换会出错 */
  67. inet_aton(ip_address, &int_addr);
  68. config_get()->ip = int_addr.addr;
  69. config_dump_config();
  70. printf("AT+OK\r\n");
  71. }
  72. return AT_SUCCESS;
  73. }
  74. /* 查找指令表中对应的指令 */
  75. unsigned char AT_cmd_search(unsigned char *p, unsigned char len)
  76. {
  77. unsigned char ret = 0;
  78. // unsigned char *pstr;
  79. unsigned char i, n;
  80. for (i = 1; at_cmd_func[i].cmd != AT_END; i++)
  81. {
  82. n = mstrlen((const char *)at_cmd_func[i].str);
  83. if (!mstrncmp((const char *)p, (const char *)at_cmd_func[i].str, n))
  84. {
  85. ret = i;
  86. break;
  87. }
  88. }
  89. return ret;
  90. }
  91. /* AT指令解析 */
  92. AT_STATUS at_cmd_parse(unsigned char *p, unsigned char len)
  93. {
  94. AT_STATUS ret = AT_SUCCESS;
  95. unsigned char index = 0;
  96. if (len < 4)
  97. return AT_ERR; /* 不符合指令最小长度 */
  98. if ((p[0] == 'A') && (p[1] == 'T') && (p[len - 2] == 0x0D) && (p[len - 1] == 0x0A))
  99. {
  100. if (len == 4)
  101. { /* 测试指令 */
  102. if (at_cmd_func[AT_CMD_TEST].cb != NULL)
  103. at_cmd_func[AT_CMD_TEST].cb(NULL, 0); /* 执行测试指令 */
  104. }
  105. else if (p[2] == '+')
  106. { /* 执行指令解析 */
  107. index = AT_cmd_search(p, len); /* 查找匹配的执行指令,0-已匹配,!0-未匹配 */
  108. if (index)
  109. {
  110. if (at_cmd_func[index].cb != NULL)
  111. { /* 判断指令对应执行函数是否存在 */
  112. unsigned char n;
  113. n = mstrlen((const char *)at_cmd_func[index].str);
  114. ret = at_cmd_func[index].cb(p + n, len - n - 2); /* 执行对应的指令函数, p+n:将指令参数传输执行函数,len-n-2:指令参数有效长度 */
  115. }
  116. else
  117. ret = AT_ERR_FUN_UNUSED; /* 没有可执行函数 */
  118. }
  119. else
  120. {
  121. ret = AT_ERR_UNINVAIL; /* 未找到匹配的指令 */
  122. }
  123. }
  124. }
  125. else
  126. { /* 格式不匹配 */
  127. return AT_ERR;
  128. }
  129. return ret;
  130. }
  131. void at_cmd_processer_push_data(uint8_t rxdata)
  132. {
  133. if (!s_at_cmd_uart_rx_buf_is_processing)
  134. {
  135. if (s_at_cmd_uart_rx_off < at_processer_rx_buf_size)
  136. {
  137. at_rx_buf[s_at_cmd_uart_rx_off] = rxdata;
  138. s_at_cmd_uart_rx_off++;
  139. }
  140. }
  141. }
  142. void at_cmd_processer_try_process_data(void)
  143. {
  144. /**
  145. * @brief
  146. * modbus协议3.5
  147. */
  148. if (s_at_cmd_uart_rx_off != 0)
  149. {
  150. uint16_t modbus_uart_rx_off_before = s_at_cmd_uart_rx_off;
  151. HAL_Delay(1);
  152. sys_critical_enter();
  153. if (s_at_cmd_uart_rx_off == modbus_uart_rx_off_before)
  154. {
  155. s_at_cmd_uart_rx_buf_is_processing = true;
  156. }
  157. sys_critical_exit();
  158. if (s_at_cmd_uart_rx_buf_is_processing)
  159. {
  160. if (at_cmd_parse(at_rx_buf, s_at_cmd_uart_rx_off) != AT_SUCCESS)
  161. {
  162. printf("at cmd parse error\r\n");
  163. }
  164. sys_critical_enter();
  165. s_at_cmd_uart_rx_off = 0;
  166. s_at_cmd_uart_rx_buf_is_processing = false;
  167. sys_critical_exit();
  168. }
  169. }
  170. }