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 + -
显示快捷键?