📄 fconfig.c
字号:
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//boolflash_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)//boolflash_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)//boolflash_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 voidflash_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//boolflash_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 voidconfig_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 voidload_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 + -