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

📄 fconfig.c

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	}
        strcpy((unsigned char *)val_ptr, line);
	break;
#endif
#endif
    case CONFIG_SCRIPT:
        // Assume it always changes
        sp = (unsigned char *)val_ptr;
        diag_printf("Enter script, terminate with empty line\n");
        while (true) {
            *sp = '\0';
            diag_printf(">> ");
            ret = _rb_gets(line, sizeof(line), 0);
            if (ret < 0) return CONFIG_ABORT;
            if (strlen(line) == 0) break;
            lp = line;
            while (*lp) {
                *sp++ = *lp++;
            }
            *sp++ = '\n';
        }
        break;
    case CONFIG_STRING:
        if (strlen(line) >= MAX_STRING_LENGTH) {
            diag_printf("Sorry, value is too long\n");
            return CONFIG_BAD;
        }
        strcpy((unsigned char *)val_ptr, line);
        break;
    }
    return CONFIG_CHANGED;
}

//
// Manage configuration information with the FLASH
//

static int
config_length(int type)
{
    switch (type) {
    case CONFIG_BOOL:
        return sizeof(bool);
    case CONFIG_INT:
        return sizeof(unsigned long);
#ifdef CYGPKG_REDBOOT_NETWORKING
    case CONFIG_IP:
        return sizeof(in_addr_t);
    case CONFIG_ESA:
        // Would like this to be sizeof(enet_addr_t), but that causes much
        // pain since it fouls the alignment of data which follows.
        return 8;
#if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1)
    case CONFIG_NETPORT:
        return MAX_STRING_LENGTH;
#endif
#endif
    case CONFIG_STRING:
        return MAX_STRING_LENGTH;
    case CONFIG_SCRIPT:
        return MAX_SCRIPT_LENGTH;
    default:
        return 0;
    }
}

static cmd_fun do_flash_config;
RedBoot_cmd("fconfig",
            "Manage configuration kept in FLASH memory",
            "[-i] [-l] [-n] [-f] [-d] | [-d] nickname [value]",
            do_flash_config
    );

static void
do_flash_config(int argc, char *argv[])
{
    bool need_update = false;
    struct config_option *optend = __CONFIG_options_TAB_END__;
    struct config_option *opt = __CONFIG_options_TAB__;
    struct option_info opts[5];
    bool list_only;
    bool nicknames;
    bool fullnames;
    bool dumbterminal;
    int list_opt = 0;
    unsigned char *dp;
    int len, ret;
    char *title;
    char *onlyone = NULL;
    char *onevalue = NULL;
    bool doneone = false;
    bool init = false;

#ifdef CYGHWR_REDBOOT_FLASH_CONFIG_MEDIA_FLASH
    if (!__flash_init) {
        diag_printf("Sorry, no FLASH memory is available\n");
        return;
    }
#endif
    memcpy(backup_config, config, sizeof(struct _config));
    script = (unsigned char *)0;

    init_opts(&opts[0], 'l', false, OPTION_ARG_TYPE_FLG, 
              (void *)&list_only, (bool *)0, "list configuration only");
    init_opts(&opts[1], 'n', false, OPTION_ARG_TYPE_FLG, 
              (void *)&nicknames, (bool *)0, "show nicknames");
    init_opts(&opts[2], 'f', false, OPTION_ARG_TYPE_FLG, 
              (void *)&fullnames, (bool *)0, "show full names");
    init_opts(&opts[3], 'i', false, OPTION_ARG_TYPE_FLG, 
              (void *)&init, (bool *)0, "initialize configuration database");
    init_opts(&opts[4], 'd', false, OPTION_ARG_TYPE_FLG, 
              (void *)&dumbterminal, (bool *)0, "dumb terminal: no clever edits");

    // First look to see if we are setting or getting a single option
    // by just quoting its nickname
    if ( (2 == argc && '-' != argv[1][0]) ||
         (3 == argc && '-' != argv[1][0] && '-' != argv[2][0])) {
        // then the command was "fconfig foo [value]"
        onlyone = argv[1];
        onevalue = (3 == argc) ? argv[2] : NULL;
        list_opt = LIST_OPT_NICKNAMES;
    }
    // Next see if we are setting or getting a single option with a dumb
    // terminal invoked, ie. no line editing.
    else if (3 == argc &&
             '-' == argv[1][0] && 'd' == argv[1][1] && 0 == argv[1][2] && 
             '-' != argv[2][0]) {
        // then the command was "fconfig -d foo"
        onlyone = argv[2];
        onevalue = NULL;
        list_opt = LIST_OPT_NICKNAMES | LIST_OPT_DUMBTERM;
    }
    else {
        if (!scan_opts(argc, argv, 1, opts, 5, 0, 0, ""))
            return;
        list_opt |= list_only ? LIST_OPT_LIST_ONLY : 0;
        list_opt |= nicknames ? LIST_OPT_NICKNAMES : LIST_OPT_FULLNAMES;
        list_opt |= fullnames ? LIST_OPT_FULLNAMES : 0;
        list_opt |= dumbterminal ? LIST_OPT_DUMBTERM : 0;
    }

    if (init && verify_action("Initialize non-volatile configuration")) {
        config_init();
        need_update = true;
    }

    dp = &config->config_data[0];
    while (dp < &config->config_data[sizeof(config->config_data)]) {
        if (CONFIG_OBJECT_TYPE(dp) == CONFIG_EMPTY) {
            break;
        }
        len = 4 + CONFIG_OBJECT_KEYLEN(dp) + CONFIG_OBJECT_ENABLE_KEYLEN(dp) + 
            config_length(CONFIG_OBJECT_TYPE(dp));
        // Provide a title for well known [i.e. builtin] objects
        title = (char *)NULL;
        opt = __CONFIG_options_TAB__;
        while (opt != optend) {
            if (strcmp(opt->key, CONFIG_OBJECT_KEY(dp)) == 0) {
                title = opt->title;
                break;
            }
            opt++;
        }
        if ( onlyone && 0 != strcmp(CONFIG_OBJECT_KEY(dp), onlyone) )
            ret = CONFIG_OK; // skip this entry
        else {
            doneone = true;
            ret = get_config(dp, title, list_opt, onevalue); // do this opt
        }
        switch (ret) {
        case CONFIG_DONE:
            goto done;
        case CONFIG_ABORT:
            memcpy(config, backup_config, sizeof(struct _config));
            return;
        case CONFIG_CHANGED:
            need_update = true;
        case CONFIG_OK:
            dp += len;
            break;
        case CONFIG_BACK:
            dp = &config->config_data[0];
            continue;
        case CONFIG_BAD:
            // Nothing - make him do it again
            diag_printf ("** invalid entry\n");
            onevalue = NULL; // request a good value be typed in - or abort/whatever
        }
    }

 done:
    if (NULL != onlyone && !doneone) {
#ifdef CYGSEM_REDBOOT_ALLOW_DYNAMIC_FLASH_CONFIG_DATA
        if (verify_action("** entry '%s' not found - add", onlyone)) {
            struct config_option opt;
            diag_printf("Trying to add value\n");
        }
#else
        diag_printf("** entry '%s' not found\n", onlyone);
#endif
    }
    if (!need_update)
        return;
    flash_write_config(true);
}


#ifdef CYGSEM_REDBOOT_FLASH_ALIASES
static cmd_fun do_alias;
RedBoot_cmd("alias",
            "Manage aliases kept in FLASH memory",
            "name [value]",
            do_alias
    );

static void
make_alias(char *alias, char *name)
{
    diag_sprintf(alias, "alias/%s", name);
}

static void
do_alias(int argc, char *argv[])
{
    char name[80];
    char *val;
    struct config_option opt;

    switch (argc) {
    case 2:
        make_alias(name, argv[1]);
        if (flash_get_config(name, &val, CONFIG_STRING)) {
            diag_printf("'%s' = '%s'\n", argv[1], val);
        } else {
            diag_printf("'%s' not found\n", argv[1]);
        }
        break;
    case 3:
        if (strlen(argv[2]) >= MAX_STRING_LENGTH) {
            diag_printf("Sorry, value is too long\n");
            break;
        }
        make_alias(name, argv[1]);
        opt.type = CONFIG_STRING;
        opt.enable = (char *)0;
        opt.enable_sense = 1;
        opt.key = name;
        opt.dflt = (CYG_ADDRESS)argv[2];
        flash_add_config(&opt, true);
        break;
    default:
        diag_printf("usage: alias name [value]\n");
    }
}

// Lookup an alias. First try plain string aliases. If that fails try
// other types so allowing access to all configured values. This allows
// for alias (macro) expansion of normal 'fconfig' data, such as the
// board IP address.
char *
flash_lookup_alias(char *alias, char *alias_buf)
{
    char name[80];
    char *val;
    unsigned char * dp;
    void *val_ptr;
    int type;
    bool hold_bool_val;
    long hold_long_val;
#ifdef CYGPKG_REDBOOT_NETWORKING
    int esa_ptr;
#endif

    make_alias(name, alias);
    if (flash_get_config(name, &val, CONFIG_STRING)) {
        return val;
    } else {
        dp = flash_lookup_config(alias);
        if (dp) {
            val_ptr = (void *)CONFIG_OBJECT_VALUE(dp);
            switch (type = CONFIG_OBJECT_TYPE(dp)) {
            case CONFIG_BOOL:
                memcpy(&hold_bool_val, val_ptr, sizeof(bool));
                diag_sprintf(alias_buf, "%s", hold_bool_val ? "true" : "false");
                break;
            case CONFIG_INT:
                memcpy(&hold_long_val, val_ptr, sizeof(unsigned long));
                diag_sprintf(alias_buf,"%ld", hold_long_val);
                break;
#ifdef CYGPKG_REDBOOT_NETWORKING
            case CONFIG_IP:
                diag_sprintf(alias_buf,"%s", inet_ntoa((in_addr_t *)val_ptr));
                break;
            case CONFIG_ESA:
                for (esa_ptr = 0;  esa_ptr < sizeof(enet_addr_t);  esa_ptr++) {
                    diag_sprintf(alias_buf+(3*esa_ptr), "0x%02X", ((unsigned char *)val_ptr)[esa_ptr]);
                    if (esa_ptr < (sizeof(enet_addr_t)-1)) diag_printf(":");
                }
                break;
#endif
            case CONFIG_SCRIPT:
                return (char *) val_ptr;
                break;
            default:
                return (char *)NULL;
            }
            return alias_buf;
        } 
        return (char *)NULL;
    }
}

#endif //  CYGSEM_REDBOOT_FLASH_ALIASES

//
// Write the in-memory copy of the configuration data to the flash device.
//
void
flash_write_config(bool prompt)
{
#if defined(CYGHWR_REDBOOT_FLASH_CONFIG_MEDIA_FLASH)
    void *err_addr;
#if !defined(CYGSEM_REDBOOT_FLASH_COMBINED_FIS_AND_CONFIG)
    int stat;
#endif
#endif

    config->len = sizeof(struct _config);
    config->key1 = CONFIG_KEY1;  
    config->key2 = CONFIG_KEY2;
    config->cksum = cyg_crc32((unsigned char *)config, sizeof(struct _config)-sizeof(config->cksum));
    if (!prompt || verify_action("Update RedBoot non-volatile configuration")) {
#ifdef CYGHWR_REDBOOT_FLASH_CONFIG_MEDIA_FLASH
#ifdef CYGSEM_REDBOOT_FLASH_COMBINED_FIS_AND_CONFIG
        flash_read(fis_addr, fis_work_block, fisdir_size, (void **)&err_addr);
        fis_update_directory();
#else 
#ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL
        // Insure [quietly] that the config page is unlocked before trying to update
        flash_unlock((void *)cfg_base, cfg_size, (void **)&err_addr);
#endif
        if ((stat = flash_erase(cfg_base, cfg_size, (void **)&err_addr)) != 0) {
            diag_printf("   initialization failed at %p: %s\n", err_addr, flash_errmsg(stat));
        } else {
            if ((stat = flash_program(cfg_base, (void *)config, sizeof(struct _config), 
                                      (void **)&err_addr)) != 0) {
                diag_printf("Error writing config data at %p: %s\n", 
                            err_addr, flash_errmsg(stat));
            }
        }
#ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL
        // Insure [quietly] that the config data is locked after the update
        flash_lock((void *)cfg_base, cfg_size, (void **)&err_addr);
#endif
#endif // CYGSEM_REDBOOT_FLASH_COMBINED_FIS_AND_CONFIG
#else  // CYGHWR_REDBOOT_FLASH_CONFIG_MEDIA_FLASH
        write_eeprom(config, sizeof(struct _config));  // into 'config'
#endif
    }
}

//
// Find the configuration entry for a particular key
//
static unsigned char *
flash_lookup_config(char *key)
{
    unsigned char *dp;
    int len;

    if (!config_ok) return (unsigned char *)NULL;

⌨️ 快捷键说明

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