Răsfoiți Sursa

update(demo/bootuf2): use flash cache

sakumisu 1 an în urmă
părinte
comite
3fc30cd058

+ 80 - 47
demo/bootuf2/bootuf2.c

@@ -18,7 +18,7 @@ const char file_IDEX[] = {
     "<html>"
     "<body>"
     "<script>\n"
-    "location.replace(\"" CONFIG_BOOT_UF2_INDEX_URL "\");\n"
+    "location.replace(\"" CONFIG_BOOTUF2_INDEX_URL "\");\n"
     "</script>"
     "</body>"
     "</html>\n"
@@ -29,7 +29,7 @@ const char file_JOIN[] = {
     "<html>"
     "<body>"
     "<script>\n"
-    "location.replace(\"" CONFIG_BOOT_UF2_JOIN_URL "\");\n"
+    "location.replace(\"" CONFIG_BOOTUF2_JOIN_URL "\");\n"
     "</script>"
     "</body>"
     "</html>\n"
@@ -44,6 +44,18 @@ static struct bootuf2_FILE files[] = {
     [3] = { .Name = "JOIN    HTM", .Content = file_JOIN, .FileSize = sizeof(file_JOIN) - 1 },
 };
 
+struct bootuf2_data {
+    const struct bootuf2_DBR *const DBR;
+    struct bootuf2_STATE *const STATE;
+    uint8_t *const fbuff;
+    uint8_t *const erase;
+    size_t page_count;
+    uint8_t *const cache;
+    const size_t cache_size;
+    uint32_t cached_address;
+    size_t cached_bytes;
+};
+
 /*!< define DBRs */
 static const struct bootuf2_DBR bootuf2_DBR = {
     .JMPInstruction = { 0xEB, 0x3C, 0x90 },
@@ -140,36 +152,15 @@ static int ffind_by_cluster(uint32_t cluster)
     return -1;
 }
 
-static bool uf2block_check_address(struct bootuf2_data *ctx,
-                                   struct bootuf2_BLOCK *uf2)
-{
-    uint32_t beg;
-    uint32_t end;
-
-    beg = uf2->TargetAddress;
-    end = uf2->TargetAddress + uf2->PayloadSize;
-
-    // if ((end >= beg) && (beg >= ctx->offset) &&
-    //     (end <= ctx->offset + ctx->size))
-    // {
-    //     return true;
-    // }
-
-    return true;
-}
-
 static bool bootuf2block_check_writable(struct bootuf2_STATE *STATE,
-                                    struct bootuf2_BLOCK *uf2, uint32_t block_max)
+                                        struct bootuf2_BLOCK *uf2, uint32_t block_max)
 {
-    if (uf2->NumberOfBlock)
-    {
-        if (uf2->BlockIndex < block_max)
-        {
+    if (uf2->NumberOfBlock) {
+        if (uf2->BlockIndex < block_max) {
             uint8_t mask = 1 << (uf2->BlockIndex % 8);
             uint32_t pos = uf2->BlockIndex / 8;
 
-            if ((STATE->Mask[pos] & mask) == 0)
-            {
+            if ((STATE->Mask[pos] & mask) == 0) {
                 return true;
             }
         }
@@ -179,32 +170,25 @@ static bool bootuf2block_check_writable(struct bootuf2_STATE *STATE,
 }
 
 static void bootuf2block_state_update(struct bootuf2_STATE *STATE,
-                                  struct bootuf2_BLOCK *uf2, uint32_t block_max)
+                                      struct bootuf2_BLOCK *uf2, uint32_t block_max)
 {
-    if (uf2->NumberOfBlock)
-    {
-        if (STATE->NumberOfBlock != uf2->NumberOfBlock)
-        {
+    if (uf2->NumberOfBlock) {
+        if (STATE->NumberOfBlock != uf2->NumberOfBlock) {
             if ((uf2->NumberOfBlock >= BOOTUF2_BLOCKSMAX) ||
-                STATE->NumberOfBlock)
-            {
+                STATE->NumberOfBlock) {
                 /*!< uf2 block only can be update once */
                 /*!< this will cause never auto reboot */
                 STATE->NumberOfBlock = 0xffffffff;
-            }
-            else
-            {
+            } else {
                 STATE->NumberOfBlock = uf2->NumberOfBlock;
             }
         }
 
-        if (uf2->BlockIndex < block_max)
-        {
+        if (uf2->BlockIndex < block_max) {
             uint8_t mask = 1 << (uf2->BlockIndex % 8);
             uint32_t pos = uf2->BlockIndex / 8;
 
-            if ((STATE->Mask[pos] & mask) == 0)
-            {
+            if ((STATE->Mask[pos] & mask) == 0) {
                 STATE->Mask[pos] |= mask;
                 STATE->NumberOfWritten++;
             }
@@ -212,7 +196,7 @@ static void bootuf2block_state_update(struct bootuf2_STATE *STATE,
     }
 
     USB_LOG_DBG("UF2 block total %d written %d index %d\r\n",
-                 uf2->NumberOfBlock, STATE->NumberOfWritten, uf2->BlockIndex);
+                uf2->NumberOfBlock, STATE->NumberOfWritten, uf2->BlockIndex);
 }
 
 static bool bootuf2block_state_check(struct bootuf2_STATE *STATE)
@@ -221,6 +205,47 @@ static bool bootuf2block_state_check(struct bootuf2_STATE *STATE)
            STATE->NumberOfBlock;
 }
 
+static int bootuf2_flash_flush(struct bootuf2_data *ctx)
+{
+    int err;
+
+    if (ctx->cached_bytes == 0) {
+        return 0;
+    }
+
+    err = bootuf2_flash_write(ctx->cached_address, ctx->cache, ctx->cached_bytes);
+
+    if (err) {
+        USB_LOG_ERR("UF2 slot flash write error %d at offset %08lx len %d\r\n",
+                    err, ctx->cached_address, ctx->cached_bytes);
+        return -1;
+    }
+
+    ctx->cached_bytes = 0;
+
+    return 0;
+}
+
+int bootuf2_flash_write_internal(struct bootuf2_data *ctx, struct bootuf2_BLOCK *uf2)
+{
+    /*!< 1.cache not empty and address not continue */
+    /*!< 2.cache full */
+    if ((ctx->cached_bytes && ((ctx->cached_address + ctx->cached_bytes) != uf2->TargetAddress)) ||
+        (ctx->cached_bytes == ctx->cache_size)) {
+        int err = bootuf2_flash_flush(ctx);
+        if (err)
+            return err;
+    }
+
+    /*!< write len always is 256, cache_size always is a multiple of 256 */
+    memcpy(ctx->cache + ctx->cached_bytes, uf2->Data, uf2->PayloadSize);
+
+    ctx->cached_address = uf2->TargetAddress - ctx->cached_bytes;
+    ctx->cached_bytes += uf2->PayloadSize;
+
+    return 0;
+}
+
 void bootuf2_init(void)
 {
     struct bootuf2_data *ctx;
@@ -228,6 +253,9 @@ void bootuf2_init(void)
     ctx = &bootuf2_disk;
 
     fcalculate_cluster(ctx);
+
+    ctx->cached_bytes = 0;
+    ctx->cached_address = 0;
 }
 
 int boot2uf2_read_sector(uint32_t start_sector, uint8_t *buff, uint32_t sector_count)
@@ -394,14 +422,13 @@ int bootuf2_write_sector(uint32_t start_sector, const uint8_t *buff, uint32_t se
 
         if (uf2->FamilyID == CONFIG_BOOTUF2_FAMILYID) {
             if (bootuf2block_check_writable(ctx->STATE, uf2, CONFIG_BOOTUF2_FLASHMAX)) {
-                bootuf2_write_flash(ctx, uf2);
+                bootuf2_flash_write_internal(ctx, uf2);
                 bootuf2block_state_update(ctx->STATE, uf2, CONFIG_BOOTUF2_FLASHMAX);
             } else {
                 USB_LOG_DBG("UF2 block %d already written\r\n",
-                       uf2->BlockIndex);
+                            uf2->BlockIndex);
             }
-        }
-        else {
+        } else {
             USB_LOG_DBG("UF2 block illegal id %08x\r\n", uf2->FamilyID);
         }
 
@@ -426,5 +453,11 @@ uint32_t bootuf2_get_sector_count(void)
 
 bool bootuf2_is_write_done(void)
 {
-    return bootuf2block_state_check(&bootuf2_disk.STATE);
+    if (bootuf2block_state_check(bootuf2_disk.STATE)) {
+        bootuf2_flash_flush(&bootuf2_disk);
+        USB_LOG_DBG("UF2 update ok\r\n");
+        return true;
+    } else {
+        return false;
+    }
 }

+ 3 - 13
demo/bootuf2/bootuf2.h

@@ -108,18 +108,6 @@ struct bootuf2_FILE
     uint16_t ClusterEnd;
 };
 
-struct bootuf2_data {
-    const struct bootuf2_DBR *const DBR;
-    struct bootuf2_STATE *const STATE;
-    uint8_t *const fbuff;
-    uint8_t *const erase;
-    size_t page_count;
-    uint8_t *const cache;
-    const size_t cache_size;
-    uint32_t cached_address;
-    size_t cached_bytes;
-};
-
 #define BOOTUF2_DIVCEIL(_v, _d) (((_v) / (_d)) + ((_v) % (_d) ? 1 : 0))
 
 #define BOOTUF2_MAGIC_START0 0x0A324655u
@@ -223,6 +211,8 @@ uint16_t bootuf2_get_sector_size(void);
 uint32_t bootuf2_get_sector_count(void);
 
 bool bootuf2_is_write_done(void);
-int bootuf2_write_flash(struct bootuf2_data *ctx, struct bootuf2_BLOCK *uf2);
+
+void boot2uf2_flash_init(void);
+int bootuf2_flash_write(uint32_t address, const uint8_t *data, size_t size);
 
 #endif /*  BOOTUF2_H */

+ 2 - 2
demo/bootuf2/bootuf2_config.h

@@ -8,8 +8,8 @@
 
 #define CONFIG_PRODUCT            "CherryUSB"
 #define CONFIG_BOARD              "CherryUSB BOARD"
-#define CONFIG_BOOT_UF2_INDEX_URL "https://github.com/cherry-embedded"
-#define CONFIG_BOOT_UF2_JOIN_URL  "http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=GyH2M5XfWTHQzmZis4ClpgvfdObPrvtk&authKey=LmcLhfno%2BiW51wmgVC%2F8WoYwUXqiclzWDHMU1Jy1d6S8cECJ4Q7bfJ%2FTe67RLakI&noverify=0&group_code=642693751"
+#define CONFIG_BOOTUF2_INDEX_URL "https://github.com/cherry-embedded"
+#define CONFIG_BOOTUF2_JOIN_URL  "http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=GyH2M5XfWTHQzmZis4ClpgvfdObPrvtk&authKey=LmcLhfno%2BiW51wmgVC%2F8WoYwUXqiclzWDHMU1Jy1d6S8cECJ4Q7bfJ%2FTe67RLakI&noverify=0&group_code=642693751"
 
 #define CONFIG_BOOTUF2_CACHE_SIZE         4096
 #define CONFIG_BOOTUF2_SECTOR_SIZE        512

+ 12 - 7
demo/bootuf2/msc_bootuf2_template.c

@@ -7,15 +7,15 @@
 #include "usbd_msc.h"
 #include "bootuf2.h"
 
-#define MSC_IN_EP          0x81
-#define MSC_OUT_EP         0x02
+#define MSC_IN_EP  0x81
+#define MSC_OUT_EP 0x02
 
 #define USBD_VID           0xFFFF
 #define USBD_PID           0xFFFF
 #define USBD_MAX_POWER     100
 #define USBD_LANGID_STRING 1033
 
-#define USB_CONFIG_SIZE    (9 + MSC_DESCRIPTOR_LEN)
+#define USB_CONFIG_SIZE (9 + MSC_DESCRIPTOR_LEN)
 
 #ifdef CONFIG_USB_HS
 #define MSC_MAX_MPS 512
@@ -115,6 +115,7 @@ static void usbd_event_handler(uint8_t busid, uint8_t event)
         case USBD_EVENT_SUSPEND:
             break;
         case USBD_EVENT_CONFIGURED:
+            bootuf2_init();
             break;
         case USBD_EVENT_SET_REMOTE_WAKEUP:
             break;
@@ -149,15 +150,19 @@ static struct usbd_interface intf0;
 
 void msc_bootuf2_init(uint8_t busid, uint32_t reg_base)
 {
-    bootuf2_init();
-
+    boot2uf2_flash_init();
     usbd_desc_register(busid, msc_bootuf2_descriptor);
     usbd_add_interface(busid, usbd_msc_init_intf(busid, &intf0, MSC_OUT_EP, MSC_IN_EP));
 
     usbd_initialize(busid, reg_base, usbd_event_handler);
 }
 
-int bootuf2_write_flash(struct bootuf2_data *ctx, struct bootuf2_BLOCK *uf2)
+void boot2uf2_flash_init(void)
 {
-    return 0;
 }
+
+int bootuf2_flash_write(uint32_t address, const uint8_t *data, size_t size)
+{
+    USB_LOG_INFO("address:%08x, size:%d\n", address, size);
+    return 0;
+}