Callback.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758
  1. /* USER CODE BEGIN Header */
  2. /**
  3. ******************************************************************************
  4. * @file : UARTCallback.c
  5. * @brief :
  6. ******************************************************************************
  7. * @attention
  8. *
  9. * Copyright (c) 2025 STMicroelectronics.
  10. * All rights reserved.
  11. *
  12. * This software is licensed under terms that can be found in the LICENSE file
  13. * in the root directory of this software component.
  14. * If no LICENSE file comes with this software, it is provided AS-IS.
  15. *
  16. ******************************************************************************
  17. */
  18. /* USER CODE END Header */
  19. /* Private includes ----------------------------------------------------------*/
  20. /* USER CODE BEGIN Includes */
  21. #include "FreeRTOS.h"
  22. #include "cmsis_os.h"
  23. #include "task.h"
  24. #include "queue.h"
  25. #include "main.h"
  26. #include "Callback.h"
  27. #include "Modbussimple.h"
  28. #include "FLASH.h"
  29. #include "DRV8837D.h"
  30. #include "kv_flash.h"
  31. /* USER CODE END Includes */
  32. /* Exported types ------------------------------------------------------------*/
  33. /* USER CODE BEGIN ET */
  34. extern DMA_HandleTypeDef hdma_usart1_rx;
  35. extern DMA_HandleTypeDef hdma_usart2_rx;
  36. extern osThreadId_t ReadTaskHandle;
  37. extern osMessageQueueId_t uart485rxqueueHandle;
  38. extern osMessageQueueId_t consolemsgqueueHandle;
  39. extern uint8_t dataReceive485[BUFFER_SIZE485]; // 485
  40. extern uint8_t dataReceivep[BUFFER_SIZEP]; // 调试
  41. extern uint32_t uartIRQ_rx_len; // 485串口接收数据长度
  42. extern uint32_t uartprint_rx_len ;
  43. /*
  44. * @ 多功能API阀参数信息
  45. */
  46. uint16_t Valve_status = 0; // 阀状态0000关0001开
  47. uint32_t uint_liquidHeight = 0; // 液位高度
  48. uint32_t uint_oil_percent = 0; // 油水百分比
  49. uint32_t uint_filtered_cap = 0; // 滤波之后的电容值
  50. /* USER CODE END ET */
  51. /* Exported functions prototypes ---------------------------------------------*/
  52. void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) // UART 接收完成回调
  53. {
  54. if (huart->Instance == USART1)
  55. HAL_GPIO_WritePin(GPIOA, RS485_RD_Pin, GPIO_PIN_RESET);
  56. }
  57. void UART1_IdleCallback(void)
  58. {
  59. HAL_UART_DMAStop(&huart1); // 停止 DMA,获取剩余数据长度
  60. uint32_t remain = __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
  61. uartIRQ_rx_len = BUFFER_SIZE485 - remain;
  62. if (uartIRQ_rx_len == 0 || uartIRQ_rx_len > BUFFER_SIZE485) {
  63. // 异常长度,忽略
  64. Restart_UART1_DMA();
  65. return;
  66. }
  67. Uart485Rx_msg uart485_msg;
  68. memset(&uart485_msg, 0, sizeof(uart485_msg));
  69. uart485_msg.len = uartIRQ_rx_len;
  70. memcpy(uart485_msg.data, dataReceive485, uartIRQ_rx_len); // 只拷贝有效长度
  71. BaseType_t xHigherPriorityTaskWoken = pdFALSE;
  72. if (xQueueSendToBackFromISR(uart485rxqueueHandle, &uart485_msg, &xHigherPriorityTaskWoken) != pdPASS)
  73. {
  74. // 队列满,移出一个旧数据再塞入
  75. Uart485Rx_msg discard_msg;
  76. xQueueReceiveFromISR(uart485rxqueueHandle, &discard_msg, &xHigherPriorityTaskWoken);
  77. xQueueSendToBackFromISR(uart485rxqueueHandle, &uart485_msg, &xHigherPriorityTaskWoken);
  78. }
  79. Restart_UART1_DMA(); // 重启 DMA 接收
  80. }
  81. void UART2_IdleCallback(void)
  82. {
  83. HAL_UART_DMAStop(&huart2);
  84. // 计算接收长度
  85. uint32_t remain = __HAL_DMA_GET_COUNTER(&hdma_usart2_rx);
  86. uartprint_rx_len = BUFFER_SIZEP - remain;
  87. if (uartprint_rx_len < 4 || uartprint_rx_len > BUFFER_SIZEP)
  88. {
  89. Restart_UART2_DMA(); // 长度异常直接重启 DMA
  90. return;
  91. }
  92. Console_msg console_msg;
  93. memset(&console_msg, 0, sizeof(console_msg)); //
  94. BaseType_t xHigherPriorityTaskWoken = pdFALSE;
  95. console_msg.len = uartprint_rx_len;
  96. memcpy(console_msg.data, dataReceivep, uartprint_rx_len); // 拷贝接收数据
  97. memset(dataReceivep, 0, sizeof(dataReceivep));
  98. if (xQueueSendToBackFromISR(consolemsgqueueHandle, &console_msg, &xHigherPriorityTaskWoken) != pdPASS) // FreeRTOS 原生 API
  99. {
  100. Console_msg discard_msg;
  101. xQueueReceiveFromISR(consolemsgqueueHandle, &discard_msg, &xHigherPriorityTaskWoken); // 丢弃队首
  102. xQueueSendToBackFromISR(consolemsgqueueHandle, &console_msg, &xHigherPriorityTaskWoken);
  103. }
  104. }
  105. void Process_Consolecallback(void) // 处理控制台命令
  106. {
  107. Console_msg conmsg;
  108. if (osMessageQueueGet(consolemsgqueueHandle, &conmsg, NULL, 0) == osOK) { // CMSIS API
  109. if (conmsg.len > 0 && conmsg.data[0] != '\0'){ // 过滤空命令
  110. parse_AT_command(conmsg.data);
  111. }
  112. Restart_UART2_DMA();
  113. }
  114. }
  115. void Process_Uart485callback(void)
  116. {
  117. Uart485Rx_msg rxMsg;
  118. if (osMessageQueueGet(uart485rxqueueHandle, &rxMsg, NULL, 0) == osOK) {
  119. DEBUG_PRINTF("485rxBuffer: ");
  120. for (int i = 0; i < rxMsg.len; i++) {
  121. DEBUG_PRINTF("%02X ", rxMsg.data[i]);
  122. }
  123. DEBUG_PRINTF("\n");
  124. // if(Systemmode != releasemode)
  125. // {
  126. // taskprint(rxMsg.data, rxMsg.len);
  127. // }
  128. if (is_modbus_03_response(rxMsg.data)) { // 处理03读指令
  129. process_modbus_03(rxMsg.data);
  130. return;
  131. }
  132. if (is_modbus_06_response(rxMsg.data)) { // 处理06写单指令
  133. process_modbus_06(rxMsg.data);
  134. return;
  135. }
  136. if (is_modbus_10_response(rxMsg.data)) { // 处理10写多指令
  137. process_modbus_10(rxMsg.data);
  138. return;
  139. }
  140. if (is_modbus_42_response(rxMsg.data)) { // 处理42升级指令
  141. process_modbus_42(rxMsg.data);
  142. return;
  143. }
  144. }
  145. }
  146. bool is_modbus_03_response(uint8_t *data)
  147. {
  148. if (!((data[0] == (JsRoot.addr & 0xFF) || data[0] == 0xFF) && data[1] == 0x03))
  149. return false; // 不匹配,直接返回 false
  150. uint16_t crc_received = (data[7] << 8) | data[6];
  151. uint16_t crc_calculated = modbus_crc16(data, 6);
  152. return memcmp(&crc_received, &crc_calculated, sizeof(crc_calculated)) == 0;
  153. }
  154. void process_modbus_03(uint8_t *data)
  155. {
  156. memset(g_modbusbuffer, 0, sizeof(g_modbusbuffer)); // 清零缓存,防止旧数据影响
  157. uint8_t *tx_buf = (uint8_t *)g_modbusbuffer; // 强制转成字节指针
  158. uint8_t func_code = data[1]; // 功能码
  159. uint16_t reg_addr = (data[2] <<8) | data[3]; // 寄存器地址
  160. uint8_t reg_count = data[5]; // 寄存器数量
  161. // 最多读取125个寄存器(Modbus限制)
  162. if (reg_count == 0 || reg_count > 125) return;
  163. // 填充应答头部
  164. tx_buf[0] = JsRoot.addr & 0xFF;
  165. tx_buf[1] = func_code;
  166. tx_buf[2] = reg_count * 2;
  167. uint16_t data_len = 0;
  168. bool found = read_modbus_registers(reg_addr, reg_count, &tx_buf[3], &data_len);
  169. if (!found) return; // 地址非法
  170. // 计算CRC
  171. uint16_t crc = modbus_crc16(tx_buf, 3 + data_len);
  172. tx_buf[3 + data_len] = crc & 0xFF;
  173. tx_buf[4 + data_len] = (crc >> 8) & 0xFF;
  174. // 发送帧长度
  175. uint16_t total_len = 5 + data_len;
  176. uart485send(tx_buf, total_len);
  177. }
  178. bool is_modbus_06_response(uint8_t *data)
  179. {
  180. if (!((data[0] == (JsRoot.addr & 0xFF) || data[0] == 0xFF)&& data[1] == 0x06))
  181. return false; // 不匹配,直接返回 false
  182. uint16_t crc_received = (data[7] << 8) | data[6];
  183. uint16_t crc_calculated = modbus_crc16(data, 6);
  184. return memcmp(&crc_received, &crc_calculated, sizeof(crc_calculated)) == 0;
  185. }
  186. void process_modbus_06(uint8_t *data) {
  187. memset(g_modbusbuffer, 0, sizeof(g_modbusbuffer));
  188. uint8_t* tx_buf = (uint8_t *)g_modbusbuffer;
  189. uint8_t func_code = data[1];
  190. uint16_t reg_addr = (data[2] << 8) | data[3];
  191. uint16_t reg_data = (data[4] << 8) | data[5];
  192. bool found = false;
  193. for (size_t i = 0; i < REGISTER_MAP_SIZE; ++i) {
  194. if (WriteReg_map[i].address == reg_addr) {
  195. found = true;
  196. if (WriteReg_map[i].handler(reg_data)) {
  197. break;
  198. } else {
  199. return;
  200. }
  201. }
  202. }
  203. if (!found) {
  204. return; // 地址无效,不做任何处理
  205. }
  206. // 构造应答
  207. uint16_t len = 0;
  208. tx_buf[len++] = JsRoot.addr;
  209. tx_buf[len++] = func_code;
  210. tx_buf[len++] = (reg_addr >> 8) & 0xFF;
  211. tx_buf[len++] = reg_addr & 0xFF;
  212. tx_buf[len++] = (reg_data >> 8) & 0xFF;
  213. tx_buf[len++] = reg_data & 0xFF;
  214. uint16_t crc = modbus_crc16(tx_buf, len);
  215. tx_buf[len++] = crc & 0xFF;
  216. tx_buf[len++] = (crc >> 8) & 0xFF;
  217. uart485send(tx_buf, len);
  218. }
  219. bool is_modbus_10_response(uint8_t *data)
  220. {
  221. if (!((data[0] == (JsRoot.addr & 0xFF) || data[0] == 0xFF)&& data[1] == 0x10))
  222. return false; // 不匹配,直接返回 false
  223. uint16_t crc_received = (data[uartIRQ_rx_len-1] << 8) | data[uartIRQ_rx_len - 2];
  224. uint16_t crc_calculated = modbus_crc16(data, uartIRQ_rx_len - 2);
  225. if (crc_received != crc_calculated)
  226. {
  227. return false; // 返回false,不执行后续处理
  228. }
  229. return true; // CRC正确
  230. }
  231. void process_modbus_10(uint8_t *data)
  232. {
  233. memset(g_modbusbuffer, 0, sizeof(g_modbusbuffer));
  234. uint8_t *tx_buf = (uint8_t *)g_modbusbuffer;
  235. uint8_t func_code = data[1];
  236. uint16_t reg_addr = (data[2] << 8) | data[3];
  237. uint16_t reg_count = (data[4] << 8) | data[5];
  238. // uint16_t byte_count = data[6];
  239. // 数据段转成 uint16_t 数组
  240. uint16_t values[reg_count];
  241. for (uint16_t i = 0; i < reg_count; i++) {
  242. values[i] = (data[7 + i * 2] << 8) | data[8 + i * 2];
  243. }
  244. bool found = false;
  245. for (size_t i = 0; i < MULTI_REGISTER_MAP_SIZE; i++) {
  246. if (WriteMultiReg_map[i].start_address == reg_addr &&
  247. WriteMultiReg_map[i].reg_count == reg_count)
  248. {
  249. found = true;
  250. if (!WriteMultiReg_map[i].handler(values, WriteMultiReg_map[i].arg)) {
  251. return; // 处理失败,不应答
  252. }
  253. break;
  254. }
  255. }
  256. if (!found) {
  257. return;
  258. }
  259. // 构造应答帧
  260. uint16_t len = 0;
  261. tx_buf[len++] = JsRoot.addr;
  262. tx_buf[len++] = func_code;
  263. tx_buf[len++] = (reg_addr >> 8) & 0xFF;
  264. tx_buf[len++] = reg_addr & 0xFF;
  265. tx_buf[len++] = (reg_count >> 8) & 0xFF;
  266. tx_buf[len++] = reg_count & 0xFF;
  267. uint16_t crc = modbus_crc16(tx_buf, len);
  268. tx_buf[len++] = crc & 0xFF;
  269. tx_buf[len++] = (crc >> 8) & 0xFF;
  270. uart485send(tx_buf, len);
  271. }
  272. bool is_modbus_42_response(uint8_t *data)
  273. {
  274. // 检查前个字节是否符合要求
  275. if (!((data[0] == (JsRoot.addr & 0xFF) && data[0] == 0xFF)&&
  276. data[1] == 0x42 && data[2] == 0xAA && data[3] == 0xBB))
  277. return false; // 不匹配,直接返回 false
  278. uint16_t crc_received = (data[uartIRQ_rx_len-1] << 8) | data[uartIRQ_rx_len - 2];
  279. uint16_t crc_calculated = modbus_crc16(data, uartIRQ_rx_len - 2);
  280. if (crc_received != crc_calculated)
  281. {
  282. return false; // 返回false,不执行后续处理
  283. }
  284. return true; // CRC正确
  285. }
  286. void process_modbus_42(uint8_t *data)
  287. {
  288. memset(g_modbusbuffer, 0, sizeof(g_modbusbuffer)); // 清零缓存,防止旧数据影响
  289. uint16_t iapDataCommandCode = (data[4] <<8) |data[5]; // IAP数据的命令码
  290. switch(iapDataCommandCode)
  291. {
  292. case 0x4000: // 升级程序起始帧
  293. handle_upgrade_start_frame(data);
  294. break;
  295. case 0x4001: // 升级程序数据帧
  296. handle_upgrade_data_frame(data);
  297. break;
  298. case 0x4002: // 升级程序结束帧
  299. handle_upgrade_end_frame();
  300. break;
  301. default:
  302. send_upgrade_end_response(0x42, 0xAABB, 0x07, 0x0000); // 命令码错误
  303. break;
  304. }
  305. }
  306. bool is_modbus_errorfunc_response(uint8_t *data)
  307. {
  308. // 检查从机地址是否符合要求(等于 JsRoot.addr 或 0xFF)
  309. bool is_valid_addr = (data[0] == (JsRoot.addr & 0xFF)) || (data[0] == 0xFF);
  310. // 检查功能码是否不在允许的范围内(0x03, 0x06, 0x10, 0x42)
  311. bool is_invalid_func = (data[1] != 0x03) &&
  312. (data[1] != 0x06) &&
  313. (data[1] != 0x10) &&
  314. (data[1] != 0x42);
  315. if (is_valid_addr && is_invalid_func)
  316. {
  317. uint16_t crc_received = (data[7] << 8) | data[6];
  318. uint16_t crc_calculated = modbus_crc16(data, 6);
  319. return (memcmp(&crc_received, &crc_calculated, sizeof(crc_received)) == 0);
  320. }
  321. return false; // 不匹配,直接返回 false
  322. }
  323. void process_modbus_errorfunc(uint8_t *data)
  324. {
  325. memset(g_modbusbuffer, 0, sizeof(g_modbusbuffer)); // 清零缓存,防止旧数据影响
  326. uint8_t *tx_buf = (uint8_t *)g_modbusbuffer; // 强制转成字节指针
  327. uint8_t func_code = data[1]; // 功能码
  328. uint8_t total_len = 0;
  329. total_len = modbus_error_response(JsRoot.addr & 0xFF, func_code, 0x01, tx_buf); // 功能码错误
  330. uart485send(tx_buf, total_len);
  331. }
  332. bool is_modbus_error_regaddr_response(uint8_t *data)
  333. {
  334. // 检查从机地址是否符合要求(等于 JsRoot.addr 或 0xFF)
  335. bool is_valid_addr = (data[0] == (JsRoot.addr & 0xFF)) || (data[0] == 0xFF);
  336. // 检查功能码是否不在允许的范围内(0x03, 0x06, 0x10, 0x42)
  337. bool is_valid_func = (data[1] == 0x03) ||
  338. (data[1] == 0x06) ||
  339. (data[1] == 0x10) ||
  340. (data[1] == 0x42);
  341. uint16_t reg_addr = (data[2] <<8) | data[3]; // 寄存器地址
  342. // 检查寄存器地址是否不在允许的范围内(0x0000 到 0x001D 之间,0xAABB)
  343. bool is_invalid_regaddr = (reg_addr > 0x0021) && (reg_addr != 0xAABB);
  344. if (is_valid_addr && is_valid_func && is_invalid_regaddr)
  345. {
  346. uint16_t crc_received = (data[7] << 8) | data[6];
  347. uint16_t crc_calculated = modbus_crc16(data, 6);
  348. return (memcmp(&crc_received, &crc_calculated, sizeof(crc_received)) == 0);
  349. }
  350. return false; // 不匹配,直接返回 false
  351. }
  352. void process_modbus_error_regaddr(uint8_t *data)
  353. {
  354. memset(g_modbusbuffer, 0, sizeof(g_modbusbuffer)); // 清零缓存,防止旧数据影响
  355. uint8_t *tx_buf = (uint8_t *)g_modbusbuffer; // 强制转成字节指针
  356. uint8_t func_code = data[1]; // 功能码
  357. uint8_t total_len = 0;
  358. total_len = modbus_error_response(JsRoot.addr & 0xFF, func_code, 0x02, tx_buf); // 功能码错误
  359. uart485send(tx_buf, total_len);
  360. }
  361. void process_modbus_error_data(uint8_t *data)
  362. {
  363. memset(g_modbusbuffer, 0, sizeof(g_modbusbuffer)); // 清零缓存,防止旧数据影响
  364. uint8_t *tx_buf = (uint8_t *)g_modbusbuffer; // 强制转成字节指针
  365. uint8_t func_code = data[1]; // 功能码
  366. uint8_t total_len = modbus_error_response(JsRoot.addr & 0xFF, func_code, 0x03, tx_buf); // 功能码错误
  367. uart485send(tx_buf, total_len);
  368. }
  369. void taskprint(uint8_t *tx_buf, uint16_t len)
  370. {
  371. char buf[1024];
  372. int offset = 0;
  373. offset += snprintf(buf + offset, sizeof(buf) - offset, "RX_BUF: ");
  374. for (uint16_t i = 0; i < len && offset < sizeof(buf) - 2; i++) { // 防止越界
  375. offset += snprintf(buf + offset, sizeof(buf) - offset, "%02X ", tx_buf[i]);
  376. }
  377. CommonPrintf("%s\r\n", buf);
  378. }
  379. void taskprinttx(uint8_t *tx_buf, uint16_t len)
  380. {
  381. char buf[128];
  382. int offset = 0;
  383. offset += snprintf(buf + offset, sizeof(buf) - offset, "TX_BUF: ");
  384. for (uint16_t i = 0; i < len && offset < sizeof(buf) - 3; i++) { // 防止越界
  385. offset += snprintf(buf + offset, sizeof(buf) - offset, "%02X ", tx_buf[i]);
  386. }
  387. CommonPrintf("%s\r\n", buf);
  388. }
  389. void uart485send(uint8_t *tx_buf, uint16_t total_len)
  390. {
  391. HAL_GPIO_WritePin(GPIOA, RS485_RD_Pin, GPIO_PIN_SET); // 拉高发送
  392. HAL_UART_Transmit_DMA(&huart1, tx_buf, total_len);
  393. }
  394. void parse_AT_command(uint8_t *buf)
  395. {
  396. if (buf == NULL || buf[0] == '\0') // 去空
  397. return;
  398. size_t len = strlen((char*)buf);
  399. // // 调试打印原始数据
  400. // printf("Raw recv (len=%d): ", (int)len);
  401. // for (size_t i = 0; i < len; i++) {
  402. // if (buf[i] >= 32 && buf[i] <= 126) {
  403. // // 可打印字符
  404. // printf("%c", buf[i]);
  405. // } else {
  406. // // 控制字符打印为 [xx]
  407. // printf("[0x%02X]", buf[i]);
  408. // }
  409. // }
  410. // printf("\r\n");
  411. // 必须以 "###::" 开头
  412. if (len < 5 || strncmp((char*)buf, "###::", 5) != 0) {// 排除不符帧头的命令串
  413. printf("error=invalid prefix, rlt=401\r\n");
  414. return;
  415. }
  416. // 必须以 "\r\n" 结尾
  417. if (len < 5 || !(buf[len - 2] == '\r' && buf[len - 1] == '\n')) {
  418. printf("error=invalid ending, rlt=402\r\n");
  419. return;
  420. }
  421. buf[len - 2] = '\0'; // 去掉 \r\n
  422. char *cmd = (char*)buf + 5; // 去掉开头 "###::"
  423. // printf("AT Raw: %s\r\n", buf);
  424. // ================== 文档命令判断 ==================
  425. if (strncmp(cmd, "--debug=", 8) == 0) { // 控制台调试时限
  426. int minutes = atoi(cmd + 8);
  427. // 限制范围:UART1 特殊限制
  428. if (minutes >= 0 && minutes <= 1440) {
  429. // uint32_t debug_console_timeout = minutes;
  430. printf("Debug console %s, timeout=%d min\r\n, OK",
  431. (minutes > 0) ? "enabled" : "disabled",
  432. minutes);
  433. } else {
  434. printf("Invalid debug time\r\n");
  435. }
  436. return;
  437. }
  438. if (strcmp(cmd, "ls") == 0) {
  439. // printf("ls OK \r\n");
  440. print_JsRoot(); // 数据缓存 dump 输出
  441. return;
  442. }
  443. if (strncmp(cmd, "{\"mac\":\"", 8) == 0) {
  444. handle_mac_set_cmd(cmd); // 设置设备sn
  445. return;
  446. }
  447. if (strncmp(cmd, "--set_time=", 11) == 0) {
  448. printf("no rtc time, ok\r\n"); // 设置系统时间
  449. return;
  450. }
  451. if (strncmp(cmd, "--cfg_set=", 10) == 0) {
  452. handle_cfg_set_cmd(cmd); // 系统配置-KV设置
  453. return;
  454. }
  455. if (strncmp(cmd, "--cfg_setx=", 11) == 0) {
  456. handle_cfg_setx_cmd(cmd); // 通用配置-KV设置
  457. return;
  458. }
  459. if (strncmp(cmd, "--cfg_get=", 10) == 0) {
  460. handle_cfg_get_cmd(cmd); // 读取键值内容
  461. return;
  462. }
  463. if (strcmp(cmd, "reboot") == 0) {
  464. printf("ok\r\n");
  465. NVIC_SystemReset(); // 重启设备
  466. return;
  467. }
  468. if (strncmp(cmd, "--fileid=", 9) == 0) {
  469. handle_fileid_cmd(cmd); // 读取库存信息
  470. return;
  471. }
  472. if (strncmp(cmd, "--clear_fileid=", 15) == 0) {
  473. handle_clear_fileid_cmd(cmd); // 清除内部配置库
  474. return;
  475. }
  476. if (strncmp(cmd, "--iwdg_get", 10) == 0) {
  477. if (__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST)) // 清除复位标志
  478. {
  479. printf ("\r\n IWDG_RST flag");
  480. __HAL_RCC_CLEAR_RESET_FLAGS(); // 清除所有复位标志(包括IWDG复位标志)
  481. }else{
  482. printf ("\r\n No IWDG_RST flag");
  483. }
  484. return;
  485. }
  486. if (strncmp(cmd, "--Stack_size", 12) == 0) {
  487. Read_Remaining_stack_space(); // 读取每个任务栈剩余空间
  488. return;
  489. }
  490. if (strncmp(cmd, "--debug_printf=", 15) == 0) {
  491. char val = cmd[15];
  492. if (val == '0' || val == '1')
  493. {
  494. debug_print_enabled = (val == '1') ? 1 : 0;
  495. printf("Debug print %s\r\n", debug_print_enabled ? "enabled" : "disabled");
  496. }
  497. else
  498. {
  499. printf("Invalid debugprintf value: %c\r\n", val);
  500. }
  501. return;
  502. }
  503. if (strncmp(cmd, "--fdc_printf=", 13) == 0) {
  504. char val = cmd[13];
  505. if (val == '0' || val == '1')
  506. {
  507. fdc_print_enabled = (val == '1') ? 1 : 0;
  508. printf("FDC print %s\r\n", fdc_print_enabled ? "enabled" : "disabled");
  509. }
  510. else
  511. {
  512. printf("Invalid fdcprintf value: %c\r\n", val);
  513. }
  514. return;
  515. }
  516. if (strncmp(cmd, "--ads_printf=", 13) == 0) {
  517. char val = cmd[13];
  518. if (val == '0' || val == '1')
  519. {
  520. ads_print_enabled = (val == '1') ? 1 : 0;
  521. printf("ADS print %s\r\n", ads_print_enabled ? "enabled" : "disabled");
  522. }
  523. else
  524. {
  525. printf("Invalid adsprintf value: %c\r\n", val);
  526. }
  527. return;
  528. }
  529. if (strncmp((char*)cmd, "help", 4) == 0)
  530. {
  531. CommonPrintf("--debug=X\r\n");
  532. CommonPrintf("ls\r\n");
  533. CommonPrintf("{\"mac\":\"X\"}\r\n");
  534. CommonPrintf("--cfg_set=${key1}=${val1}\r\n");
  535. CommonPrintf("--cfg_setx=X,${key}=${val}\r\n");
  536. CommonPrintf("--cfg_get=${key}\r\n");
  537. CommonPrintf("reboot\r\n");
  538. CommonPrintf("--fileid=X,0\r\n");
  539. CommonPrintf("--clear_fileid=X\r\n");
  540. CommonPrintf("--iwdg_get\r\n");
  541. CommonPrintf("--Stack_size\r\n");
  542. CommonPrintf("--debug_printf=X\r\n");
  543. CommonPrintf("--fdc_printf=X\r\n");
  544. CommonPrintf("--ads_printf=X\r\n");
  545. return;
  546. }
  547. printf("error=unknown command, rlt=409\r\n"); // 未识别的命令
  548. // // AT+sys=release\r\n 更改系统模式为发布模式
  549. // if (strncmp((char*)buf, "AT+sys=release", 14) == 0)
  550. // {
  551. // Systemmode = releasemode;
  552. // printf(" Systemmode = releasemode \r\n");
  553. // return;
  554. // }
  555. // // AT+sys=iapboot\r\n 更改系统模式为升级模式
  556. // if (strncmp((char*)buf, "AT+sys=iapboot", 14) == 0)
  557. // {
  558. // Systemmode = IAPbootloader;
  559. // printf(" Systemmode = iapbootloader \r\n");
  560. // return;
  561. // }
  562. // // AT+sys=debug\r\n 更改系统模式为调试模式
  563. // if (strncmp((char*)buf, "AT+sys=debug", 12) == 0)
  564. // {
  565. // Systemmode = Debugmode;
  566. // printf(" Systemmode = debugmode \r\n");
  567. // return;
  568. // }
  569. }
  570. void print_JsRoot(void) {
  571. // 打印 JsonDat_Root 基础字段
  572. CommonPrintf(
  573. "mac=%s, addr=%u, role=%d, vers_id=%u, age=%d, age_ms=%ld, "
  574. "iapSize=%d, iapMd5=%s, iapLoadStatus=%u, subcode=%u, ubootback=%d, "
  575. "debug=%d, console=%d, baudrate=%d, update_ok=%d, update_err=%d\n",
  576. JsRoot.mac, JsRoot.addr, JsRoot.role, JsRoot.vers_id, JsRoot.age, JsRoot.age_ms,
  577. JsRoot.iapSize, JsRoot.iapMd5, JsRoot.iapLoadStatus, JsRoot.subcode, JsRoot.ubootback,
  578. JsRoot.debug, JsRoot.console, JsRoot.baudrate, JsRoot.update_ok, JsRoot.update_err
  579. );
  580. // 打印 calib_rod
  581. CommonPrintf("[calib_rod.vol_values]=");
  582. for (int i = 0; i < CALIB_ROD_POINT_NUM; i++) {
  583. CommonPrintf("%.3f%s", JsWork.calib_rod.vol_values[i],
  584. (i < CALIB_ROD_POINT_NUM - 1) ? "," : "\n");
  585. }
  586. // 打印 calib_oil_water
  587. CommonPrintf("[calib_oil_water.cap_values]=");
  588. for (int i = 0; i < CALIB_POINT_NUM; i++) {
  589. CommonPrintf("%.3f%s", JsWork.calib_oil_water.cap_values[i],
  590. (i < CALIB_POINT_NUM - 1) ? "," : "\n");
  591. }
  592. // 打印 calib_residual_oil
  593. CommonPrintf("[calib_residual_oil.cap_values]=");
  594. for (int i = 0; i < CALIB_HEIGHT_POINT_NUM; i++) {
  595. CommonPrintf("%.3f%s", JsWork.calib_residual_oil.cap_values[i],
  596. (i < CALIB_HEIGHT_POINT_NUM - 1) ? "," : "\n");
  597. }
  598. CommonPrintf("[calib_residual_oil.vol_values]=");
  599. for (int i = 0; i < CALIB_HEIGHT_POINT_NUM; i++) {
  600. CommonPrintf("%.3f%s", JsWork.calib_residual_oil.vol_values[i],
  601. (i < CALIB_HEIGHT_POINT_NUM - 1) ? "," : "\n");
  602. }
  603. // 打印 JsWork 其他 float 字段
  604. CommonPrintf(
  605. "rod_vol_offset=%.3f, rod_dialog=%.3f, "
  606. "oil_para_indu=%.3f, oil_para_cap=%.3f, oil_cap_offset=%.3f, oil_dialog=%.3f, rod_coltime=%d\n",
  607. JsWork.rod_vol_offset,
  608. JsWork.rod_dialog,
  609. JsWork.oil_para_indu,
  610. JsWork.oil_para_cap,
  611. JsWork.oil_cap_offset,
  612. JsWork.oil_dialog,
  613. JsWork.rod_coltime
  614. );
  615. CommonPrintf(
  616. "res_para_indu=%.3f, res_para_cap=%.3f, res_cap_offset=%.3f, res_vol_offset=%.3f, "
  617. "res_cap_dialog=%.3f, res_vol_dialog=%.3f, res_oil_cap_coltime=%d, res_oil_vol_coltime=%d\n",
  618. JsWork.res_para_indu,
  619. JsWork.res_para_cap,
  620. JsWork.res_cap_offset,
  621. JsWork.res_vol_offset,
  622. JsWork.res_cap_dialog,
  623. JsWork.res_vol_dialog,
  624. JsWork.res_oil_cap_coltime,
  625. JsWork.res_oil_vol_coltime
  626. );
  627. CommonPrintf(
  628. "temp_vol_offset=%.3f, temp_dialog=%.3f, temp_coltime=%d\n",
  629. JsWork.temp_vol_offset,
  630. JsWork.temp_dialog,
  631. JsWork.temp_coltime
  632. );
  633. }
  634. /* USER CODE BEGIN EFP */