Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(console): Added runtime component registration support in console_simple_init #402

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion components/console_simple_init/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
idf_component_register(SRCS "console_simple_init.c"
INCLUDE_DIRS "."
PRIV_REQUIRES console)
PRIV_REQUIRES console
LDFRAGMENTS linker.lf)
22 changes: 22 additions & 0 deletions components/console_simple_init/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this potentially links more object files than necessary. We only need to ensure that the component registration callback is linked, but the component may also contain other object files. Following the "user shouldn't pay for what they don't use" principle I think we could try to have a more light-weight solution.

This is probably not a blocker for this PR specifically, we can always update the documentation later. But for other console components you create we might need to revise the WHOLE_ARCHIVE approach. (Also, not a blocker for releasing the first versions.)



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)
39 changes: 32 additions & 7 deletions components/console_simple_init/console_simple_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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)
{
Expand All @@ -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)
{
Expand Down
32 changes: 25 additions & 7 deletions components/console_simple_init/console_simple_init.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
espressif-abhikroy marked this conversation as resolved.
Show resolved Hide resolved


/**
* @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);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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());

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
dependencies:
idf:
version: '*'
version: ">=5.0"
console_simple_init:
version: "*"
override_path: '../../../'
13 changes: 13 additions & 0 deletions components/console_simple_init/linker.lf
Original file line number Diff line number Diff line change
@@ -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)