📄 fconfig.c
字号:
} 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 intconfig_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 voiddo_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_ALIASESstatic cmd_fun do_alias;RedBoot_cmd("alias", "Manage aliases kept in FLASH memory", "name [value]", do_alias );static voidmake_alias(char *alias, char *name){ diag_sprintf(alias, "alias/%s", name);}static voiddo_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.//voidflash_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 + -