⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flash.c

📁 基于ecos的redboot
💻 C
📖 第 1 页 / 共 5 页
字号:
    } 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: %s\n", err_addr, 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 void
fis_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;
	bool word_mode = false;
    struct option_info opts[4];
#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");
	init_opts(&opts[2], 'w', false, OPTION_ARG_TYPE_FLG, 
              (void **)&word_mode, (bool *)0, "read flash in 32-bit mode");
    num_options = 3;
#ifdef CYGPKG_COMPRESS_ZLIB
    init_opts(&opts[3], '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;
    }
    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)user_ram_start) || ((mem_addr+img->size) >= (unsigned long)user_ram_end))
		&& ((mem_addr < SRAM_BASE) || ((mem_addr+img->size) >= (SRAM_BASE + qdr_ch_sz_array[0])))
		&& ((mem_addr < (SRAM_BASE + 0x10000000)) || ((mem_addr+img->size) >= ((SRAM_BASE + 0x10000000) + qdr_ch_sz_array[1])))) {
        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_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) {
            printf("decompression error: %s\n", p->msg);
        } else {
            printf("Image loaded from %p-%p\n", (unsigned char *)mem_addr, p->out_buf);
        }

    } else // dangling block
#endif
    {
		if(word_mode)
		{
			*(SP_FRM_REG) = USE_32_BIT_DATA;
			memcpy((void *)mem_addr, (void *)img->flash_base, img->data_length);
			*(SP_FRM_REG) = USE_8_BIT_DATA;
		}
		else
		{
			charcpy((void *)mem_addr, (void *)img->flash_base, img->data_length);
		}
    }
    entry_address = (unsigned long *)img->entry_point;
	flash_entry_address = (unsigned long *)img->flash_base;
#ifdef CYGPKG_REDBOOT_FIS_CRC_CHECK
    cksum = crc32((unsigned char *)mem_addr, img->data_length);
    if (show_cksum) {
        printf("Checksum: 0x%08lx\n", cksum);
    }
    // When decompressing, leave CRC checking to decompressor
    if (!decompress && img->file_cksum) {
        if (cksum != img->file_cksum) {
            printf("** Warning - checksum failure.  stored: 0x%08lx, computed: 0x%08lx\n",
                   img->file_cksum, cksum);
        }
    }
#endif
}
#endif // CYGOPT_REDBOOT_FIS

static void
fis_write(int argc, char *argv[])
{
    int stat;
    unsigned long mem_addr, flash_addr, length;
    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;
	bool overlap = false;

    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 + block_size - 1) / block_size) * block_size;
#endif
    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 (flash_addr_set && flash_addr & (block_size-1)) {
        printf("Invalid FLASH address: %p\n", (void *)flash_addr);
        printf("   must be 0x%x aligned\n", block_size);
        return;
    }
    if ((mem_addr < (unsigned long)ram_start) ||
        ((mem_addr+length) >= (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);
    }
    // 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), &overlap)) {
        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
    }
	if(overlap)
	{
		flash_unlock((void *)flash_addr, length, (void **)&err_addr);
	}
    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: %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) {
            printf("Can't program region at %p: %s\n", err_addr, flash_errmsg(stat));
            prog_ok = false;
        }
    }
	if(overlap)
	{
		flash_lock((void *)flash_addr, length, (void **)&err_addr);
	}
}

static void
fis_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];
	bool overlap = false;

    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 (flash_addr_set && flash_addr & (block_size-1)) {
        printf("Invalid FLASH address: %p\n", (void *)flash_addr);
        printf("   must be 0x%x aligned\n", 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), &overlap)) {
        return;
    }
	if(overlap)
	{
		flash_unlock((void *)flash_addr, length, (void **)&err_addr);
	}
    if ((stat = flash_erase((void *)flash_addr, length, (void **)&err_addr)) != 0) {
        printf("Error erasing at %p: %s\n", err_addr, flash_errmsg(stat));
    }
	if(overlap)
	{
		flash_lock((void *)flash_addr, length, (void **)&err_addr);
	}
}

#ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING

static void
fis_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: %s\n", err_addr, flash_errmsg(stat));
    }
}

static void
fis_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: %s\n", err_addr, flash_errmsg(stat));
    }
}
#endif

static int __flash_init = 0;

void
_flash_info(void)
{
    if (!__flash_init) return;
    printf("FLASH(%dM): %p - %p, %d blocks of %p bytes each.\n", (((int)flash_end - (int)flash_start) / (1024 * 1024)),
           flash_start, flash_end, (int)blocks, (void *)block_size);
}

static bool
do_flash_init(void)
{
    int stat;

    if (!__flash_init) {
		*(SP_FRM_REG) = USE_8_BIT_DATA;
        if ((stat = flash_init((void *)(workspace_end-FLASH_MIN_WORKSPACE), 
                               FLASH_MIN_WORKSPACE, printf)) != 0) {
            printf("FLASH: driver init failed: %s\n", flash_errmsg(stat));
            return false;
        }
		__flash_init = 1;
        flash_get_limits((void *)0, (void **)&flash_start, (void **)&flash_end);
        flash_get_block_info(&block_size, &blocks);
        fis_work_block = (unsigned char *)(workspace_end-FLASH_MIN_WORKSPACE-block_size);
        workspace_end = fis_work_block;
        fisdir_size = block_size;
    }
    return true;
}

#ifndef CYGOPT_REDBOOT_FLASH_CONFIG
RedBoot_init(do_flash_init, RedBoot_INIT_FIRST);
#endif

static void
do_fis(int argc, char *argv[])
{
    struct cmd *cmd;

    if (argc < 2) {
        fis_usage("too few arguments");
        return;
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -