blob: 77a7a4d9c02d5573179b252b64285a7c1b0fc1b5 [file] [log] [blame]
Heinrich Schuchardt380c6b92020-12-12 08:33:28 +01001.. SPDX-License-Identifier: GPL-2.0+
2
3Implementing shell commands
4===========================
5
6Command definition
7------------------
8
9Commands are added to U-Boot by creating a new command structure.
10This is done by first including command.h, then using the U_BOOT_CMD() or the
11U_BOOT_CMD_COMPLETE macro to fill in a struct cmd_tbl structure.
12
13.. code-block:: c
14
15 U_BOOT_CMD(name, maxargs, repeatable, command, "usage", "help")
16 U_BOOT_CMD_COMPLETE(name, maxargs, repeatable, command, "usage, "help", comp)
17
18name
19 The name of the command. This is **not** a string.
20
21maxargs
22 The maximum number of arguments this function takes including
23 the command itself.
24
25repeatable
26 Either 0 or 1 to indicate if autorepeat is allowed.
27
28command
29 Pointer to the command function. This is the function that is
30 called when the command is issued.
31
32usage
33 Short description. This is a string.
34
35help
36 Long description. This is a string. The long description is
37 only available if CONFIG_SYS_LONGHELP is defined.
38
39comp
40 Pointer to the completion function. May be NULL.
41 This function is called if the user hits the TAB key while
42 entering the command arguments to complete the entry. Command
43 completion is only available if CONFIG_AUTO_COMPLETE is defined.
44
45Sub-command definition
46----------------------
47
48Likewise an array of struct cmd_tbl holding sub-commands can be created using
49either of the following macros:
50
51.. code-block:: c
52
53 U_BOOT_CMD_MKENT(name, maxargs, repeatable, command, "usage", "help")
54 U_BOOT_CMD_MKENTCOMPLETE(name, maxargs, repeatable, command, "usage, "help", comp)
55
56This table has to be evaluated in the command function of the main command, e.g.
57
58.. code-block:: c
59
60 static struct cmd_tbl cmd_sub[] = {
61 U_BOOT_CMD_MKENT(foo, CONFIG_SYS_MAXARGS, 1, do_foo, "", ""),
62 U_BOOT_CMD_MKENT(bar, CONFIG_SYS_MAXARGS, 1, do_bar, "", ""),
63 };
64
65 static int do_cmd(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
66 {
67 struct cmd_tbl *cp;
68
69 if (argc < 2)
70 return CMD_RET_USAGE;
71
72 /* drop sub-command argument */
73 argc--;
74 argv++;
75
76 cp = find_cmd_tbl(argv[0], cmd_ut_sub, ARRAY_SIZE(cmd_sub));
77
78 if (cp)
79 return cp->cmd(cmdtp, flag, argc, argv);
80
81 return CMD_RET_USAGE;
82 }
83
84Command function
85----------------
86
87The command function pointer has to be of type
88
89.. code-block:: c
90
Alexander Dahl27987b82024-02-26 16:46:43 +010091 int (*cmd)(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
Heinrich Schuchardt380c6b92020-12-12 08:33:28 +010092
93cmdtp
94 Table entry describing the command (see above).
95
96flag
97 A bitmap which may contain the following bits
98
99 * CMD_FLAG_REPEAT - The last command is repeated.
100 * CMD_FLAG_BOOTD - The command is called by the bootd command.
101 * CMD_FLAG_ENV - The command is called by the run command.
102
103argc
104 Number of arguments including the command.
105
106argv
107 Arguments.
108
109Allowable return value are:
110
111CMD_RET_SUCCESS
112 The command was successfully executed.
113
114CMD_RET_FAILURE
115 The command failed.
116
117CMD_RET_USAGE
118 The command was called with invalid parameters. This value
119 leads to the display of the usage string.
120
121Completion function
122-------------------
123
124The completion function pointer has to be of type
125
126.. code-block:: c
127
128 int (*complete)(int argc, char *const argv[], char last_char,
129 int maxv, char *cmdv[]);
130
131argc
132 Number of arguments including the command.
133
134argv
135 Arguments.
136
137last_char
138 The last character in the command line buffer.
139
140maxv
141 Maximum number of possible completions that may be returned by
142 the function.
143
144cmdv
145 Used to return possible values for the last argument. The last
146 possible completion must be followed by NULL.
147
148The function returns the number of possible completions (without the terminating
149NULL value).
150
151Behind the scene
152----------------
153
154The structure created is named with a special prefix and placed by
155the linker in a special section using the linker lists mechanism
156(see include/linker_lists.h)
157
158This makes it possible for the final link to extract all commands
159compiled into any object code and construct a static array so the
160command array can be iterated over using the linker lists macros.
161
162The linker lists feature ensures that the linker does not discard
163these symbols when linking full U-Boot even though they are not
164referenced in the source code as such.
165
166If a new board is defined do not forget to define the command section
167by writing in u-boot.lds ($(srctree)/board/boardname/u-boot.lds) these
1683 lines:
169
170.. code-block:: c
171
Andrew Scull99e2fbc2022-05-30 10:00:04 +0000172 __u_boot_list : {
173 KEEP(*(SORT(__u_boot_list*)));
Heinrich Schuchardt380c6b92020-12-12 08:33:28 +0100174 }
175
176Writing tests
177-------------
178
179All new commands should have tests. Tests for existing commands are very
180welcome.
181
182It is fairly easy to write a test for a command. Enable it in sandbox, and
183then add code that runs the command and checks the output.
184
185Here is an example:
186
187.. code-block:: c
188
189 /* Test 'acpi items' command */
190 static int dm_test_acpi_cmd_items(struct unit_test_state *uts)
191 {
192 struct acpi_ctx ctx;
193 void *buf;
194
195 buf = malloc(BUF_SIZE);
196 ut_assertnonnull(buf);
197
198 ctx.current = buf;
199 ut_assertok(acpi_fill_ssdt(&ctx));
Heinrich Schuchardt380c6b92020-12-12 08:33:28 +0100200 run_command("acpi items", 0);
201 ut_assert_nextline("dev 'acpi-test', type 1, size 2");
202 ut_assert_nextline("dev 'acpi-test2', type 1, size 2");
203 ut_assert_console_end();
204
205 ctx.current = buf;
206 ut_assertok(acpi_inject_dsdt(&ctx));
Heinrich Schuchardt380c6b92020-12-12 08:33:28 +0100207 run_command("acpi items", 0);
208 ut_assert_nextline("dev 'acpi-test', type 2, size 2");
209 ut_assert_nextline("dev 'acpi-test2', type 2, size 2");
210 ut_assert_console_end();
211
Heinrich Schuchardt380c6b92020-12-12 08:33:28 +0100212 run_command("acpi items -d", 0);
213 ut_assert_nextline("dev 'acpi-test', type 2, size 2");
214 ut_assert_nextlines_are_dump(2);
215 ut_assert_nextline("%s", "");
216 ut_assert_nextline("dev 'acpi-test2', type 2, size 2");
217 ut_assert_nextlines_are_dump(2);
218 ut_assert_nextline("%s", "");
219 ut_assert_console_end();
220
221 return 0;
222 }
Simon Glass695b4642024-08-22 07:58:04 -0600223 DM_TEST(dm_test_acpi_cmd_items, UTF_SCAN_PDATA | UTF_SCAN_FDT | UTF_CONSOLE);
224
225Note that it is not necessary to call console_record_reset() unless you are
226trying to drop some unchecked output. Consider using ut_check_skip_to_line()
227instead.