📄 flash_junk.c
字号:
} } return false;}static voidfis_create(int argc, char *argv[]){ int i, stat; unsigned long mem_addr, exec_addr, flash_addr, entry_addr, length, img_size; char *name; bool mem_addr_set = false; bool exec_addr_set = false; bool entry_addr_set = false; bool flash_addr_set = false; bool length_set = false; bool img_size_set = false; void *fis_addr, *err_addr; struct fis_image_desc *img; bool slot_found; struct option_info opts[6]; bool prog_ok; init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, (void **)&mem_addr, (bool *)&mem_addr_set, "memory base address"); init_opts(&opts[1], 'r', true, OPTION_ARG_TYPE_NUM, (void **)&exec_addr, (bool *)&exec_addr_set, "ram base address"); init_opts(&opts[2], 'e', true, OPTION_ARG_TYPE_NUM, (void **)&entry_addr, (bool *)&entry_addr_set, "entry point address"); init_opts(&opts[3], 'f', true, OPTION_ARG_TYPE_NUM, (void **)&flash_addr, (bool *)&flash_addr_set, "FLASH memory base address"); init_opts(&opts[4], 'l', true, OPTION_ARG_TYPE_NUM, (void **)&length, (bool *)&length_set, "image length [in FLASH]"); init_opts(&opts[5], 's', true, OPTION_ARG_TYPE_NUM, (void **)&img_size, (bool *)&img_size_set, "image size [actual data]"); if (!scan_opts(argc, argv, 2, opts, 6, (void *)&name, OPTION_ARG_TYPE_STR, "file name")) { fis_usage("invalid arguments"); return; } if (!mem_addr_set || !length_set || !name) { fis_usage("required parameter missing"); return; } if (!img_size_set) { img_size = length; } // 'length' is size of FLASH image, 'img_size' is actual data size // Round up length to FLASH block size length = ((length + block_size - 1) / block_size) * block_size; if (length < img_size) { printf("Invalid FLASH image size/length combination"); return; } if (flash_addr_set && ((stat = flash_verify_addr((void *)flash_addr)) || (stat = flash_verify_addr((void *)(flash_addr+img_size-1))))) { printf("Invalid FLASH address: %p (%s)\n", (void *)flash_addr, flash_errmsg(stat)); printf(" valid range is %p-%p\n", (void *)flash_start, (void *)flash_end); return; } if ((mem_addr < (unsigned long)ram_start) || ((mem_addr+img_size) >= (unsigned long)ram_end)) { printf("** WARNING: RAM address: %p may be invalid\n", (void *)mem_addr); printf(" valid range is %p-%p\n", (void *)ram_start, (void *)ram_end); } if (strlen(name) >= sizeof(img->name)) { printf("Name is too long, must be less than %d chars\n", (int)sizeof(img->name)); return; } if (!flash_addr_set && !fis_find_free(&flash_addr, length)) { printf("Can't locate %ld bytes free in FLASH\n", length); return; } // Find a slot in the directory for this entry // First, see if an image by this name is already present slot_found = false; fis_addr = (void *)((unsigned long)flash_end - block_size); memcpy(fis_work_block, fis_addr, block_size); img = (struct fis_image_desc *)fis_work_block; for (i = 0; i < block_size/sizeof(*img); i++, img++) { if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) { if (flash_addr_set && (img->flash_base != flash_addr)) { printf("Image found, but FLASH address incorrect\n"); return; } if (img->size != length) { printf("Image found, but LENGTH is incorrect (0x%x != 0x%x)\n", img->size, length); return; } if (!verify_action("An image named '%s' exists", name)) { return; } else { slot_found = true; break; } } } // If not found, try and find an empty slot if (!slot_found) { img = (struct fis_image_desc *)fis_work_block; for (i = 0; i < block_size/sizeof(*img); i++, img++) { if (img->name[0] == (unsigned char)0xFF) { slot_found = true; break; } } } // Safety check - make sure the address range is not within the code we're running if (flash_code_overlaps((void *)flash_addr, (void *)(flash_addr+img_size-1))) { printf("Can't program this region - contains code in use!\n"); return; } prog_ok = true; if (prog_ok) { // Erase area to be programmed if ((stat = flash_erase((void *)flash_addr, length, (void **)&err_addr)) != 0) { printf("Can't erase region at %p: %x(%s)\n", err_addr, stat, flash_errmsg(stat)); prog_ok = false; } } if (prog_ok) { // Now program it if ((stat = flash_program((void *)flash_addr, (void *)mem_addr, img_size, (void **)&err_addr)) != 0) { printf("Can't program region at %p: %x(%s)\n", err_addr, stat, flash_errmsg(stat)); prog_ok = false; } } // Update directory memset(img, 0, sizeof(*img)); strcpy(img->name, name); img->flash_base = flash_addr; img->mem_base = exec_addr_set ? exec_addr : (flash_addr_set ? flash_addr : mem_addr); img->entry_point = entry_addr_set ? entry_addr : (unsigned long)entry_address; // Hope it's been set img->size = length; img->data_length = img_size; img->file_cksum = _cksum((unsigned long *)mem_addr, img_size);#ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL // Insure [quietly] that the directory is unlocked before trying to update flash_unlock((void *)fis_addr, block_size, (void **)&err_addr);#endif if ((stat = flash_erase((void *)fis_addr, block_size, (void **)&err_addr)) != 0) { printf("Error erasing at %p: %x(%s)\n", err_addr, stat, flash_errmsg(stat)); // Don't try to program if the erase failed } else { // Now program it if ((stat = flash_program((void *)fis_addr, (void *)fis_work_block, block_size, (void **)&err_addr)) != 0) { printf("Error programming at %p: %x(%s)\n", err_addr, stat, flash_errmsg(stat)); } }#ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL // Insure [quietly] that the directory is locked after the update flash_lock((void *)fis_addr, block_size, (void **)&err_addr);#endif}static voidfis_erase(int argc, char *argv[]){ int stat; unsigned long flash_addr, length; bool flash_addr_set = false; bool length_set = false; void *err_addr; struct option_info opts[2]; init_opts(&opts[0], 'f', true, OPTION_ARG_TYPE_NUM, (void **)&flash_addr, (bool *)&flash_addr_set, "FLASH memory base address"); init_opts(&opts[1], 'l', true, OPTION_ARG_TYPE_NUM, (void **)&length, (bool *)&length_set, "length"); if (!scan_opts(argc, argv, 2, opts, 2, (void **)0, 0, "")) { fis_usage("invalid arguments"); return; } if (!flash_addr_set || !length_set) { fis_usage("missing argument"); return; } if (flash_addr_set && ((stat = flash_verify_addr((void *)flash_addr)) || (stat = flash_verify_addr((void *)(flash_addr+length-1))))) { printf("Invalid FLASH address: %p (%s)\n", (void *)flash_addr, flash_errmsg(stat)); printf(" valid range is %p-%p\n", (void *)flash_start, (void *)flash_end); return; } // Safety check - make sure the address range is not within the code we're running if (flash_code_overlaps((void *)flash_addr, (void *)(flash_addr+length-1))) { printf("Can't program this region - contains code in use!\n"); return; } if ((stat = flash_erase((void *)flash_addr, length, (void **)&err_addr)) != 0) { printf("Error erasing at %p: %x(%s)\n", err_addr, stat, flash_errmsg(stat)); }}#if 0 < CYGHWR_IO_FLASH_BLOCK_LOCKING // This is an *interface*static voidfis_lock(int argc, char *argv[]){ int stat; unsigned long flash_addr, length; bool flash_addr_set = false; bool length_set = false; void *err_addr; struct option_info opts[2]; init_opts(&opts[0], 'f', true, OPTION_ARG_TYPE_NUM, (void **)&flash_addr, (bool *)&flash_addr_set, "FLASH memory base address"); init_opts(&opts[1], 'l', true, OPTION_ARG_TYPE_NUM, (void **)&length, (bool *)&length_set, "length"); if (!scan_opts(argc, argv, 2, opts, 2, (void **)0, 0, "")) { fis_usage("invalid arguments"); return; } if (!flash_addr_set || !length_set) { fis_usage("missing argument"); return; } if (flash_addr_set && ((stat = flash_verify_addr((void *)flash_addr)) || (stat = flash_verify_addr((void *)(flash_addr+length-1))))) { printf("Invalid FLASH address: %p (%s)\n", (void *)flash_addr, flash_errmsg(stat)); printf(" valid range is %p-%p\n", (void *)flash_start, (void *)flash_end); return; } if ((stat = flash_lock((void *)flash_addr, length, (void **)&err_addr)) != 0) { printf("Error locking at %p: %x(%s)\n", err_addr, stat, flash_errmsg(stat)); }}static voidfis_unlock(int argc, char *argv[]){ int stat; unsigned long flash_addr, length; bool flash_addr_set = false; bool length_set = false; void *err_addr; struct option_info opts[2]; init_opts(&opts[0], 'f', true, OPTION_ARG_TYPE_NUM, (void **)&flash_addr, (bool *)&flash_addr_set, "FLASH memory base address"); init_opts(&opts[1], 'l', true, OPTION_ARG_TYPE_NUM, (void **)&length, (bool *)&length_set, "length"); if (!scan_opts(argc, argv, 2, opts, 2, (void **)0, 0, "")) { fis_usage("invalid arguments"); return; } if (!flash_addr_set || !length_set) { fis_usage("missing argument"); return; } if (flash_addr_set && ((stat = flash_verify_addr((void *)flash_addr)) || (stat = flash_verify_addr((void *)(flash_addr+length-1))))) { printf("Invalid FLASH address: %p (%s)\n", (void *)flash_addr, flash_errmsg(stat)); printf(" valid range is %p-%p\n", (void *)flash_start, (void *)flash_end); return; } if ((stat = flash_unlock((void *)flash_addr, length, (void **)&err_addr)) != 0) { printf("Error unlocking at %p: %x(%s)\n", err_addr, stat, flash_errmsg(stat)); }}#endifstatic voidfis_delete(int argc, char *argv[]){ char *name; int i, stat; void *fis_addr, *err_addr; struct fis_image_desc *img; bool slot_found; if (!scan_opts(argc, argv, 2, 0, 0, (void **)&name, OPTION_ARG_TYPE_STR, "image name")) { fis_usage("invalid arguments"); return; } slot_found = false; fis_addr = (void *)((unsigned long)flash_end - block_size); memcpy(fis_work_block, fis_addr, block_size); img = (struct fis_image_desc *)fis_work_block; img += 2; // Skip reserved files for (i = 2; i < block_size/sizeof(*img); i++, img++) { if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) { if (!verify_action("Delete image '%s'", name)) { return; } else { slot_found = true; break; } } } if (!slot_found) { printf("No image '%s' found\n", name); return; } // Erase Data blocks (free space) if ((stat = flash_erase((void *)img->flash_base, img->size, (void **)&err_addr)) != 0) { printf("Error erasing at %p: %x(%s)\n", err_addr, stat, flash_errmsg(stat)); }#ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL // Insure [quietly] that the directory is unlocked before trying to update flash_unlock((void *)fis_addr, block_size, (void **)&err_addr);#endif // Update directory memset(img, 0xFF, sizeof(*img)); if ((stat = flash_erase((void *)fis_addr, block_size, (void **)&err_addr)) != 0) { printf("Error erasing at %p: %x(%s)\n", err_addr, stat, flash_errmsg(stat)); // Don't try to program if the erase failed } else { // Now program it if ((stat = flash_program((void *)fis_addr, (void *)fis_work_block, block_size, (void **)&err_addr)) != 0) { printf("Error programming at %p: %x(%s)\n", err_addr, stat, flash_errmsg(stat)); } }#ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL // Insure [quietly] that the directory is locked after the update flash_lock((void *)fis_addr, block_size, (void **)&err_addr);#endif}static voidfis_load(int argc, char *argv[]){ char *name; struct fis_image_desc *img; unsigned long mem_addr; bool mem_addr_set = false; bool show_cksum = false; struct option_info opts[2]; init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, (void **)&mem_addr, (bool *)&mem_addr_set, "memory [load] base address"); init_opts(&opts[1], 'c', false, OPTION_ARG_TYPE_FLG, (void **)&show_cksum, (bool *)0, "display checksum"); if (!scan_opts(argc, argv, 2, opts, 2, (void **)&name, OPTION_ARG_TYPE_STR, "image name")) { fis_usage("invalid arguments"); return; } if ((img = fis_lookup(name)) == (struct fis_image_desc *)0) { printf("No image '%s' found\n", name); return; } if (!mem_addr_set) { mem_addr = img->mem_base; } // Load image from FLASH into RAM if ((mem_addr < (unsigned long)ram_start) || ((mem_addr+img->size) >= (unsigned long)ram_end)) { printf("Not a loadable image\n"); return; } memcpy((void *)mem_addr, (void *)img->flash_base, img->size); entry_address = (unsigned long *)img->entry_point; if (img->file_cksum) { unsigned long cksum = _cksum((unsigned long *)mem_addr, img->data_length); if (cksum != img->file_cksum) { printf("** Warning - checksum failure. stored: %08lx, computed: %08lx\n", img->file_cksum, cksum); } if (show_cksum) { printf("Checksum: %08lx\n", cksum); } }}static booldo_flash_init(void){ int stat; static int init = 0; if (!init) { init = 1; if ((stat = flash_init((void *)(ram_end-FLASH_MIN_WORKSPACE), FLASH_MIN_WORKSPACE)) != 0) { printf("FLASH: driver init failed!, status: %x\n", stat); return false; } flash_get_limits((void *)0, (void **)&flash_start, (void **)&flash_end); flash_get_block_info(&block_size, &blocks); printf("FLASH: %p - %p, %d blocks of %p bytes each.\n", flash_start, flash_end, blocks, (void *)block_size); fis_work_block = (unsigned char *)(ram_end-FLASH_MIN_WORKSPACE-block_size); } return true;}voiddo_fis(int argc, char *argv[]){ struct cmd *cmd; if (argc < 2) { fis_usage("too few arguments"); return; } if (!do_flash_init()) return; if ((cmd = cmd_search(__FIS_cmds_TAB__, &__FIS_cmds_TAB_END__,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -