📄 flash_junk.c
字号:
argv[1])) != (struct cmd *)0) { (cmd->fun)(argc, argv); return; } fis_usage("unrecognized command");}#ifdef CYGSEM_REDBOOT_FLASH_CONFIG#include <flash_config.h>// Configuration data, saved in FLASH, used to set/update RedBoot// normal "configuration" data items.static struct _config { unsigned long key1; unsigned char config_data[1024-(3*4)]; unsigned long key2; unsigned long cksum;} config;#define CONFIG_KEY1 0x0BADFACE#define CONFIG_KEY2 0xDEADDEAD#define CONFIG_DONE 0#define CONFIG_ABORT -1#define CONFIG_CHANGED 1#define CONFIG_OK 2#define CONFIG_BACK 3#define CONFIG_BAD 4// Note: the following options are related. If 'bootp' is false, then// the other values are used in the configuration. Because of the way// that configuration tables are generated, they should have names which// are related. The configuration options will show up lexicographically// ordered, thus the peculiar naming.RedBoot_config_option("Run script at boot", boot_script, ALWAYS_ENABLED, true, CONFIG_BOOL );RedBoot_config_option("Boot script", boot_script_data, "boot_script", true, CONFIG_SCRIPT );// Some preprocessor magic for building the [constant] prompt string#define __cat(s1,c2,s3) s1 ## #c2 ## s3#define _cat(s1,c2,s3) __cat(s1,c2,s3)RedBoot_config_option(_cat("Boot script timeout (", CYGNUM_REDBOOT_FLASH_SCRIPT_TIMEOUT_RESOLUTION, "ms resolution)"), boot_script_timeout, "boot_script", true, CONFIG_INT );#undef __cat#undef _catCYG_HAL_TABLE_BEGIN( __CONFIG_options_TAB__, RedBoot_config_options);CYG_HAL_TABLE_END( __CONFIG_options_TAB_END__, RedBoot_config_options);extern struct config_option __CONFIG_options_TAB__[], __CONFIG_options_TAB_END__[];static intget_config(struct config_option *opt, int offset, bool list_only){ char line[80], *sp, *lp; int ret; bool hold_bool_val, enable; unsigned long hold_int_val;#ifdef CYGPKG_REDBOOT_NETWORKING in_addr_t hold_ip_val; enet_addr_t hold_esa_val; int esa_ptr; char *esp;#endif void *val_ptr; if (opt->enable) { flash_get_config(opt->enable, &enable, CONFIG_BOOL); if ((opt->enable_sense && !enable) || (!opt->enable_sense && enable)) { return CONFIG_OK; // Disabled field } } val_ptr = (void *)((unsigned char *)&config + offset); printf("%s: ", opt->title); switch (opt->type) { case CONFIG_BOOL: printf("%s ", *(bool *)val_ptr ? "true" : "false"); break; case CONFIG_INT: printf("%d ", *(int *)val_ptr); break;#ifdef CYGPKG_REDBOOT_NETWORKING case CONFIG_IP: printf("%s ", inet_ntoa((in_addr_t *)val_ptr)); break; case CONFIG_ESA: for (esa_ptr = 0; esa_ptr < sizeof(enet_addr_t); esa_ptr++) { printf("0x%02X", ((unsigned char *)val_ptr)[esa_ptr]); if (esa_ptr < (sizeof(enet_addr_t)-1)) printf(":"); } printf(" "); break;#endif case CONFIG_STRING: printf("??"); return CONFIG_OK; // FIXME - skip for now case CONFIG_SCRIPT: printf("\n"); sp = lp = (unsigned char *)val_ptr; while (*sp) { while (*lp != '\n') lp++; *lp = '\0'; printf(".. %s\n", sp); *lp++ = '\n'; sp = lp; } break; } if (list_only) { printf("\n"); return CONFIG_OK; } if (opt->type != CONFIG_SCRIPT) { ret = gets(line, sizeof(line), 0); if (ret < 0) return CONFIG_ABORT; if (strlen(line) == 0) return CONFIG_OK; // Just a CR - leave value untouched if (line[0] == '.') return CONFIG_DONE; if (line[0] == '^') return CONFIG_BACK; } switch (opt->type) { case CONFIG_BOOL: hold_bool_val = *(bool *)val_ptr; if (!parse_bool(line, (bool *)val_ptr)) { return CONFIG_BAD; } if (hold_bool_val != *(bool *)val_ptr) { return CONFIG_CHANGED; } else { return CONFIG_OK; } break; case CONFIG_INT: hold_int_val = *(unsigned long *)val_ptr; if (!parse_num(line, (unsigned long *)val_ptr, 0, 0)) { return CONFIG_BAD; } if (hold_int_val != *(unsigned long *)val_ptr) { return CONFIG_CHANGED; } else { return CONFIG_OK; } break;#ifdef CYGPKG_REDBOOT_NETWORKING case CONFIG_IP: hold_ip_val.s_addr = ((in_addr_t *)val_ptr)->s_addr; if (!inet_aton(line, (in_addr_t *)val_ptr)) { return CONFIG_BAD; } if (hold_ip_val.s_addr != ((in_addr_t *)val_ptr)->s_addr) { return CONFIG_CHANGED; } else { return CONFIG_OK; } break; case CONFIG_ESA: memcpy(&hold_esa_val, val_ptr, sizeof(enet_addr_t)); esp = line; for (esa_ptr = 0; esa_ptr < sizeof(enet_addr_t); esa_ptr++) { unsigned long esa_byte; if (!parse_num(esp, &esa_byte, &esp, ":")) { memcpy(val_ptr, &hold_esa_val, sizeof(enet_addr_t)); return CONFIG_BAD; } ((unsigned char *)val_ptr)[esa_ptr] = esa_byte; } return CONFIG_CHANGED; break;#endif case CONFIG_SCRIPT: // Assume it always changes sp = (unsigned char *)val_ptr; printf("Enter script, terminate with empty line\n"); while (true) { *sp = '\0'; printf(">> "); ret = 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: printf("??"); } return CONFIG_CHANGED;}//// Manage configuration information with the FLASH//// Calculate a simple checksum. This is used to validate configuration// data. Since it is used for sensitive information, it makes sense to// be somewhat careful when accepting it. Also, the [strange] addition// of shifted data helps make this work even if the data layout changes// over time.static unsigned long_fconfig_cksum(unsigned long *buf, int len){ unsigned long cksum = 0; int shift = 0; // Round 'len' up to multiple of longwords len = (len + (sizeof(unsigned long)-1)) / sizeof(unsigned long); while (len-- > 0) { cksum ^= (*buf | (*buf << shift)); buf++; if (++shift == 16) shift = 0; } return cksum;}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;#endif case CONFIG_STRING: return 0; case CONFIG_SCRIPT: return MAX_SCRIPT_LENGTH; }}voiddo_flash_config(int argc, char *argv[]){ int stat, ret; void *cfg_base, *err_addr; bool need_update = false; struct config_option *optbeg = __CONFIG_options_TAB__; struct config_option *optend = __CONFIG_options_TAB_END__; struct config_option *opt = __CONFIG_options_TAB__; struct _config hold_config; int offset = sizeof(unsigned long); struct option_info opts[1]; bool list_only; if (!do_flash_init()) return; memcpy(&hold_config, &config, sizeof(config)); script = (unsigned char *)0; init_opts(&opts[0], 'l', false, OPTION_ARG_TYPE_FLG, (void **)&list_only, (bool *)0, "list configuration only"); if (!scan_opts(argc, argv, 1, opts, 1, 0, 0, "")) { return; } while (opt != optend) { ret = get_config(opt, offset, list_only); switch (ret) { case CONFIG_DONE: goto done; case CONFIG_ABORT: memcpy(&config, &hold_config, sizeof(config)); return; case CONFIG_CHANGED: need_update = true; case CONFIG_OK: offset += config_length(opt->type); opt++; break; case CONFIG_BACK: if (opt != optbeg) opt--; continue; case CONFIG_BAD: // Nothing - make him do it again printf ("** invalid entry\n"); } } done: if (!need_update) return; config.key1 = CONFIG_KEY1; config.key2 = CONFIG_KEY2; config.cksum = _fconfig_cksum((unsigned long *)&config, sizeof(config)-sizeof(config.cksum)); //cfg_base = flash_end_1 - (2*block_size); cfg_base = flash_end - (2*block_size); if (verify_action("Update RedBoot non-volatile configuration")) {#ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL // Insure [quietly] that the config page is unlocked before trying to update flash_unlock((void *)cfg_base, block_size, (void **)&err_addr);#endif if ((stat = flash_erase(cfg_base, block_size, (void **)&err_addr)) != 0) { printf(" initialization failed %p: %x(%s)\n", err_addr, stat, flash_errmsg(stat)); } else { if ((stat = flash_program(cfg_base, (void *)&config, sizeof(config), (void **)&err_addr)) != 0) { printf("Error writing config data at %p: %x(%s)\n", err_addr, stat, 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, block_size, (void **)&err_addr);#endif }}voidflash_get_config(char *key, void *val, int type){ struct config_option *optend = __CONFIG_options_TAB_END__; struct config_option *opt = __CONFIG_options_TAB__; int offset = sizeof(unsigned long); // Offset past starting 'key' void *val_ptr; if (!do_flash_init()) return; while (opt != optend) { val_ptr = (void *)((unsigned char *)&config + offset); if (strcmp(opt->key, key) == 0) { if (opt->type == type) { switch (opt->type) { case CONFIG_BOOL: *(bool *)val = *(bool *)val_ptr; break; case CONFIG_INT: *(unsigned long *)val = *(unsigned long *)val_ptr; 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 case CONFIG_STRING: break; case CONFIG_SCRIPT: // Just return a pointer to the script *(unsigned char **)val = (unsigned char *)val_ptr; break; } } else { printf("Request for config value '%s' - wrong type\n", key); } return; } offset += config_length(opt->type); opt++; } printf("Can't find config value '%s'\n", key);}//// 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){ void *cfg_base; bool use_boot_script; config_ok = false; script = (unsigned char *)0; if (!do_flash_init()) return; //cfg_base = flash_end_1 - (2*block_size); cfg_base = flash_end - (2*block_size); memcpy(&config, cfg_base, sizeof(config)); if ((_fconfig_cksum((unsigned long *)&config, sizeof(config)-sizeof(config.cksum)) != config.cksum) || (config.key1 != CONFIG_KEY1)|| (config.key2 != CONFIG_KEY2)) { printf("FLASH configuration checksum error or invalid key\n"); memset(&config, 0, sizeof(config)); return; } 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); } config_ok = true;}RedBoot_init(load_flash_config, RedBoot_INIT_FIRST);#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -