cmd_nvs.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611
  1. /* Console example — NVS commands
  2. This example code is in the Public Domain (or CC0 licensed, at your option.)
  3. Unless required by applicable law or agreed to in writing, this
  4. software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  5. CONDITIONS OF ANY KIND, either express or implied.
  6. */
  7. #ifdef __cplusplus
  8. extern "C" {
  9. #endif
  10. #include "nvs_flash.h"
  11. #include <stdio.h>
  12. #include <errno.h>
  13. #include <string.h>
  14. #include <stdlib.h>
  15. #include <inttypes.h>
  16. #include "esp_log.h"
  17. #include "esp_console.h"
  18. #include "argtable3/argtable3.h"
  19. #include "freertos/FreeRTOS.h"
  20. #include "freertos/event_groups.h"
  21. #include "esp_err.h"
  22. #include "cmd_nvs.h"
  23. #include "nvs.h"
  24. #include "nvs_utilities.h"
  25. #include "platform_console.h"
  26. #include "messaging.h"
  27. #include "tools.h"
  28. #include "trace.h"
  29. extern esp_err_t network_wifi_erase_legacy();
  30. extern esp_err_t network_wifi_erase_known_ap();
  31. static const char *ARG_TYPE_STR = "type can be: i8, u8, i16, u16 i32, u32 i64, u64, str, blob";
  32. static const char * TAG = "cmd_nvs";
  33. EXT_RAM_ATTR static struct {
  34. struct arg_str *key;
  35. struct arg_str *type;
  36. struct arg_str *value;
  37. struct arg_end *end;
  38. } set_args;
  39. EXT_RAM_ATTR static struct {
  40. struct arg_str *key;
  41. struct arg_str *type;
  42. struct arg_end *end;
  43. } get_args;
  44. EXT_RAM_ATTR static struct {
  45. struct arg_str *key;
  46. struct arg_end *end;
  47. } erase_args;
  48. EXT_RAM_ATTR static struct {
  49. struct arg_str *namespace;
  50. struct arg_end *end;
  51. } erase_all_args;
  52. EXT_RAM_ATTR static struct {
  53. struct arg_str *partition;
  54. struct arg_str *namespace;
  55. struct arg_str *type;
  56. struct arg_end *end;
  57. } list_args;
  58. EXT_RAM_ATTR static struct {
  59. struct arg_lit *legacy;
  60. struct arg_lit *ap_list;
  61. struct arg_end *end;
  62. } wifi_erase_args;
  63. static esp_err_t store_blob(nvs_handle nvs, const char *key, const char *str_values)
  64. {
  65. uint8_t value;
  66. size_t str_len = strlen(str_values);
  67. size_t blob_len = str_len / 2;
  68. if (str_len % 2) {
  69. log_send_messaging(MESSAGING_ERROR, "Blob data must contain even number of characters");
  70. return ESP_ERR_NVS_TYPE_MISMATCH;
  71. }
  72. char *blob = (char *)malloc_init_external(blob_len);
  73. if (blob == NULL) {
  74. return ESP_ERR_NO_MEM;
  75. }
  76. for (int i = 0, j = 0; i < str_len; i++) {
  77. char ch = str_values[i];
  78. if (ch >= '0' && ch <= '9') {
  79. value = ch - '0';
  80. } else if (ch >= 'A' && ch <= 'F') {
  81. value = ch - 'A' + 10;
  82. } else if (ch >= 'a' && ch <= 'f') {
  83. value = ch - 'a' + 10;
  84. } else {
  85. log_send_messaging(MESSAGING_ERROR, "Blob data contain invalid character");
  86. free(blob);
  87. return ESP_ERR_NVS_TYPE_MISMATCH;
  88. }
  89. if (i & 1) {
  90. blob[j++] += value;
  91. } else {
  92. blob[j] = value << 4;
  93. }
  94. }
  95. esp_err_t err = nvs_set_blob(nvs, key, blob, blob_len);
  96. free(blob);
  97. if (err == ESP_OK) {
  98. err = nvs_commit(nvs);
  99. }
  100. return err;
  101. }
  102. static esp_err_t set_value_in_nvs(const char *key, const char *str_type, const char *str_value)
  103. {
  104. esp_err_t err;
  105. nvs_handle nvs;
  106. bool range_error = false;
  107. nvs_type_t type = str_to_type(str_type);
  108. if (type == NVS_TYPE_ANY) {
  109. return ESP_ERR_NVS_TYPE_MISMATCH;
  110. }
  111. err = nvs_open_from_partition(settings_partition, current_namespace, NVS_READWRITE, &nvs);
  112. if (err != ESP_OK) {
  113. return err;
  114. }
  115. if (type == NVS_TYPE_I8) {
  116. int32_t value = strtol(str_value, NULL, 0);
  117. if (value < INT8_MIN || value > INT8_MAX || errno == ERANGE) {
  118. range_error = true;
  119. } else {
  120. err = nvs_set_i8(nvs, key, (int8_t)value);
  121. }
  122. } else if (type == NVS_TYPE_U8) {
  123. uint32_t value = strtoul(str_value, NULL, 0);
  124. if (value > UINT8_MAX || errno == ERANGE) {
  125. range_error = true;
  126. } else {
  127. err = nvs_set_u8(nvs, key, (uint8_t)value);
  128. }
  129. } else if (type == NVS_TYPE_I16) {
  130. int32_t value = strtol(str_value, NULL, 0);
  131. if (value < INT16_MIN || value > INT16_MAX || errno == ERANGE) {
  132. range_error = true;
  133. } else {
  134. err = nvs_set_i16(nvs, key, (int16_t)value);
  135. }
  136. } else if (type == NVS_TYPE_U16) {
  137. uint32_t value = strtoul(str_value, NULL, 0);
  138. if (value > UINT16_MAX || errno == ERANGE) {
  139. range_error = true;
  140. } else {
  141. err = nvs_set_u16(nvs, key, (uint16_t)value);
  142. }
  143. } else if (type == NVS_TYPE_I32) {
  144. int32_t value = strtol(str_value, NULL, 0);
  145. if (errno != ERANGE) {
  146. err = nvs_set_i32(nvs, key, value);
  147. }
  148. } else if (type == NVS_TYPE_U32) {
  149. uint32_t value = strtoul(str_value, NULL, 0);
  150. if (errno != ERANGE) {
  151. err = nvs_set_u32(nvs, key, value);
  152. }
  153. } else if (type == NVS_TYPE_I64) {
  154. int64_t value = strtoll(str_value, NULL, 0);
  155. if (errno != ERANGE) {
  156. err = nvs_set_i64(nvs, key, value);
  157. }
  158. } else if (type == NVS_TYPE_U64) {
  159. uint64_t value = strtoull(str_value, NULL, 0);
  160. if (errno != ERANGE) {
  161. err = nvs_set_u64(nvs, key, value);
  162. }
  163. } else if (type == NVS_TYPE_STR) {
  164. err = nvs_set_str(nvs, key, str_value);
  165. } else if (type == NVS_TYPE_BLOB) {
  166. err = store_blob(nvs, key, str_value);
  167. }
  168. if (range_error || errno == ERANGE) {
  169. nvs_close(nvs);
  170. return ESP_ERR_NVS_VALUE_TOO_LONG;
  171. }
  172. if (err == ESP_OK) {
  173. log_send_messaging(MESSAGING_INFO, "Set value ok. Committing '%s'", key);
  174. err = nvs_commit(nvs);
  175. if (err == ESP_OK) {
  176. log_send_messaging(MESSAGING_INFO, "Value stored under key '%s'", key);
  177. }
  178. }
  179. nvs_close(nvs);
  180. return err;
  181. }
  182. static esp_err_t get_value_from_nvs(const char *key, const char *str_type)
  183. {
  184. nvs_handle nvs;
  185. esp_err_t err;
  186. nvs_type_t type = str_to_type(str_type);
  187. if (type == NVS_TYPE_ANY) {
  188. return ESP_ERR_NVS_TYPE_MISMATCH;
  189. }
  190. err = nvs_open_from_partition(settings_partition, current_namespace, NVS_READWRITE, &nvs);
  191. if (err != ESP_OK) {
  192. return err;
  193. }
  194. if (type == NVS_TYPE_I8) {
  195. int8_t value;
  196. err = nvs_get_i8(nvs, key, &value);
  197. if (err == ESP_OK) {
  198. log_send_messaging(MESSAGING_INFO,"Value associated with key '%s' is %d \n", key, value);
  199. }
  200. } else if (type == NVS_TYPE_U8) {
  201. uint8_t value;
  202. err = nvs_get_u8(nvs, key, &value);
  203. if (err == ESP_OK) {
  204. log_send_messaging(MESSAGING_INFO,"Value associated with key '%s' is %u \n", key, value);
  205. }
  206. } else if (type == NVS_TYPE_I16) {
  207. int16_t value;
  208. err = nvs_get_i16(nvs, key, &value);
  209. if (err == ESP_OK) {
  210. log_send_messaging(MESSAGING_INFO,"Value associated with key '%s' is %d \n", key, value);
  211. }
  212. } else if (type == NVS_TYPE_U16) {
  213. uint16_t value;
  214. if ((err = nvs_get_u16(nvs, key, &value)) == ESP_OK) {
  215. log_send_messaging(MESSAGING_INFO,"Value associated with key '%s' is %u", key, value);
  216. }
  217. } else if (type == NVS_TYPE_I32) {
  218. int32_t value;
  219. if ((err = nvs_get_i32(nvs, key, &value)) == ESP_OK) {
  220. log_send_messaging(MESSAGING_INFO,"Value associated with key '%s' is %d \n", key, value);
  221. }
  222. } else if (type == NVS_TYPE_U32) {
  223. uint32_t value;
  224. if ((err = nvs_get_u32(nvs, key, &value)) == ESP_OK) {
  225. log_send_messaging(MESSAGING_INFO,"Value associated with key '%s' is %u \n", key, value);
  226. }
  227. } else if (type == NVS_TYPE_I64) {
  228. int64_t value;
  229. if ((err = nvs_get_i64(nvs, key, &value)) == ESP_OK) {
  230. log_send_messaging(MESSAGING_INFO,"Value associated with key '%s' is %lld \n", key, value);
  231. }
  232. } else if (type == NVS_TYPE_U64) {
  233. uint64_t value;
  234. if ( (err = nvs_get_u64(nvs, key, &value)) == ESP_OK) {
  235. log_send_messaging(MESSAGING_INFO,"Value associated with key '%s' is %llu \n", key, value);
  236. }
  237. } else if (type == NVS_TYPE_STR) {
  238. size_t len=0;
  239. if ( (err = nvs_get_str(nvs, key, NULL, &len)) == ESP_OK) {
  240. char *str = (char *)malloc_init_external(len);
  241. if ( (err = nvs_get_str(nvs, key, str, &len)) == ESP_OK) {
  242. log_send_messaging(MESSAGING_INFO,"String associated with key '%s' is %s \n", key, str);
  243. }
  244. free(str);
  245. }
  246. } else if (type == NVS_TYPE_BLOB) {
  247. size_t len;
  248. if ( (err = nvs_get_blob(nvs, key, NULL, &len)) == ESP_OK) {
  249. char *blob = (char *)malloc_init_external(len);
  250. if ( (err = nvs_get_blob(nvs, key, blob, &len)) == ESP_OK) {
  251. log_send_messaging(MESSAGING_INFO,"Blob associated with key '%s' is %d bytes long: \n", key, len);
  252. print_blob(blob, len);
  253. }
  254. free(blob);
  255. }
  256. }
  257. nvs_close(nvs);
  258. return err;
  259. }
  260. static esp_err_t erase(const char *key)
  261. {
  262. nvs_handle nvs;
  263. esp_err_t err = nvs_open_from_partition(settings_partition, current_namespace, NVS_READWRITE, &nvs);
  264. if (err == ESP_OK) {
  265. err = nvs_erase_key(nvs, key);
  266. if (err == ESP_OK) {
  267. err = nvs_commit(nvs);
  268. if (err == ESP_OK) {
  269. log_send_messaging(MESSAGING_INFO, "Value with key '%s' erased", key);
  270. }
  271. }
  272. nvs_close(nvs);
  273. }
  274. return err;
  275. }
  276. static esp_err_t erase_all(const char *name)
  277. {
  278. nvs_handle nvs;
  279. esp_err_t err = nvs_open_from_partition(settings_partition, current_namespace, NVS_READWRITE, &nvs);
  280. if (err == ESP_OK) {
  281. err = nvs_erase_all(nvs);
  282. if (err == ESP_OK) {
  283. err = nvs_commit(nvs);
  284. }
  285. }
  286. log_send_messaging(MESSAGING_INFO, "Namespace '%s' was %s erased", name, (err == ESP_OK) ? "" : "not");
  287. nvs_close(nvs);
  288. return ESP_OK;
  289. }
  290. static int set_value(int argc, char **argv)
  291. {
  292. ESP_LOGD(TAG, "%s %u - Parsing keys ",__func__,__LINE__);
  293. int nerrors = arg_parse_msg(argc, argv,(struct arg_hdr **)&set_args);
  294. if (nerrors != 0) {
  295. return 1;
  296. }
  297. const char *key = set_args.key->sval[0];
  298. const char *type = set_args.type->sval[0];
  299. const char *values = set_args.value->sval[0];
  300. cmd_send_messaging(argv[0],MESSAGING_INFO, "Setting '%s' (type %s)", key,type);
  301. esp_err_t err = set_value_in_nvs(key, type, values);
  302. if (err != ESP_OK) {
  303. cmd_send_messaging(argv[0],MESSAGING_ERROR, "%s", esp_err_to_name(err));
  304. return 1;
  305. }
  306. return 0;
  307. }
  308. static int get_value(int argc, char **argv)
  309. {
  310. int nerrors = arg_parse_msg(argc, argv,(struct arg_hdr **)&get_args);
  311. if (nerrors != 0) {
  312. return 1;
  313. }
  314. const char *key = get_args.key->sval[0];
  315. const char *type = get_args.type->sval[0];
  316. esp_err_t err = get_value_from_nvs(key, type);
  317. if (err != ESP_OK) {
  318. cmd_send_messaging(argv[0],MESSAGING_ERROR, "%s", esp_err_to_name(err));
  319. return 1;
  320. }
  321. return 0;
  322. }
  323. static int erase_value(int argc, char **argv)
  324. {
  325. int nerrors = arg_parse_msg(argc, argv,(struct arg_hdr **)&erase_args);
  326. if (nerrors != 0) {
  327. return 1;
  328. }
  329. const char *key = erase_args.key->sval[0];
  330. esp_err_t err = erase(key);
  331. if (err != ESP_OK) {
  332. cmd_send_messaging(argv[0],MESSAGING_ERROR, "%s", esp_err_to_name(err));
  333. return 1;
  334. }
  335. return 0;
  336. }
  337. static int erase_namespace(int argc, char **argv)
  338. {
  339. int nerrors = arg_parse_msg(argc, argv,(struct arg_hdr **)&erase_all_args);
  340. if (nerrors != 0) {
  341. return 1;
  342. }
  343. const char *name = erase_all_args.namespace->sval[0];
  344. esp_err_t err = erase_all(name);
  345. if (err != ESP_OK) {
  346. cmd_send_messaging(argv[0],MESSAGING_ERROR, "%s", esp_err_to_name(err));
  347. return 1;
  348. }
  349. return 0;
  350. }
  351. static int erase_network_manager(int argc, char **argv)
  352. {
  353. nvs_handle nvs;
  354. esp_err_t err = nvs_open("config", NVS_READWRITE, &nvs);
  355. if (err == ESP_OK) {
  356. err = nvs_erase_all(nvs);
  357. if (err == ESP_OK) {
  358. err = nvs_commit(nvs);
  359. }
  360. }
  361. nvs_close(nvs);
  362. if (err != ESP_OK) {
  363. cmd_send_messaging(argv[0],MESSAGING_ERROR, "System configuration was not erased. %s", esp_err_to_name(err));
  364. return 1;
  365. }
  366. else {
  367. cmd_send_messaging(argv[0],MESSAGING_WARNING, "system configuration was erased. Please reboot.");
  368. }
  369. return 0;
  370. }
  371. static int wifi_erase_config(int argc, char **argv)
  372. {
  373. esp_err_t err=ESP_OK;
  374. esp_err_t err_ap_list=ESP_OK;
  375. bool done = false;
  376. int nerrors = arg_parse_msg(argc, argv,(struct arg_hdr **)&wifi_erase_args);
  377. if (nerrors != 0) {
  378. return 1;
  379. }
  380. if(wifi_erase_args.ap_list->count>0){
  381. err_ap_list = network_wifi_erase_known_ap();
  382. if (err_ap_list != ESP_OK) {
  383. cmd_send_messaging(argv[0],MESSAGING_ERROR, "Could not erase legacy wifi configuration: %s", esp_err_to_name(err));
  384. }
  385. else {
  386. cmd_send_messaging(argv[0],MESSAGING_ERROR, "Legacy wifi configuration was erased");
  387. }
  388. done = true;
  389. }
  390. if(wifi_erase_args.legacy->count>0){
  391. err = network_wifi_erase_legacy();
  392. if (err != ESP_OK) {
  393. cmd_send_messaging(argv[0],MESSAGING_ERROR, "Could not erase known ap list : %s", esp_err_to_name(err));
  394. }
  395. else {
  396. cmd_send_messaging(argv[0],MESSAGING_ERROR, "Known access point list was erased");
  397. }
  398. done = true;
  399. }
  400. if(!done){
  401. cmd_send_messaging(argv[0],MESSAGING_WARNING, "Please specify at least one configuration type to erase.", esp_err_to_name(err));
  402. }
  403. return (err_ap_list==ESP_OK && err==ESP_OK)?0:1;
  404. }
  405. static int list(const char *part, const char *name, const char *str_type)
  406. {
  407. nvs_type_t type = str_to_type(str_type);
  408. nvs_iterator_t it = nvs_entry_find(part, NULL, type);
  409. if (it == NULL) {
  410. log_send_messaging(MESSAGING_ERROR, "No such enty was found");
  411. return 1;
  412. }
  413. do {
  414. nvs_entry_info_t info;
  415. nvs_entry_info(it, &info);
  416. it = nvs_entry_next(it);
  417. log_send_messaging(MESSAGING_INFO, "namespace '%s', key '%s', type '%s' \n",
  418. info.namespace_name, info.key, type_to_str(info.type));
  419. } while (it != NULL);
  420. return 0;
  421. }
  422. static int list_entries(int argc, char **argv)
  423. {
  424. list_args.partition->sval[0] = "";
  425. list_args.namespace->sval[0] = "";
  426. list_args.type->sval[0] = "";
  427. int nerrors = arg_parse_msg(argc, argv,(struct arg_hdr **)&list_args);
  428. if (nerrors != 0) {
  429. return 1;
  430. }
  431. const char *part = list_args.partition->sval[0];
  432. const char *name = list_args.namespace->sval[0];
  433. const char *type = list_args.type->sval[0];
  434. return list(part, name, type);
  435. }
  436. void register_nvs()
  437. {
  438. set_args.key = arg_str1(NULL, NULL, "<key>", "key of the value to be set");
  439. set_args.type = arg_str1(NULL, NULL, "<type>", ARG_TYPE_STR);
  440. set_args.value = arg_str1("v", "value", "<value>", "value to be stored");
  441. set_args.end = arg_end(2);
  442. get_args.key = arg_str1(NULL, NULL, "<key>", "key of the value to be read");
  443. get_args.type = arg_str1(NULL, NULL, "<type>", ARG_TYPE_STR);
  444. get_args.end = arg_end(2);
  445. erase_args.key = arg_str1(NULL, NULL, "<key>", "key of the value to be erased");
  446. erase_args.end = arg_end(2);
  447. erase_all_args.namespace = arg_str1(NULL, NULL, "<namespace>", "namespace to be erased");
  448. erase_all_args.end = arg_end(2);
  449. wifi_erase_args.ap_list = arg_lit0("a","ap_list","Erases Known access points list");
  450. wifi_erase_args.legacy = arg_lit0("l","legacy","Erases legacy access point storage");
  451. wifi_erase_args.end = arg_end(1);
  452. list_args.partition = arg_str1(NULL, NULL, "<partition>", "partition name");
  453. list_args.namespace = arg_str0("n", "namespace", "<namespace>", "namespace name");
  454. list_args.type = arg_str0("t", "type", "<type>", ARG_TYPE_STR);
  455. list_args.end = arg_end(2);
  456. const esp_console_cmd_t set_cmd = {
  457. .command = "nvs_set",
  458. .help = "Set variable in selected namespace. Blob type must be comma separated list of hex values. \n"
  459. "Examples:\n"
  460. " nvs_set VarName i32 -v 123 \n"
  461. " nvs_set VarName srt -v YourString \n"
  462. " nvs_set VarName blob -v 0123456789abcdef \n",
  463. .hint = NULL,
  464. .func = &set_value,
  465. .argtable = &set_args
  466. };
  467. const esp_console_cmd_t get_cmd = {
  468. .command = "nvs_get",
  469. .help = "Get variable from selected namespace. \n"
  470. "Example: nvs_get VarName i32",
  471. .hint = NULL,
  472. .func = &get_value,
  473. .argtable = &get_args
  474. };
  475. const esp_console_cmd_t erase_cmd = {
  476. .command = "nvs_erase",
  477. .help = "Erase variable from current namespace",
  478. .hint = NULL,
  479. .func = &erase_value,
  480. .argtable = &erase_args
  481. };
  482. const esp_console_cmd_t erase_namespace_cmd = {
  483. .command = "nvs_erase_namespace",
  484. .help = "Erases specified namespace",
  485. .hint = NULL,
  486. .func = &erase_namespace,
  487. .argtable = &erase_all_args
  488. };
  489. const esp_console_cmd_t erase_config_cmd = {
  490. .command = "wifi_erase_config",
  491. .help = "Erases all stored access points from flash",
  492. .hint = NULL,
  493. .func = &wifi_erase_config,
  494. .argtable = &wifi_erase_args
  495. };
  496. const esp_console_cmd_t erase_networkmanager_cmd = {
  497. .command = "nvs_erase_configuration",
  498. .help = "Erases system's configuration",
  499. .hint = NULL,
  500. .func = &erase_network_manager,
  501. .argtable = NULL
  502. };
  503. const esp_console_cmd_t list_entries_cmd = {
  504. .command = "nvs_list",
  505. .help = "List stored key-value pairs stored in NVS."
  506. "Namespace and type can be specified to print only those key-value pairs.\n"
  507. "Following command list variables stored inside 'nvs' partition, under namespace 'storage' with type uint32_t"
  508. "Example: nvs_list nvs -n storage -t u32 \n",
  509. .hint = NULL,
  510. .func = &list_entries,
  511. .argtable = &list_args
  512. };
  513. MEMTRACE_PRINT_DELTA_MESSAGE("registering list_entries_cmd");
  514. ESP_ERROR_CHECK(esp_console_cmd_register(&list_entries_cmd));
  515. MEMTRACE_PRINT_DELTA_MESSAGE("registering set_cmd");
  516. ESP_ERROR_CHECK(esp_console_cmd_register(&set_cmd));
  517. MEMTRACE_PRINT_DELTA_MESSAGE("registering get_cmd");
  518. ESP_ERROR_CHECK(esp_console_cmd_register(&get_cmd));
  519. MEMTRACE_PRINT_DELTA_MESSAGE("registering erase_cmd");
  520. ESP_ERROR_CHECK(esp_console_cmd_register(&erase_cmd));
  521. MEMTRACE_PRINT_DELTA_MESSAGE("registering erase_namespace_cmd");
  522. ESP_ERROR_CHECK(esp_console_cmd_register(&erase_namespace_cmd));
  523. MEMTRACE_PRINT_DELTA_MESSAGE("registering erase_config_cmd");
  524. ESP_ERROR_CHECK(esp_console_cmd_register(&erase_networkmanager_cmd));
  525. MEMTRACE_PRINT_DELTA_MESSAGE("registering erase_config_cmd");
  526. ESP_ERROR_CHECK(esp_console_cmd_register(&erase_config_cmd));
  527. MEMTRACE_PRINT_DELTA_MESSAGE("Done");
  528. }
  529. #ifdef __cplusplus
  530. extern }
  531. #endif