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

📄 fconfig.c

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 C
📖 第 1 页 / 共 3 页
字号:

    dp = &config->config_data[0];
    while (dp < &config->config_data[sizeof(config->config_data)]) {
        len = 4 + CONFIG_OBJECT_KEYLEN(dp) + CONFIG_OBJECT_ENABLE_KEYLEN(dp) +
            config_length(CONFIG_OBJECT_TYPE(dp));
        if (strcmp(key, CONFIG_OBJECT_KEY(dp)) == 0) {
            return dp;
        }
        dp += len;
    }
//    diag_printf("Can't find config data for '%s'\n", key);
    return false;
}

//
// Enumerate the keys from the configuration
//
bool
flash_next_key(char *key, int keylen, int *type, int *offset)
{
    unsigned char *dp;
    int len;

    if (!config_ok) return false;
    if ((*offset < 0) || (*offset >= MAX_CONFIG_DATA)) return false;

    dp = &config->config_data[*offset];
    if ((*type = CONFIG_OBJECT_TYPE(dp)) == CONFIG_EMPTY) return false;
    if ((len = CONFIG_OBJECT_KEYLEN(dp)) > keylen) return false;        
    memcpy(key, CONFIG_OBJECT_KEY(dp), len);
    *offset += 4 + CONFIG_OBJECT_KEYLEN(dp) + CONFIG_OBJECT_ENABLE_KEYLEN(dp) +
        config_length(CONFIG_OBJECT_TYPE(dp));
    return true;
}

//
// Retrieve a data object from the data base (in memory copy)
//
bool
flash_get_config(char *key, void *val, int type)
{
    unsigned char *dp;
    void *val_ptr;
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG_READONLY_FALLBACK
    struct _config *save_config = 0;
    bool res;
#endif

    if (!config_ok) return false;

    if ((dp = flash_lookup_config(key)) != (unsigned char *)NULL) {
        if (CONFIG_OBJECT_TYPE(dp) == type) {
            val_ptr = (void *)CONFIG_OBJECT_VALUE(dp);
            switch (type) {
                // Note: the data may be unaligned in the configuration data
            case CONFIG_BOOL:
                memcpy(val, val_ptr, sizeof(bool));
                break;
            case CONFIG_INT:
                memcpy(val, val_ptr, sizeof(unsigned long));
                break;
#ifdef CYGPKG_REDBOOT_NETWORKING
            case CONFIG_IP:
                memcpy(val, val_ptr, sizeof(in_addr_t));
                break;
            case CONFIG_ESA:
                memcpy(val, val_ptr, sizeof(enet_addr_t));
                break;
#endif
#if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1)
	    case CONFIG_NETPORT:
#endif
            case CONFIG_STRING:
            case CONFIG_SCRIPT:
                // Just return a pointer to the script/line
                *(unsigned char **)val = (unsigned char *)val_ptr;
                break;
            }
        } else {
            diag_printf("Request for config value '%s' - wrong type\n", key);
        }
        return true;
    }
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG_READONLY_FALLBACK
    // Did not find key. Is configuration data valid?
    // Check to see if the config data is valid, if not, revert to 
    // readonly mode, by setting config to readonly_config.  We
    // will set it back before we leave this function.
    if ( (config != readonly_config) && ((cyg_crc32((unsigned char *)config, 
               sizeof(struct _config)-sizeof(config->cksum)) != config->cksum) ||
        (config->key1 != CONFIG_KEY1)|| (config->key2 != CONFIG_KEY2))) {
        save_config = config;
        config = readonly_config;
        if ((cyg_crc32((unsigned char *)config, 
                       sizeof(struct _config)-sizeof(config->cksum)) != config->cksum) ||
            (config->key1 != CONFIG_KEY1)|| (config->key2 != CONFIG_KEY2)) {
            diag_printf("FLASH configuration checksum error or invalid key\n");
            config = save_config;
            return false;
        }
        else{
            diag_printf("Getting config information in READONLY mode\n");
            res = flash_get_config(key, val, type);
            config = save_config;
            return res;
        }        
    }
#endif
    return false;
}

//
// Update a data object in the data base (in memory copy & backing store)
//
bool
flash_set_config(char *key, void *val, int type)
{
    unsigned char *dp;
    void *val_ptr;

    if (!config_ok) return false;

    if ((dp = flash_lookup_config(key)) != (unsigned char *)NULL) {
        if (CONFIG_OBJECT_TYPE(dp) == type) {
            val_ptr = (void *)CONFIG_OBJECT_VALUE(dp);
            switch (type) {
                // Note: the data may be unaligned in the configuration data
            case CONFIG_BOOL:
                memcpy(val_ptr, val, sizeof(bool));
                break;
            case CONFIG_INT:
                memcpy(val_ptr, val, sizeof(unsigned long));
                break;
#ifdef CYGPKG_REDBOOT_NETWORKING
            case CONFIG_IP:
                memcpy(val_ptr, val, sizeof(in_addr_t));
                break;
            case CONFIG_ESA:
                memcpy(val_ptr, val, sizeof(enet_addr_t));
                break;
#endif
#if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1)
	    case CONFIG_NETPORT:
#endif
            case CONFIG_STRING:
            case CONFIG_SCRIPT:
                memcpy(val_ptr, val, config_length(CONFIG_STRING));
                break;
            }
        } else {
            diag_printf("Can't set config value '%s' - wrong type\n", key);
            return false;
        }
        flash_write_config(false);
        return true;
    }
    return false;
}

//
// Copy data into the config area
//
static void
flash_config_insert_value(unsigned char *dp, struct config_option *opt)
{
    switch (opt->type) {
        // Note: the data may be unaligned in the configuration data
    case CONFIG_BOOL:
        memcpy(dp, (void *)&opt->dflt, sizeof(bool));
        break;
    case CONFIG_INT:
        memcpy(dp, (void *)&opt->dflt, sizeof(unsigned long));
        break;
#ifdef CYGPKG_REDBOOT_NETWORKING
    case CONFIG_IP:
        memcpy(dp, (void *)&opt->dflt, sizeof(in_addr_t));
        break;
    case CONFIG_ESA:
        memcpy(dp, (void *)opt->dflt, sizeof(enet_addr_t));
        break;
#if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1)
    case CONFIG_NETPORT:
	// validate dflt and if not acceptable use first port
        {
	    int index;
	    const char *name;
	    for (index = 0; (name = net_devname(index)) != NULL; index++)
		if (!strcmp((char *)opt->dflt, name))
		    break;
	    if (name == NULL)
		name = net_devname(0);
	    memcpy(dp, name, strlen(name) + 1);
        }
        break;
#endif
#endif
    case CONFIG_STRING:
        memcpy(dp, (void *)opt->dflt, config_length(CONFIG_STRING));
        break;
    case CONFIG_SCRIPT:
        break;
    }
}

//
// Add a new option to the database
//
bool
flash_add_config(struct config_option *opt, bool update)
{
    unsigned char *dp, *kp;
    int len, elen, size;

    // If data item is already present, just update it
    // Note: only the data value can be thusly changed
    if ((dp = flash_lookup_config(opt->key)) != (unsigned char *)NULL) {
        flash_config_insert_value(CONFIG_OBJECT_VALUE(dp), opt);
        if (update) {
            flash_write_config(true);
        }
        return true;
    }
    // Add the data item
    dp = &config->config_data[0];
    size = 0;
    while (size < sizeof(config->config_data)) {
        if (CONFIG_OBJECT_TYPE(dp) == CONFIG_EMPTY) {
            kp = opt->key;
            len = strlen(kp) + 1;
            size += len + 2 + 2 + config_length(opt->type);
            if (opt->enable) {
                elen = strlen(opt->enable) + 1;
                size += elen;
            } else {
                elen = 0;
            }
            if (size > sizeof(config->config_data)) {
                break;
            }
            CONFIG_OBJECT_TYPE(dp) = opt->type; 
            CONFIG_OBJECT_KEYLEN(dp) = len;
            CONFIG_OBJECT_ENABLE_SENSE(dp) = opt->enable_sense;
            CONFIG_OBJECT_ENABLE_KEYLEN(dp) = elen;
            dp = CONFIG_OBJECT_KEY(dp);
            while (*kp) *dp++ += *kp++;
            *dp++ = '\0';    
            if (elen) {
                kp = opt->enable;
                while (*kp) *dp++ += *kp++;
                *dp++ = '\0';    
            }
            flash_config_insert_value(dp, opt);
            if (update) {
                flash_write_config(true);
            }
            return true;
        } else {
            len = 4 + CONFIG_OBJECT_KEYLEN(dp) + CONFIG_OBJECT_ENABLE_KEYLEN(dp) +
                config_length(CONFIG_OBJECT_TYPE(dp));
            dp += len;
            size += len;
        }
    }
    diag_printf("No space to add '%s'\n", opt->key);
    return false;
}

//
// Reset/initialize configuration data - used only when starting from scratch
//
static void
config_init(void)
{
    // Well known option strings
    struct config_option *optend = __CONFIG_options_TAB_END__;
    struct config_option *opt = __CONFIG_options_TAB__;

    memset(config, 0, sizeof(struct _config));
    while (opt != optend) {
        if (!flash_add_config(opt, false)) {
            return;
        }
        opt++;
    }
    config_ok = true;
}

//
// Attempt to get configuration information from the FLASH.
// If available (i.e. good checksum, etc), initialize "known"
// values for later use.
//
static void
load_flash_config(void)
{
    bool use_boot_script;
    unsigned char *cfg_temp = (unsigned char *)workspace_end;
#ifdef CYGHWR_REDBOOT_FLASH_CONFIG_MEDIA_FLASH
    void *err_addr;
#endif

    config_ok = false;
    script = (unsigned char *)0;
    cfg_temp -= sizeof(struct _config);  // Space for primary config data
    config = (struct _config *)cfg_temp;
    cfg_temp -= sizeof(struct _config);  // Space for backup config data
    backup_config = (struct _config *)cfg_temp;
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG_READONLY_FALLBACK
    cfg_temp -= sizeof(struct _config);  // Space for readonly copy of config data
    readonly_config = (struct _config *)cfg_temp;
#endif
    workspace_end = cfg_temp;
#ifdef CYGHWR_REDBOOT_FLASH_CONFIG_MEDIA_FLASH
    if (!do_flash_init()) return;
#ifdef CYGSEM_REDBOOT_FLASH_COMBINED_FIS_AND_CONFIG
    cfg_size = _rup(sizeof(struct _config), sizeof(struct fis_image_desc));
    if ((fisdir_size-cfg_size) < (CYGNUM_REDBOOT_FIS_DIRECTORY_ENTRY_COUNT *
                                  CYGNUM_REDBOOT_FIS_DIRECTORY_ENTRY_SIZE)) {
        // Too bad this can't be checked at compile/build time
        diag_printf("Sorry, FLASH config exceeds available space in FIS directory\n");
        return;
    }
    cfg_base = (void *)(((CYG_ADDRESS)fis_addr + fisdir_size) - cfg_size);
    fisdir_size -= cfg_size;
#else
    cfg_size = (flash_block_size > sizeof(struct _config)) ? 
        sizeof(struct _config) : 
        _rup(sizeof(struct _config), flash_block_size);
    if (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK < 0) {
        cfg_base = (void *)((CYG_ADDRESS)flash_end + 1 -
           _rup(_rup((-CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK*flash_block_size), cfg_size), flash_block_size));
    } else {
        cfg_base = (void *)((CYG_ADDRESS)flash_start + 
           _rup(_rup((CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK*flash_block_size), cfg_size), flash_block_size));
    }
#endif
    flash_read((void *)cfg_base, (void *)config, sizeof(struct _config), (void **)&err_addr);
#else
    read_eeprom(config, sizeof(struct _config));  // into 'config'
#endif
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG_READONLY_FALLBACK
    memcpy(readonly_config, config, sizeof(struct _config));
#endif
    if ((cyg_crc32((unsigned char *)config, 
                   sizeof(struct _config)-sizeof(config->cksum)) != config->cksum) ||
        (config->key1 != CONFIG_KEY1)|| (config->key2 != CONFIG_KEY2)) {
        diag_printf("**Warning** FLASH configuration checksum error or invalid key\n");
        diag_printf("Use 'fconfig -i' to [re]initialize database\n");
        config_init();
        return;
    }
    config_ok = true;
    flash_get_config("boot_script", &use_boot_script, CONFIG_BOOL);
    if (use_boot_script) {
        flash_get_config("boot_script_data", &script, CONFIG_SCRIPT);
        flash_get_config("boot_script_timeout", &script_timeout, CONFIG_INT);
    }
#ifdef CYGSEM_REDBOOT_VARIABLE_BAUD_RATE
    if (flash_get_config("console_baud_rate", &console_baud_rate, CONFIG_INT)) {
        extern int set_console_baud_rate(int);
        set_console_baud_rate(console_baud_rate);
    }
#endif
}

RedBoot_init(load_flash_config, RedBoot_INIT_SECOND);

// EOF fconfig.c

⌨️ 快捷键说明

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