flash.c
来自「ecos实时嵌入式操作系统」· C语言 代码 · 共 1,912 行 · 第 1/5 页
C
1,912 行
} if (prog_ok) { // 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 : (CYG_ADDRESS)entry_address; // Hope it's been set img->size = length; img->data_length = img_size;#ifdef CYGSEM_REDBOOT_FIS_CRC_CHECK img->file_cksum = cyg_crc32((unsigned char *)flash_addr, img_size);#endif fis_update_directory(); }}extern void arm_fis_delete(char *);static voidfis_delete(int argc, char *argv[]){ char *name; int num_reserved, i, stat; void *err_addr; struct fis_image_desc *img; if (!scan_opts(argc, argv, 2, 0, 0, (void **)&name, OPTION_ARG_TYPE_STR, "image name")) { fis_usage("invalid arguments"); return; }#ifdef CYGHWR_REDBOOT_ARM_FLASH_SIB // FIXME: this is somewhat half-baked arm_fis_delete(name); return;#endif img = (struct fis_image_desc *)fis_work_block; num_reserved = 0;#ifdef CYGOPT_REDBOOT_FIS_RESERVED_BASE num_reserved++;#endif#ifdef CYGOPT_REDBOOT_FIS_REDBOOT num_reserved++;#endif#ifdef CYGOPT_REDBOOT_FIS_REDBOOT_BACKUP num_reserved++;#endif#ifdef CYGOPT_REDBOOT_FIS_REDBOOT_POST num_reserved++;#endif#ifdef CYGSEM_REDBOOT_FLASH_CONFIG num_reserved++;#endif#if 1 // And the descriptor for the descriptor table itself num_reserved++;#endif memcpy(fis_work_block, fis_addr, fisdir_size); img = fis_lookup(name, &i); if (img) { if (i < num_reserved) { diag_printf("Sorry, '%s' is a reserved image and cannot be deleted\n", img->name); return; } if (!verify_action("Delete image '%s'", name)) { return; } } else { diag_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) { diag_printf("Error erasing at %p: %s\n", err_addr, flash_errmsg(stat)); } else { img->name[0] = (unsigned char)0xFF; fis_update_directory(); }}static voidfis_load(int argc, char *argv[]){ char *name; struct fis_image_desc *img; CYG_ADDRESS mem_addr; bool mem_addr_set = false; bool show_cksum = false; struct option_info opts[3];#ifdef CYGPKG_REDBOOT_FIS_CRC_CHECK unsigned long cksum;#endif int num_options;#ifdef CYGPKG_COMPRESS_ZLIB bool decompress = false;#endif 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"); num_options = 2;#ifdef CYGPKG_COMPRESS_ZLIB init_opts(&opts[num_options], 'd', false, OPTION_ARG_TYPE_FLG, (void **)&decompress, 0, "decompress"); num_options++;#endif if (!scan_opts(argc, argv, 2, opts, num_options, (void **)&name, OPTION_ARG_TYPE_STR, "image name")) { fis_usage("invalid arguments"); return; } memcpy(fis_work_block, fis_addr, fisdir_size); if ((img = fis_lookup(name, NULL)) == (struct fis_image_desc *)0) { diag_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 < (CYG_ADDRESS)user_ram_start) || ((mem_addr+img->data_length) >= (CYG_ADDRESS)user_ram_end)) { diag_printf("Not a loadable image\n"); return; }#ifdef CYGPKG_COMPRESS_ZLIB if (decompress) { int err; _pipe_t fis_load_pipe; _pipe_t* p = &fis_load_pipe; p->out_buf = (unsigned char*) mem_addr; p->out_max = p->out_size = -1; p->in_buf = (unsigned char*) img->flash_base; p->in_avail = img->data_length; err = (*_dc_init)(p); if (0 == err) err = (*_dc_inflate)(p); // Free used resources, do final translation of // error value. err = (*_dc_close)(p, err); if (0 != err && p->msg) { diag_printf("decompression error: %s\n", p->msg); } else { diag_printf("Image loaded from %p-%p\n", (unsigned char *)mem_addr, p->out_buf); } // Set load address/top load_address = mem_addr; load_address_end = (unsigned long)p->out_buf; // Reload fis directory memcpy(fis_work_block, fis_addr, fisdir_size); } else // dangling block#endif { memcpy((void *)mem_addr, (void *)img->flash_base, img->data_length); // Set load address/top load_address = mem_addr; load_address_end = mem_addr + img->data_length; } entry_address = (unsigned long)img->entry_point;#ifdef CYGPKG_REDBOOT_FIS_CRC_CHECK cksum = cyg_crc32((unsigned char *)mem_addr, img->data_length); if (show_cksum) { diag_printf("Checksum: 0x%08lx\n", cksum); } // When decompressing, leave CRC checking to decompressor if (!decompress && img->file_cksum) { if (cksum != img->file_cksum) { diag_printf("** Warning - checksum failure. stored: 0x%08lx, computed: 0x%08lx\n", img->file_cksum, cksum); } }#endif}#endif // CYGOPT_REDBOOT_FISstatic voidfis_write(int argc, char *argv[]){ int stat; unsigned long length; CYG_ADDRESS mem_addr, flash_addr; bool mem_addr_set = false; bool flash_addr_set = false; bool length_set = false; void *err_addr; struct option_info opts[3]; 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], 'f', true, OPTION_ARG_TYPE_NUM, (void **)&flash_addr, (bool *)&flash_addr_set, "FLASH memory base address"); init_opts(&opts[2], 'l', true, OPTION_ARG_TYPE_NUM, (void **)&length, (bool *)&length_set, "image length [in FLASH]"); if (!scan_opts(argc, argv, 2, opts, 3, 0, 0, 0)) { fis_usage("invalid arguments"); return; } if (!mem_addr_set || !flash_addr_set || !length_set) { fis_usage("required parameter missing"); return; } // Round up length to FLASH block size#ifndef CYGPKG_HAL_MIPS // FIXME: compiler is b0rken length = ((length + flash_block_size - 1) / flash_block_size) * flash_block_size;#endif if (flash_addr_set && ((stat = flash_verify_addr((void *)flash_addr)) || (stat = flash_verify_addr((void *)(flash_addr+length-1))))) { _show_invalid_flash_address(flash_addr, stat); return; } if (flash_addr_set && flash_addr & (flash_block_size-1)) { diag_printf("Invalid FLASH address: %p\n", (void *)flash_addr); diag_printf(" must be 0x%x aligned\n", flash_block_size); return; } if ((mem_addr < (CYG_ADDRESS)ram_start) || ((mem_addr+length) >= (CYG_ADDRESS)ram_end)) { diag_printf("** WARNING: RAM address: %p may be invalid\n", (void *)mem_addr); diag_printf(" valid range is %p-%p\n", (void *)ram_start, (void *)ram_end); } // 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))) { diag_printf("Can't program this region - contains code in use!\n"); return; } if (!verify_action("* CAUTION * about to program FLASH\n at %p..%p from %p", (void *)flash_addr, (void *)(flash_addr+length-1), (void *)mem_addr)) { return; // The guy gave up } prog_ok = true; if (prog_ok) { // Erase area to be programmed if ((stat = flash_erase((void *)flash_addr, length, (void **)&err_addr)) != 0) { diag_printf("Can't erase region at %p: %s\n", err_addr, flash_errmsg(stat)); prog_ok = false; } } if (prog_ok) { // Now program it if ((stat = flash_program((void *)flash_addr, (void *)mem_addr, length, (void **)&err_addr)) != 0) { diag_printf("Can't program region at %p: %s\n", err_addr, flash_errmsg(stat)); prog_ok = false; } }}static voidfis_erase(int argc, char *argv[]){ int stat; unsigned long length; CYG_ADDRESS flash_addr; 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))))) { _show_invalid_flash_address(flash_addr, stat); return; } if (flash_addr_set && flash_addr & (flash_block_size-1)) { diag_printf("Invalid FLASH address: %p\n", (void *)flash_addr); diag_printf(" must be 0x%x aligned\n", flash_block_size); 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))) { diag_printf("Can't erase this region - contains code in use!\n"); return; } if ((stat = flash_erase((void *)flash_addr, length, (void **)&err_addr)) != 0) { diag_printf("Error erasing at %p: %s\n", err_addr, flash_errmsg(stat)); }}#ifdef CYGHWR_IO_FLASH_BLOCK_LOCKINGstatic voidfis_lock(int argc, char *argv[]){ char *name; int stat; unsigned long length; CYG_ADDRESS flash_addr; 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 **)&name, OPTION_ARG_TYPE_STR, "image name")) { fis_usage("invalid arguments"); return; } /* Get parameters from image if specified */ if (name) { struct fis_image_desc *img; memcpy(fis_work_block, fis_addr, fisdir_size); if ((img = fis_lookup(name, NULL)) == (struct fis_image_desc *)0) { diag_printf("No image '%s' found\n", name); return; } flash_addr = img->flash_base; length = img->size; } else 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))))) { _show_invalid_flash_address(flash_addr, stat); return; } if ((stat = flash_lock((void *)flash_addr, length, (void **)&err_addr)) != 0) { diag_printf("Error locking at %p: %s\n", err_addr, flash_errmsg(stat)); }}static voidfis_unlock(int argc, char *argv[]){ char *name; int stat; unsigned long length; CYG_ADDRESS flash_addr; 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 **)&name, OPTION_ARG_TYPE_STR, "image name")) { fis_usage("invalid arguments"); return; } if (name) { struct fis_image_desc *img; memcpy(fis_work_block, fis_addr, fisdir_size);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?