Skip to content

Commit db1c4ce

Browse files
committed
feat(esp_commands): Add tests to the esp_commands component
1 parent 2ec41d0 commit db1c4ce

File tree

10 files changed

+755
-1
lines changed

10 files changed

+755
-1
lines changed

esp_commands/README.md

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
# ESP Commands
2+
3+
The `esp_commands` component provides a flexible command registration and execution framework for ESP-IDF applications.
4+
It allows applications to define console-like commands with metadata (help text, hints, glossary entries) and register them dynamically or statically.
5+
6+
---
7+
8+
## Features
9+
10+
- Define commands with:
11+
- Command name
12+
- Group categorization
13+
- Help text
14+
- Optional hints and glossary callbacks
15+
- Register commands at runtime or at compile-time (via section placement macros).
16+
- Execute commands from command line strings.
17+
- Provide command completion, hints, and glossary callback registration mechanism.
18+
- Create and manage subsets of commands (command sets).
19+
- Customizable configuration for command parsing and hint display.
20+
21+
---
22+
23+
## Configuration
24+
25+
The component is initialized with a configuration struct:
26+
27+
```c
28+
esp_commands_config_t config = ESP_COMMANDS_CONFIG_DEFAULT();
29+
esp_commands_update_config(&config);
30+
```
31+
32+
- `max_cmdline_length`: Maximum command line buffer length (bytes).
33+
- `max_cmdline_args`: Maximum number of arguments parsed.
34+
- `hint_color`: ANSI color code used for hints.
35+
- `hint_bold`: Whether hints are displayed in bold.
36+
37+
---
38+
39+
## Defining Commands
40+
41+
### Command Structure
42+
43+
A command is described by the `esp_command_t` struct:
44+
45+
```c
46+
typedef struct esp_command {
47+
const char *name; /*!< Command name */
48+
const char *group; /*!< Group/category */
49+
const char *help; /*!< Short help text */
50+
esp_command_func_t func; /*!< Command implementation */
51+
void *func_ctx; /*!< User context */
52+
esp_command_hint_t hint_cb; /*!< Hint callback */
53+
esp_command_glossary_t glossary_cb; /*!< Glossary callback */
54+
} esp_command_t;
55+
```
56+
57+
### Static Registration
58+
59+
Use the `ESP_COMMAND_REGISTER` macro to register a command at compile time:
60+
61+
```c
62+
static int my_cmd(void *ctx, int argc, char **argv) {
63+
printf("Hello from my_cmd!\n");
64+
return 0;
65+
}
66+
67+
ESP_COMMAND_REGISTER(my_cmd, tools, "Prints hello", my_cmd, NULL, NULL, NULL);
68+
```
69+
70+
This places the command into the `.esp_commands` section.
71+
72+
### Dynamic Registration
73+
74+
Commands can also be registered/unregistered at runtime:
75+
76+
```c
77+
esp_command_t cmd = {
78+
.name = "echo",
79+
.group = "utils",
80+
.help = "Echoes arguments back",
81+
.func = echo_func,
82+
};
83+
84+
esp_commands_register_cmd(&cmd);
85+
esp_commands_unregister_cmd("echo");
86+
```
87+
88+
---
89+
90+
## Executing Commands
91+
92+
Commands can be executed from a command line string:
93+
94+
```c
95+
int cmd_ret;
96+
esp_err_t ret = esp_commands_execute(NULL, "my_cmd arg1 arg2", &cmd_ret);
97+
```
98+
99+
- `cmd_set`: Limits execution to a set of commands (or `NULL` for all commands).
100+
- `cmd_line`: String containing the command and arguments.
101+
- `cmd_ret`: Receives the command function return value.
102+
103+
---
104+
105+
## Command Completion, Hints, and Glossary
106+
107+
Completion & Help APIs:
108+
109+
```c
110+
esp_commands_get_completion(NULL, "ec", completion_cb);
111+
const char *hint = esp_commands_get_hint(NULL, "echo", &color, &bold);
112+
const char *glossary = esp_commands_get_glossary(NULL, "echo");
113+
```
114+
115+
- **Completion**: Suggests matching commands.
116+
- **Hint**: Provides a short usage hint.
117+
- **Glossary**: Provides detailed command description.
118+
119+
---
120+
121+
## Command Sets
122+
123+
Command sets allow grouping subsets of commands for filtering:
124+
125+
```c
126+
const char *cmd_names[] = {"echo", "my_cmd"};
127+
esp_command_set_handle_t set =
128+
ESP_COMMANDS_CREATE_CMD_SET(cmd_names, FIELD_ACCESSOR(name));
129+
130+
esp_commands_execute(set, "echo Hello!", NULL);
131+
esp_commands_destroy_cmd_set(&set);
132+
```
133+
134+
- Create sets by name, group, or other fields.
135+
- Concatenate sets with `esp_commands_concat_cmd_set()`.
136+
- Destroy sets when no longer needed.
137+
138+
---
139+
140+
## Quick Start Example
141+
142+
```c
143+
#include <stdio.h>
144+
#include "esp_commands.h"
145+
146+
// Example command function
147+
static int hello_cmd(void *ctx, int argc, char **argv) {
148+
printf("Hello, ESP Commands!\n");
149+
return 0;
150+
}
151+
152+
// Register command statically
153+
ESP_COMMAND_REGISTER(hello_cmd, demo, "Prints a hello message", hello_cmd, NULL, NULL, NULL);
154+
155+
void app_main(void) {
156+
// Update configuration (optional)
157+
esp_commands_config_t config = ESP_COMMANDS_CONFIG_DEFAULT();
158+
esp_commands_update_config(&config);
159+
160+
// Execute command
161+
int ret_val;
162+
esp_err_t ret = esp_commands_execute(NULL, "hello_cmd", &ret_val);
163+
if (ret == ESP_OK) {
164+
printf("Command executed successfully, return value: %d\n", ret_val);
165+
} else {
166+
printf("Failed to execute command, error: %d\n", ret);
167+
}
168+
}
169+
```
170+
171+
---
172+
173+
## API Reference
174+
175+
- **Configuration**: `esp_commands_update_config()`
176+
- **Registration**: `esp_commands_register_cmd()`, `esp_commands_unregister_cmd()`
177+
- **Execution**: `esp_commands_execute()`, `esp_commands_find_command()`
178+
- **Completion & Help APIs**: `esp_commands_get_completion()`, `esp_commands_get_hint()`, `esp_commands_get_glossary()`
179+
- **Command Sets**: `esp_commands_create_cmd_set()`, `esp_commands_concat_cmd_set()`, `esp_commands_destroy_cmd_set()`
180+
181+
---

esp_commands/include/esp_commands.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ esp_err_t esp_commands_execute(esp_command_set_handle_t cmd_set, const char *cmd
223223
*
224224
* @param cmd_set Handle to the command set to search in. Must be a valid
225225
* `esp_command_set_handle_t` or `NULL` if the search should be performed
226-
* on all statically adn dynamically registered commands.
226+
* on all statically and dynamically registered commands.
227227
* @param name String containing the name of the command to search for.
228228
*
229229
* @return pointer to the matching command or NULL if no command is found.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
cmake_minimum_required(VERSION 3.16)
2+
3+
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
4+
set(COMPONENTS main)
5+
project(esp_commands_test)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
idf_component_register(SRCS "test_esp_commands.c" "test_main.c"
2+
PRIV_INCLUDE_DIRS "." "include"
3+
PRIV_REQUIRES unity
4+
WHOLE_ARCHIVE)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
dependencies:
2+
espressif/esp_commands:
3+
version: "*"
4+
override_path: "../.."
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#pragma once
8+
9+
#ifdef __cplusplus
10+
extern "C" {
11+
#endif
12+
13+
#define NB_OF_REGISTERED_CMD 8
14+
15+
#define GET_NAME(NAME, SUFFIX) NAME##SUFFIX
16+
#define GET_STR(STR) #STR
17+
18+
#define CREATE_CMD_FUNC(NAME) \
19+
static int GET_NAME(NAME, _func)(void *ctx, int argc, char **argv) { \
20+
printf(GET_STR(NAME) GET_STR(_func)); \
21+
printf("\n"); \
22+
return 0; \
23+
}
24+
25+
#define CREATE_FUNC(NAME, SUFFIX) \
26+
static const char *GET_NAME(NAME, SUFFIX)(void *context) { \
27+
return #NAME #SUFFIX; \
28+
}
29+
30+
/* static command functions*/
31+
CREATE_CMD_FUNC(cmd_a)
32+
CREATE_CMD_FUNC(cmd_b)
33+
CREATE_CMD_FUNC(cmd_c)
34+
CREATE_CMD_FUNC(cmd_d)
35+
CREATE_CMD_FUNC(cmd_e)
36+
CREATE_CMD_FUNC(cmd_f)
37+
CREATE_CMD_FUNC(cmd_g)
38+
CREATE_CMD_FUNC(cmd_h)
39+
40+
/* static hint functions*/
41+
CREATE_FUNC(cmd_a, _hint)
42+
CREATE_FUNC(cmd_b, _hint)
43+
CREATE_FUNC(cmd_c, _hint)
44+
CREATE_FUNC(cmd_d, _hint)
45+
CREATE_FUNC(cmd_e, _hint)
46+
CREATE_FUNC(cmd_f, _hint)
47+
CREATE_FUNC(cmd_g, _hint)
48+
CREATE_FUNC(cmd_h, _hint)
49+
50+
/* static glossary functions*/
51+
CREATE_FUNC(cmd_a, _glossary)
52+
CREATE_FUNC(cmd_b, _glossary)
53+
CREATE_FUNC(cmd_c, _glossary)
54+
CREATE_FUNC(cmd_d, _glossary)
55+
CREATE_FUNC(cmd_e, _glossary)
56+
CREATE_FUNC(cmd_f, _glossary)
57+
CREATE_FUNC(cmd_g, _glossary)
58+
CREATE_FUNC(cmd_h, _glossary)
59+
60+
/* command registration */
61+
ESP_COMMAND_REGISTER(cmd_a, group_1, GET_STR(cmd_a_help), cmd_a_func, NULL, cmd_a_hint, cmd_a_glossary);
62+
ESP_COMMAND_REGISTER(cmd_b, group_1, GET_STR(cmd_b_help), cmd_b_func, NULL, cmd_b_hint, cmd_b_glossary);
63+
ESP_COMMAND_REGISTER(cmd_c, group_2, GET_STR(cmd_c_help), cmd_c_func, NULL, cmd_c_hint, cmd_c_glossary);
64+
ESP_COMMAND_REGISTER(cmd_d, group_2, GET_STR(cmd_d_help), cmd_d_func, NULL, cmd_d_hint, cmd_d_glossary);
65+
ESP_COMMAND_REGISTER(cmd_e, group_3, GET_STR(cmd_e_help), cmd_e_func, NULL, cmd_e_hint, cmd_e_glossary);
66+
ESP_COMMAND_REGISTER(cmd_f, group_3, GET_STR(cmd_f_help), cmd_f_func, NULL, cmd_f_hint, cmd_f_glossary);
67+
ESP_COMMAND_REGISTER(cmd_g, group_4, GET_STR(cmd_g_help), cmd_g_func, NULL, cmd_g_hint, cmd_g_glossary);
68+
ESP_COMMAND_REGISTER(cmd_h, group_4, GET_STR(cmd_h_help), cmd_h_func, NULL, cmd_h_hint, cmd_h_glossary);
69+
70+
#ifdef __cplusplus
71+
}
72+
#endif

0 commit comments

Comments
 (0)