diff --git a/components/console_simple_init/CMakeLists.txt b/components/console_simple_init/CMakeLists.txt index a6d5a34a6d..b152e9c9b4 100644 --- a/components/console_simple_init/CMakeLists.txt +++ b/components/console_simple_init/CMakeLists.txt @@ -1,3 +1,4 @@ idf_component_register(SRCS "console_simple_init.c" INCLUDE_DIRS "." - PRIV_REQUIRES console) + PRIV_REQUIRES console + LDFRAGMENTS linker.lf) diff --git a/components/console_simple_init/README.md b/components/console_simple_init/README.md index 30d01fedde..ec7522145d 100644 --- a/components/console_simple_init/README.md +++ b/components/console_simple_init/README.md @@ -32,6 +32,28 @@ It also provides an api to register an user provided command. // This allows you to execute the do_user_cmd function when the "user" command is invoked ESP_ERROR_CHECK(console_cmd_user_register("user", do_user_cmd)); + // Register any other plugin command added to your project + ESP_ERROR_CHECK(console_cmd_all_register()); ESP_ERROR_CHECK(console_cmd_start()); // Start console ``` + +### Automatic registration of console commands +The `console_simple_init` component includes a utility function named `console_cmd_all_register()`. This function automates the registration of all commands that are linked into the application. To use this functionality, the application can call `console_cmd_all_register()` as demonstrated above. + +When creating a new component, you can ensure that its commands are registered automatically by placing the registration function into the `.console_cmd_desc` section within the output binary. + +To achieve this, follow these steps: +1. Add the following lines to the main file of the component +``` +static const console_cmd_plugin_desc_t __attribute__((section(".console_cmd_desc"), used)) PLUGIN = { + .name = "cmd_name_string", + .plugin_regd_fn = &cmd_registration_function +};̌ +``` +2. Add the `WHOLE_ARCHIVE` flag to CMakeLists.txt of the component. + + +For more details refer: +* [IDF Component Manager](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-component-manager.html) +* [Linker Script Generation](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/linker-script-generation.html) diff --git a/components/console_simple_init/console_simple_init.c b/components/console_simple_init/console_simple_init.c index 3d95638172..b1eb29a7a8 100644 --- a/components/console_simple_init/console_simple_init.c +++ b/components/console_simple_init/console_simple_init.c @@ -8,13 +8,13 @@ #include "esp_log.h" #include "console_simple_init.h" + static esp_console_repl_t *repl = NULL; static const char *TAG = "console_simple_init"; /** * @brief Initializes the esp console - * @return - * - esp_err_t + * @return ESP_OK on success */ esp_err_t console_cmd_init(void) { @@ -40,13 +40,12 @@ esp_err_t console_cmd_init(void) } /** - * @brief Initialize Ethernet driver based on Espressif IoT Development Framework Configuration + * @brief Register a user supplied command * * @param[in] cmd string that is the user defined command * @param[in] do_user_cmd Function pointer for a user-defined command callback function * - * @return - * - esp_err_t + * @return ESP_OK on success */ esp_err_t console_cmd_user_register(char *cmd, esp_console_cmd_func_t do_user_cmd) { @@ -67,10 +66,36 @@ esp_err_t console_cmd_user_register(char *cmd, esp_console_cmd_func_t do_user_cm return ret; } + +/** + * @brief Register all the console commands in .console_cmd_desc section + * + * @return ESP_OK on success + */ +esp_err_t console_cmd_all_register(void) +{ + esp_err_t ret = ESP_FAIL; + extern const console_cmd_plugin_desc_t _console_cmd_array_start; + extern const console_cmd_plugin_desc_t _console_cmd_array_end; + + ESP_LOGI(TAG, "List of Console commands:\n"); + for (const console_cmd_plugin_desc_t *it = &_console_cmd_array_start; it != &_console_cmd_array_end; ++it) { + ESP_LOGI(TAG, "- Command '%s', function plugin_regd_fn=%p\n", it->name, it->plugin_regd_fn); + if (it->plugin_regd_fn != NULL) { + ret = (it->plugin_regd_fn)(); + if (ret != ESP_OK) { + return ret; + } + } + } + + return ESP_OK; +} + + /** * @brief Starts the esp console - * @return - * - esp_err_t + * @return ESP_OK on success */ esp_err_t console_cmd_start(void) { diff --git a/components/console_simple_init/console_simple_init.h b/components/console_simple_init/console_simple_init.h index 8084be2c0e..c06c028f1b 100644 --- a/components/console_simple_init/console_simple_init.h +++ b/components/console_simple_init/console_simple_init.h @@ -13,28 +13,46 @@ extern "C" { #endif + +/* This stucture describes the plugin to the rest of the application */ +typedef struct { + /* A pointer to the name of the command */ + const char *name; + + /* A function which performs auto-registration of console commands */ + esp_err_t (*plugin_regd_fn)(void); +} console_cmd_plugin_desc_t; + + /** * @brief Initializes the esp console - * @return - * - esp_err_t + * @return ESP_OK on success */ esp_err_t console_cmd_init(void); + /** - * @brief Initialize Ethernet driver based on Espressif IoT Development Framework Configuration + * @brief Register a user supplied command * * @param[in] cmd string that is the user defined command * @param[in] do_user_cmd Function pointer for a user-defined command callback function * - * @return - * - esp_err_t + * @return ESP_OK on success */ esp_err_t console_cmd_user_register(char *user_cmd, esp_console_cmd_func_t do_user_cmd); + +/** + * @brief Register all the console commands in .console_cmd_desc section + * + * @return ESP_OK on success + */ +esp_err_t console_cmd_all_register(void); + + /** * @brief Starts the esp console - * @return - * - esp_err_t + * @return ESP_OK on success */ esp_err_t console_cmd_start(void); diff --git a/components/console_simple_init/examples/console_basic/main/console_basic.c b/components/console_simple_init/examples/console_basic/main/console_basic.c index ffe962dab6..c2c28b8daf 100644 --- a/components/console_simple_init/examples/console_basic/main/console_basic.c +++ b/components/console_simple_init/examples/console_basic/main/console_basic.c @@ -30,6 +30,9 @@ void app_main(void) // Register user command ESP_ERROR_CHECK(console_cmd_user_register("user", do_user_cmd)); + // Register all the plugin commands added to this example + ESP_ERROR_CHECK(console_cmd_all_register()); + // start console REPL ESP_ERROR_CHECK(console_cmd_start()); diff --git a/components/console_simple_init/examples/console_basic/main/idf_component.yml b/components/console_simple_init/examples/console_basic/main/idf_component.yml index a6027e49e6..a3d59b813f 100644 --- a/components/console_simple_init/examples/console_basic/main/idf_component.yml +++ b/components/console_simple_init/examples/console_basic/main/idf_component.yml @@ -1,6 +1,6 @@ dependencies: idf: - version: '*' + version: ">=5.0" console_simple_init: version: "*" override_path: '../../../' diff --git a/components/console_simple_init/linker.lf b/components/console_simple_init/linker.lf new file mode 100644 index 0000000000..3a6ff2496e --- /dev/null +++ b/components/console_simple_init/linker.lf @@ -0,0 +1,13 @@ +[sections:console_cmd_desc] +entries: + .console_cmd_desc + +[scheme:console_cmd_desc_default] +entries: + console_cmd_desc -> flash_rodata + +[mapping:console_cmd_desc] +archive: * +entries: + * (console_cmd_desc_default); + console_cmd_desc -> flash_rodata KEEP() SORT(name) SURROUND(console_cmd_array)