| | |
| | | |
| | | #include <cstring> |
| | | #include <pthread.h> |
| | | #include <cstdlib> |
| | | #include "mcu_if.h" |
| | | #include "../common/apptimer.h" |
| | | #include "../utils/crc16.h" |
| | |
| | | |
| | | #define ID_CM_APP_BOOT 0x0001 |
| | | #define ID_MC_MCU_BOOT 0x8001 |
| | | #define ID_CM_INQ_MCU_VER 0x0002 |
| | | #define ID_MC_MCU_VER 0x8002 |
| | | #define ID_CM_DFU_UPLOAD 0x0002 |
| | | #define ID_MC_DFU_RSP 0x8002 |
| | | #define ID_CM_RW_INFO 0x0003 |
| | | #define ID_MC_RW_INFO_RSP 0x8003 |
| | | #define ID_CM_MCU_DFU_REQ 0x0004 |
| | |
| | | uint16_t crc16; |
| | | }McuPkt; |
| | | |
| | | static uint8_t *dfuFile = NULL; |
| | | static uint8_t dfuFileBitmap[128]; |
| | | |
| | | static int dfuFileLength = 0; |
| | | static int dfuTryCnt = 0; |
| | | const int DFU_MAX_TRY = 3; |
| | | const int DFU_FILE_BLOCK_SIZE = 896; |
| | | |
| | | static void *UartThread1(void *p); |
| | | static void ParseMcuTimeout(union sigval sig); |
| | | static void McuCommandEntry(uint16_t id, const uint8_t *data, int lenth); |
| | | |
| | | static void SendDfuFile(int fileLen, int sentLen, int blockLen, const uint8_t *data); |
| | | static void GoNextDfuLater(union sigval sig); |
| | | static void GoNextDfu(void); |
| | | |
| | | void ParseMcuInit(void) |
| | | { |
| | | dfuFile = NULL; |
| | | dfuFileLength = 0; |
| | | |
| | | parse_status = SYNC_HEAD_ONE; |
| | | AppTimer_delete(ParseMcuTimeout); |
| | | |
| | |
| | | case ID_MC_MCU_BOOT: |
| | | DEBUG("MCU BOOT"); |
| | | break; |
| | | case ID_MC_MCU_VER: |
| | | DEBUG("MCU VER"); |
| | | case ID_MC_DFU_RSP: |
| | | DEBUG("ID_MC_DFU_RSP %d len %d", data[0], lenth); |
| | | |
| | | if (data[0] == 0) { |
| | | // 第一包传输成功 |
| | | dfuFileBitmap[0] |= 0x01; |
| | | } else if (data[0] == 10) { |
| | | // 升级完成 |
| | | memset(dfuFileBitmap, 0xFF, sizeof(dfuFileBitmap)); |
| | | } else if (data[0] == 11) { |
| | | // 放弃传输 |
| | | UploadDfuFileEnd(); |
| | | } else if (data[0] == 12) { |
| | | // 全部重传 |
| | | memset(dfuFileBitmap, 0, sizeof(dfuFileBitmap)); |
| | | } else if (data[0] == 13) { |
| | | // 部分重传,有后续字段 |
| | | DEBUG("BITMAP %02X %02X %02X %02X %02X", data[1], data[2], data[3], data[4], data[5]); |
| | | |
| | | int total = dfuFileLength / DFU_FILE_BLOCK_SIZE + ((dfuFileLength % DFU_FILE_BLOCK_SIZE)?1:0); |
| | | int a = 0, b = 0; |
| | | for (int i = 1; i < lenth; ++i) { |
| | | for (int j = 0; j < 8; ++j) { |
| | | if ((data[i] & BV(j))) b++; |
| | | a++; |
| | | if (a == total) { |
| | | i = lenth; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | DEBUG("BITMAP total %d succ %d", total, b); |
| | | |
| | | //memset(dfuFileBitmap, 0, sizeof(dfuFileBitmap)); |
| | | memcpy(dfuFileBitmap, data + 1, lenth - 1); |
| | | |
| | | if (total % 8) { |
| | | dfuFileBitmap[total/8] &= ~BV((total%8) - 1); |
| | | } else { |
| | | dfuFileBitmap[(total+7)/8 - 1] &= ~BV(7); |
| | | } |
| | | // dfuFileBitmap[total/8] &= ~BV(total%8); |
| | | } |
| | | |
| | | dfuTryCnt = 0; |
| | | AppTimer_delete(GoNextDfuLater); |
| | | GoNextDfu(); |
| | | break; |
| | | case ID_MC_RW_INFO_RSP: |
| | | break; |
| | |
| | | break; |
| | | case ID_MC_MCU_DFU_DATA_RSP: |
| | | break; |
| | | case ID_MC_CAR_INFO: |
| | | DEBUG("ID_MC_CAR_INFO"); |
| | | case ID_MC_CAR_INFO: { |
| | | DEBUG("ID_MC_CAR_INFO %d", lenth); |
| | | char ver[64] = {0}; |
| | | |
| | | memcpy(ver, data, 32); |
| | | |
| | | DEBUG("ID_MC_CAR_INFO %s", ver); |
| | | |
| | | break; |
| | | } |
| | | case ID_MC_RTK_DATA: |
| | | DEBUG("ID_MC_RTK_DATA"); |
| | | break; |
| | |
| | | break; |
| | | } |
| | | } |
| | | |
| | | static void SendDfuFile(int fileLen, int sentLen, int blockLen, const uint8_t *data) { |
| | | uint8_t buffer[1024]; |
| | | int x = 0; |
| | | |
| | | DEBUG("SendDfuFile fileLen %d sentLen %d blockLen %d", fileLen, sentLen, blockLen); |
| | | |
| | | buffer[x++] = BREAK_UINT32(fileLen, 3); |
| | | buffer[x++] = BREAK_UINT32(fileLen, 2); |
| | | buffer[x++] = BREAK_UINT32(fileLen, 1); |
| | | buffer[x++] = BREAK_UINT32(fileLen, 0); |
| | | |
| | | buffer[x++] = BREAK_UINT32(sentLen, 3); |
| | | buffer[x++] = BREAK_UINT32(sentLen, 2); |
| | | buffer[x++] = BREAK_UINT32(sentLen, 1); |
| | | buffer[x++] = BREAK_UINT32(sentLen, 0); |
| | | |
| | | buffer[x++] = HI_UINT16(blockLen); |
| | | buffer[x++] = LO_UINT16(blockLen); |
| | | |
| | | memcpy(buffer + x, data, blockLen); |
| | | x += blockLen; |
| | | |
| | | SendMcuCommand(ID_CM_DFU_UPLOAD, buffer, x); |
| | | } |
| | | |
| | | static void GoNextDfuLater(union sigval sig) { |
| | | AppTimer_delete(GoNextDfuLater); |
| | | |
| | | GoNextDfu(); |
| | | } |
| | | |
| | | static void GoNextDfu(void) |
| | | { |
| | | int dfuFileSent = 0, currDfuBlockLength = 0; |
| | | |
| | | if (dfuFileLength == 0 || dfuFile == NULL) |
| | | return; |
| | | |
| | | int row = 0, col = 0; |
| | | |
| | | dfuFileSent = dfuFileLength; |
| | | |
| | | for (row = 0; row < sizeof(dfuFileBitmap); ++row) { |
| | | for (col = 0; col < 8; ++col) { |
| | | if ((dfuFileBitmap[row] & BV(col)) == 0) { |
| | | DEBUG("ROW = %d COL = %d", row, col); |
| | | dfuFileSent = row * DFU_FILE_BLOCK_SIZE * 8 + col * DFU_FILE_BLOCK_SIZE; |
| | | goto GET_FILE_START; |
| | | } |
| | | } |
| | | } |
| | | |
| | | GET_FILE_START: |
| | | currDfuBlockLength = (dfuFileLength - dfuFileSent > DFU_FILE_BLOCK_SIZE) ? DFU_FILE_BLOCK_SIZE : (dfuFileLength - dfuFileSent); |
| | | |
| | | if (dfuFileSent >= dfuFileLength || currDfuBlockLength == 0) { |
| | | UploadDfuFileEnd(); |
| | | return; |
| | | } |
| | | |
| | | SendDfuFile(dfuFileLength, dfuFileSent, currDfuBlockLength, dfuFile + dfuFileSent); |
| | | |
| | | if (dfuFileSent > 0 && dfuFileSent + currDfuBlockLength < dfuFileLength) { |
| | | dfuFileBitmap[row] |= BV(col); |
| | | } |
| | | |
| | | if (dfuFileSent == 0 || dfuFileSent + currDfuBlockLength == dfuFileLength) { |
| | | dfuTryCnt++; |
| | | if (dfuTryCnt > DFU_MAX_TRY) { |
| | | UploadDfuFileEnd(); |
| | | return; |
| | | } |
| | | DEBUG("GoNextDfuLater 3 sec..."); |
| | | AppTimer_add(GoNextDfuLater, D_SEC(3)); |
| | | } else { |
| | | AppTimer_add(GoNextDfuLater, 10); |
| | | } |
| | | } |
| | | |
| | | void UploadDfuFileEnd(void) |
| | | { |
| | | DEBUG("UploadDfuFileEnd"); |
| | | |
| | | if (dfuFile != NULL) |
| | | free(dfuFile); |
| | | dfuFileLength = 0; |
| | | |
| | | AppTimer_delete(GoNextDfuLater); |
| | | } |
| | | |
| | | void UploadDfuFile(const uint8_t *file, int length) |
| | | { |
| | | DEBUG("UploadDfuFile %ld", length); |
| | | |
| | | if (length > 0) { |
| | | if (dfuFile != NULL) |
| | | free(dfuFile); |
| | | |
| | | dfuTryCnt = 0; |
| | | |
| | | dfuFile = (uint8_t *) malloc(length); |
| | | dfuFileLength = length; |
| | | memcpy(dfuFile, file, length); |
| | | memset(dfuFileBitmap, 0, sizeof(dfuFileBitmap)); |
| | | AppTimer_delete(GoNextDfuLater); |
| | | |
| | | GoNextDfu(); |
| | | } |
| | | } |