#include "stdio.h" #include #include "hostRecvSlaveDataParse.h" #include "hostQueueUart.h" #include "mcu_common.h" static void slaveStateMachine(void); /* 状态机函数 */ static uint8_t slaveAnalysisWait(void); static uint8_t slaveAnalysisStartFlagSL(void); static uint8_t slaveAnalysisPortSL(void); static uint8_t slaveAnalysisLengthSL(void); static uint8_t slaveAnalysisEndFlagSL(void); /* 状态机状态机变量 */ uartStateMachine slaveState = wait; /** * @brief 状态机函数 * @param * @retval */ void slaveStateMachine(void) { if (slaveState == wait) { if (slaveAnalysisWait() == TRUE) { mcuUartRxTime = xTaskGetTickCount(); } } else if (slaveState == startFlagSL) { slaveAnalysisStartFlagSL(); } else if (slaveState == portSL) { slaveAnalysisPortSL(); } else if (slaveState == lengthSL) { slaveAnalysisLengthSL(); } else if (slaveState == endFlagSL) { slaveAnalysisEndFlagSL(); } } /** * @brief 状态 wait * @param * @retval 0:解析失败 1:解析成功 */ #define waitMaxLen 2 uint8_t slaveAnalysisWait(void) { if (mcuUartRxBufferIndex >= 2) { /* 透传数据帧包头 */ if (mcuUartRxBuffer[0] == 'S' && mcuUartRxBuffer[1] == 'L') { // log_info("startFlagSL\n"); state = startFlagSL; return TRUE; } } if (mcuUartRxBufferIndex < waitMaxLen) { return FALSE; } state = wait; mcuUartRxBufferIndex--; memcpy(mcuUartRxBuffer, mcuUartRxBuffer + 1, mcuUartRxBufferIndex); return FALSE; } /** * @brief 状态 startFlagSL * @param * @retval 0:解析失败 1:解析成功 */ uint8_t slaveAnalysisStartFlagSL(void) { /* 校验端口号 */ if (mcuUartRxBuffer[2] < 13) { // log_info("portSL\n"); state = portSL; return TRUE; } // log_error("portSL %d \n", gw485RxBuffer[2]); state = wait; mcuUartRxBufferIndex--; memcpy(mcuUartRxBuffer, mcuUartRxBuffer + 1, mcuUartRxBufferIndex); return FALSE; } /** * @brief 状态 portSL * @param * @retval 0:解析失败 1:解析成功 */ #define PortSLMaxLen 5 uint8_t slaveAnalysisPortSL(void) { /* 解析数据包的度 */ if (mcuUartRxBufferIndex >= PortSLMaxLen) { uint32_t tempLen = 0; tempLen = (mcuUartRxBuffer[3] << 8) | mcuUartRxBuffer[4]; if (tempLen <= 1024) { // log_info("lengthSL\n"); state = lengthSL; frameLength = 6 + tempLen; return TRUE; } } if (mcuUartRxBufferIndex < PortSLMaxLen) { return FALSE; } // log_error("lengthSL %d \n", (gw485RxBuffer[3] << 8) | gw485RxBuffer[4]); state = wait; mcuUartRxBufferIndex--; memcpy(mcuUartRxBuffer, mcuUartRxBuffer + 1, mcuUartRxBufferIndex); return FALSE; } /** * @brief 状态 lengthSL * @param * @retval 0:解析失败 1:解析成功 */ #define LengthSLMaxLen frameLength uint8_t slaveAnalysisLengthSL(void) { /* 解析帧尾 */ if (mcuUartRxBufferIndex >= LengthSLMaxLen) { if (mcuUartRxBuffer[LengthSLMaxLen - 1] == 0x17) { // log_info("endFlagSL\n"); state = endFlagSL; return TRUE; } } if (mcuUartRxBufferIndex < LengthSLMaxLen) { return FALSE; } // log_info("endFlagSL %d\n", gw485RxBuffer[LengthSLMaxLen - 1]); state = wait; mcuUartRxBufferIndex--; memcpy(mcuUartRxBuffer, mcuUartRxBuffer + 1, mcuUartRxBufferIndex); return FALSE; } /** * @brief 状态 endFlagSL * @param * @retval 0:解析失败 1:解析成功 */ uint8_t slaveAnalysisEndFlagSL(void) { uint16_t tempLen = ((mcuUartRxBuffer[3] << 8) | mcuUartRxBuffer[4]) + 6; //系统内存不足,丢去当前包 if (xPortGetFreeHeapSize() < tempLen + 1024) { //清零buff state = wait; su806RxBufferIndex = 0; return 1; } uint8_t *Buff = (uint8_t *)pvPortMalloc(tempLen + hostQueueUartSendInfoSize); hostQueueUartSendInfo *sendBuff = (hostQueueUartSendInfo *)Buff; sendBuff->length = tempLen; sendBuff->data = Buff + hostQueueUartSendInfoSize; memcpy((char *)sendBuff->data, (char *)su806RxBuffer, tempLen); if (uxQueueSpacesAvailable(su806_uart_Queue)) { xQueueSend(su806_uart_Queue, &Buff, 10); } /* 队列中无空间,释放内存,退出 */ else { vPortFree(Buff); } return 0; } void hostRecvSlaveDataParse(device_handle device) { /* 每次函数最多执行10ms */ static uint32_t tickstart = 0U; tickstart = xTaskGetTickCount(); /* 2S未解析出来一帧数据,将数据清零 */ if (getTickDiff(mcuUartRxTime) >= tick_2S) { mcuUartRxTime = xTaskGetTickCount(); mcuUartRxBufferIndex = 0; state = wait; } while (uart_dev_char_present(device) == 1 && ((xTaskGetTickCount() - tickstart) < 5)) { mcuUartRxBuffer[mcuUartRxBufferIndex++] = uart_dev_in_char(device); slaveStateMachine(); } if (uart_dev_char_present(device) != 1 && state != wait) { slaveStateMachine(); } }