diff --git a/demo/bootuf2/bootuf2.c b/demo/bootuf2/bootuf2.c index b992c4ba..c4c6ee5f 100644 --- a/demo/bootuf2/bootuf2.c +++ b/demo/bootuf2/bootuf2.c @@ -18,7 +18,7 @@ const char file_IDEX[] = { "" "" "" "" "\n" @@ -29,7 +29,7 @@ const char file_JOIN[] = { "" "" "" "" "\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; + } } \ No newline at end of file diff --git a/demo/bootuf2/bootuf2.h b/demo/bootuf2/bootuf2.h index b6a6e16b..ec31d3ea 100644 --- a/demo/bootuf2/bootuf2.h +++ b/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 */ diff --git a/demo/bootuf2/bootuf2_config.h b/demo/bootuf2/bootuf2_config.h index 5bc86022..307d09d2 100644 --- a/demo/bootuf2/bootuf2_config.h +++ b/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 diff --git a/demo/bootuf2/msc_bootuf2_template.c b/demo/bootuf2/msc_bootuf2_template.c index 7bba6f98..05d380d0 100644 --- a/demo/bootuf2/msc_bootuf2_template.c +++ b/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; +} \ No newline at end of file