/** * Scan files under the root path and display them * \param full_path true to display full file path, else file name only. */ void media_scan_files(bool full_path) { FILINFO fno; DIR dir; char *fname; #if _USE_LFN char lfname[_MAX_LFN + 1]; fno.lfname = lfname; fno.lfsize = sizeof(lfname); #endif if (media_selection >= MEDIA_NUM_MAX) { return; } if (medias[media_selection].lun_id == 0xFF) { /* No files */ return; } media_connect(); file_path[2] = 0; /* Open the directory */ res = f_opendir(&dir, file_path); if (res == FR_OK) { for (;;) { res = f_readdir(&dir, &fno); if (res != FR_OK || fno.fname[0] == 0) { break; } #if _USE_LFN fname = *fno.lfname ? fno.lfname : fno.fname; #else fname = fno.fname; #endif if (*fname == '.') { continue; } /* Display if it's file */ if (0 == (fno.fattrib & AM_DIR)) { if (full_path) { dbg_print("%s/%s\r\n", file_path, fname); } else { dbg_print("%s\r\n", fname); } } } } }
/** * Receive new firmware * * \param info Regions information struct * \param no_partition Use single partition, do not split memory to app + buff * * \return received firmware size */ static uint32_t _app_load(struct regions_info *info, bool no_partition) { void *addr, *info_addr; uint32_t *p_sign, *p_len; uint32_t rx_size; uint32_t target_region; uint32_t i = 0, flags = 0xFF; if (info->boot_region != 0 && info->boot_region != 1) { dbg_print("bl: Boot region information (%d) invalid\r\n", (int)info->boot_region); return 0; } /* Wait media connection */ i = 0; while (i < MEDIA_NUM_MAX) { media_select((enum media_types)i); if (media_connect()) { dbg_print("bl: Source media %s is ready\r\n", media_get_type_str((enum media_types)i)); break; } else if (flags & (1 << i)) { flags &= ~(1 << i); dbg_print("bl: Source media %s not ready\r\n", media_get_type_str((enum media_types)i)); } i++; } target_region = no_partition ? info->boot_region : (!info->boot_region); addr = (void *)APP_START(target_region); info_addr = (void *)INFO_ADDR(false); dbg_print("bl: Load to %x, info @ %x\r\n", (unsigned)addr, (unsigned)info_addr); dbg_print("bl: Unlock download buffer & info area ...\r\n"); memory_unlock(addr, (void *)((uint32_t)addr + APP_CODE_SIZE - 1)); memory_unlock(info_addr, (void *)((uint32_t)info_addr + INFO_SIZE - 1)); dbg_print("bl: Unlock download buffer & info area done\r\n"); dbg_print("bl: Erase download buffer & info area ...\r\n"); memory_erase( addr, APP_CODE_SIZE); memory_erase(info_addr, INFO_SIZE); dbg_print("bl: Erase download buffer & info area done\r\n"); #ifdef DBG_USE_LED _app_led_blink(50, 4); _app_led_on(DBG_LED_PIN); #endif /* Clear SW force boot trigger */ #ifdef TRIGGER_USE_FLAG info->trigger = TRIGGER_BOOT; #endif p_sign = &info->signature[target_region]; p_len = &info->length[target_region]; rx_size = media_load_file(addr, APP_SIZE, (uint8_t *)app_mem_block_buf, MEM_BLOCK_SIZE, _app_save_block); if (rx_size) { *p_sign = region_signature(addr, rx_size); *p_len = rx_size; } else { *p_sign = 0; *p_len = 0; } /* Save region information */ region_info_write(info_addr, info); dbg_print("bl: Lock download buffer & info area ...\r\n"); memory_lock(addr, (void *)((uint32_t)addr + APP_CODE_SIZE - 1)); memory_lock(info_addr, (void *)((uint32_t)info_addr + INFO_SIZE - 1)); dbg_print("bl: Lock download buffer & info area done\r\n"); #ifdef DBG_USE_LED _app_led_off(DBG_LED_PIN); #endif #if DUMP_ENABLE _dump_data("Downloaded APP:\r\n", addr, rx_size, true); _dump_data("INFO:\r\n", info_addr, INFO_SIZE, true); #endif return rx_size; }