From 3ce7d9cbccabf7f94d8203a98796599cd9dd5411 Mon Sep 17 00:00:00 2001
From: fctom1215 <fctom1215@outlook.com>
Date: 星期二, 11 二月 2020 17:14:27 +0800
Subject: [PATCH] 修改了上坡起步。

---
 lib/src/main/cpp/mcu/mcu_if.cpp |  191 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 185 insertions(+), 6 deletions(-)

diff --git a/lib/src/main/cpp/mcu/mcu_if.cpp b/lib/src/main/cpp/mcu/mcu_if.cpp
index 454eb73..44e0c9e 100644
--- a/lib/src/main/cpp/mcu/mcu_if.cpp
+++ b/lib/src/main/cpp/mcu/mcu_if.cpp
@@ -4,6 +4,7 @@
 
 #include <cstring>
 #include <pthread.h>
+#include <cstdlib>
 #include "mcu_if.h"
 #include "../common/apptimer.h"
 #include "../utils/crc16.h"
@@ -29,8 +30,8 @@
 
 #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
@@ -54,12 +55,27 @@
     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);
 
@@ -284,8 +300,54 @@
         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;
@@ -293,9 +355,16 @@
             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;
@@ -306,3 +375,113 @@
             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();
+    }
+}

--
Gitblit v1.8.0