1.. 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 91 int (*cmd)(struct cmd_tbl *cmdtp, int flag, int argc, const char *argv[]); 92 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 172 .u_boot_list : { 173 KEEP(*(SORT(.u_boot_list*))); 174 } 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)); 200 console_record_reset(); 201 run_command("acpi items", 0); 202 ut_assert_nextline("dev 'acpi-test', type 1, size 2"); 203 ut_assert_nextline("dev 'acpi-test2', type 1, size 2"); 204 ut_assert_console_end(); 205 206 ctx.current = buf; 207 ut_assertok(acpi_inject_dsdt(&ctx)); 208 console_record_reset(); 209 run_command("acpi items", 0); 210 ut_assert_nextline("dev 'acpi-test', type 2, size 2"); 211 ut_assert_nextline("dev 'acpi-test2', type 2, size 2"); 212 ut_assert_console_end(); 213 214 console_record_reset(); 215 run_command("acpi items -d", 0); 216 ut_assert_nextline("dev 'acpi-test', type 2, size 2"); 217 ut_assert_nextlines_are_dump(2); 218 ut_assert_nextline("%s", ""); 219 ut_assert_nextline("dev 'acpi-test2', type 2, size 2"); 220 ut_assert_nextlines_are_dump(2); 221 ut_assert_nextline("%s", ""); 222 ut_assert_console_end(); 223 224 return 0; 225 } 226 DM_TEST(dm_test_acpi_cmd_items, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); 227