1 /* 2 * Copyright (c) 2018 Nordic Semiconductor ASA 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #ifndef SHELL_H__ 8 #define SHELL_H__ 9 10 #include <zephyr/kernel.h> 11 #include <zephyr/shell/shell_types.h> 12 #include <zephyr/shell/shell_history.h> 13 #include <zephyr/shell/shell_fprintf.h> 14 #include <zephyr/shell/shell_log_backend.h> 15 #include <zephyr/shell/shell_string_conv.h> 16 #include <zephyr/logging/log_instance.h> 17 #include <zephyr/logging/log.h> 18 #include <zephyr/sys/iterable_sections.h> 19 #include <zephyr/sys/util.h> 20 21 #if defined CONFIG_SHELL_GETOPT 22 #include <getopt.h> 23 #endif 24 25 #ifdef __cplusplus 26 extern "C" { 27 #endif 28 29 #ifndef CONFIG_SHELL_CMD_BUFF_SIZE 30 #define CONFIG_SHELL_CMD_BUFF_SIZE 0 31 #endif 32 33 #ifndef CONFIG_SHELL_PRINTF_BUFF_SIZE 34 #define CONFIG_SHELL_PRINTF_BUFF_SIZE 0 35 #endif 36 37 #ifndef CONFIG_SHELL_HISTORY_BUFFER 38 #define CONFIG_SHELL_HISTORY_BUFFER 0 39 #endif 40 41 #define Z_SHELL_CMD_ROOT_LVL (0u) 42 43 #define SHELL_HEXDUMP_BYTES_IN_LINE 16 44 45 /** 46 * @brief Flag indicates that optional arguments will be treated as one, 47 * unformatted argument. 48 * 49 * By default, shell is parsing all arguments, treats all spaces as argument 50 * separators unless they are within quotation marks which are removed in that 51 * case. If command rely on unformatted argument then this flag shall be used 52 * in place of number of optional arguments in command definition to indicate 53 * that only mandatory arguments shall be parsed and remaining command string is 54 * passed as a raw string. 55 */ 56 #define SHELL_OPT_ARG_RAW (0xFE) 57 58 /** 59 * @brief Flag indicating that number of optional arguments is not limited. 60 */ 61 #define SHELL_OPT_ARG_CHECK_SKIP (0xFF) 62 63 /** 64 * @brief Flag indicating maximum number of optional arguments that can be 65 * validated. 66 */ 67 #define SHELL_OPT_ARG_MAX (0xFD) 68 69 /** 70 * @brief Shell API 71 * @defgroup shell_api Shell API 72 * @ingroup os_services 73 * @{ 74 */ 75 76 struct shell_static_entry; 77 78 /** 79 * @brief Shell dynamic command descriptor. 80 * 81 * @details Function shall fill the received shell_static_entry structure 82 * with requested (idx) dynamic subcommand data. If there is more than 83 * one dynamic subcommand available, the function shall ensure that the 84 * returned commands: entry->syntax are sorted in alphabetical order. 85 * If idx exceeds the available dynamic subcommands, the function must 86 * write to entry->syntax NULL value. This will indicate to the shell 87 * module that there are no more dynamic commands to read. 88 */ 89 typedef void (*shell_dynamic_get)(size_t idx, 90 struct shell_static_entry *entry); 91 92 /** 93 * @brief Shell command descriptor. 94 */ 95 union shell_cmd_entry { 96 /** Pointer to function returning dynamic commands.*/ 97 shell_dynamic_get dynamic_get; 98 99 /** Pointer to array of static commands. */ 100 const struct shell_static_entry *entry; 101 }; 102 103 struct shell; 104 105 struct shell_static_args { 106 uint8_t mandatory; /*!< Number of mandatory arguments. */ 107 uint8_t optional; /*!< Number of optional arguments. */ 108 }; 109 110 /** 111 * @brief Get by index a device that matches . 112 * 113 * This can be used, for example, to identify I2C_1 as the second I2C 114 * device. 115 * 116 * Devices that failed to initialize or do not have a non-empty name 117 * are excluded from the candidates for a match. 118 * 119 * @param idx the device number starting from zero. 120 * 121 * @param prefix optional name prefix used to restrict candidate 122 * devices. Indexing is done relative to devices with names that 123 * start with this text. Pass null if no prefix match is required. 124 */ 125 const struct device *shell_device_lookup(size_t idx, 126 const char *prefix); 127 128 /** 129 * @brief Shell command handler prototype. 130 * 131 * @param sh Shell instance. 132 * @param argc Arguments count. 133 * @param argv Arguments. 134 * 135 * @retval 0 Successful command execution. 136 * @retval 1 Help printed and command not executed. 137 * @retval -EINVAL Argument validation failed. 138 * @retval -ENOEXEC Command not executed. 139 */ 140 typedef int (*shell_cmd_handler)(const struct shell *sh, 141 size_t argc, char **argv); 142 143 /** 144 * @brief Shell dictionary command handler prototype. 145 * 146 * @param sh Shell instance. 147 * @param argc Arguments count. 148 * @param argv Arguments. 149 * @param data Pointer to the user data. 150 * 151 * @retval 0 Successful command execution. 152 * @retval 1 Help printed and command not executed. 153 * @retval -EINVAL Argument validation failed. 154 * @retval -ENOEXEC Command not executed. 155 */ 156 typedef int (*shell_dict_cmd_handler)(const struct shell *sh, size_t argc, 157 char **argv, void *data); 158 159 /* When entries are added to the memory section a padding is applied for 160 * native_posix_64 and x86_64 targets. Adding padding to allow handle data 161 * in the memory section as array. 162 */ 163 #if (defined(CONFIG_ARCH_POSIX) && defined(CONFIG_64BIT)) || defined(CONFIG_X86_64) 164 #define Z_SHELL_STATIC_ENTRY_PADDING 24 165 #else 166 #define Z_SHELL_STATIC_ENTRY_PADDING 0 167 #endif 168 169 /* 170 * @brief Shell static command descriptor. 171 */ 172 struct shell_static_entry { 173 const char *syntax; /*!< Command syntax strings. */ 174 const char *help; /*!< Command help string. */ 175 const union shell_cmd_entry *subcmd; /*!< Pointer to subcommand. */ 176 shell_cmd_handler handler; /*!< Command handler. */ 177 struct shell_static_args args; /*!< Command arguments. */ 178 uint8_t padding[Z_SHELL_STATIC_ENTRY_PADDING]; 179 }; 180 181 /** 182 * @brief Macro for defining and adding a root command (level 0) with required 183 * number of arguments. 184 * 185 * @note Each root command shall have unique syntax. If a command will be called 186 * with wrong number of arguments shell will print an error message and command 187 * handler will not be called. 188 * 189 * @param[in] syntax Command syntax (for example: history). 190 * @param[in] subcmd Pointer to a subcommands array. 191 * @param[in] help Pointer to a command help string. 192 * @param[in] handler Pointer to a function handler. 193 * @param[in] mandatory Number of mandatory arguments including command name. 194 * @param[in] optional Number of optional arguments. 195 */ 196 #define SHELL_CMD_ARG_REGISTER(syntax, subcmd, help, handler, \ 197 mandatory, optional) \ 198 static const struct shell_static_entry UTIL_CAT(_shell_, syntax) = \ 199 SHELL_CMD_ARG(syntax, subcmd, help, handler, mandatory, optional); \ 200 static const TYPE_SECTION_ITERABLE(union shell_cmd_entry, \ 201 UTIL_CAT(shell_cmd_, syntax), shell_root_cmds, \ 202 UTIL_CAT(shell_cmd_, syntax) \ 203 ) = { \ 204 .entry = &UTIL_CAT(_shell_, syntax) \ 205 } 206 207 /** 208 * @brief Macro for defining and adding a conditional root command (level 0) 209 * with required number of arguments. 210 * 211 * @see SHELL_CMD_ARG_REGISTER for details. 212 * 213 * Macro can be used to create a command which can be conditionally present. 214 * It is and alternative to \#ifdefs around command registration and command 215 * handler. If command is disabled handler and subcommands are removed from 216 * the application. 217 * 218 * @param[in] flag Compile time flag. Command is present only if flag 219 * exists and equals 1. 220 * @param[in] syntax Command syntax (for example: history). 221 * @param[in] subcmd Pointer to a subcommands array. 222 * @param[in] help Pointer to a command help string. 223 * @param[in] handler Pointer to a function handler. 224 * @param[in] mandatory Number of mandatory arguments including command name. 225 * @param[in] optional Number of optional arguments. 226 */ 227 #define SHELL_COND_CMD_ARG_REGISTER(flag, syntax, subcmd, help, handler, \ 228 mandatory, optional) \ 229 COND_CODE_1(\ 230 flag, \ 231 (\ 232 SHELL_CMD_ARG_REGISTER(syntax, subcmd, help, handler, \ 233 mandatory, optional) \ 234 ), \ 235 (\ 236 static shell_cmd_handler dummy_##syntax##_handler __unused = \ 237 handler;\ 238 static const union shell_cmd_entry *dummy_subcmd_##syntax \ 239 __unused = subcmd\ 240 ) \ 241 ) 242 /** 243 * @brief Macro for defining and adding a root command (level 0) with 244 * arguments. 245 * 246 * @note All root commands must have different name. 247 * 248 * @param[in] syntax Command syntax (for example: history). 249 * @param[in] subcmd Pointer to a subcommands array. 250 * @param[in] help Pointer to a command help string. 251 * @param[in] handler Pointer to a function handler. 252 */ 253 #define SHELL_CMD_REGISTER(syntax, subcmd, help, handler) \ 254 SHELL_CMD_ARG_REGISTER(syntax, subcmd, help, handler, 0, 0) 255 256 /** 257 * @brief Macro for defining and adding a conditional root command (level 0) 258 * with arguments. 259 * 260 * @see SHELL_COND_CMD_ARG_REGISTER. 261 * 262 * @param[in] flag Compile time flag. Command is present only if flag 263 * exists and equals 1. 264 * @param[in] syntax Command syntax (for example: history). 265 * @param[in] subcmd Pointer to a subcommands array. 266 * @param[in] help Pointer to a command help string. 267 * @param[in] handler Pointer to a function handler. 268 */ 269 #define SHELL_COND_CMD_REGISTER(flag, syntax, subcmd, help, handler) \ 270 SHELL_COND_CMD_ARG_REGISTER(flag, syntax, subcmd, help, handler, 0, 0) 271 272 /** 273 * @brief Macro for creating a subcommand set. It must be used outside of any 274 * function body. 275 * 276 * Example usage: 277 * @code{.c} 278 * SHELL_STATIC_SUBCMD_SET_CREATE( 279 * foo, 280 * SHELL_CMD(abc, ...), 281 * SHELL_CMD(def, ...), 282 * SHELL_SUBCMD_SET_END 283 * ) 284 * @endcode 285 * 286 * @param[in] name Name of the subcommand set. 287 * @param[in] ... List of commands created with @ref SHELL_CMD_ARG or 288 * or @ref SHELL_CMD 289 */ 290 #define SHELL_STATIC_SUBCMD_SET_CREATE(name, ...) \ 291 static const struct shell_static_entry shell_##name[] = { \ 292 __VA_ARGS__ \ 293 }; \ 294 static const union shell_cmd_entry name = { \ 295 .entry = shell_##name \ 296 } 297 298 #define Z_SHELL_UNDERSCORE(x) _##x 299 #define Z_SHELL_SUBCMD_NAME(...) \ 300 UTIL_CAT(shell_subcmds, MACRO_MAP_CAT(Z_SHELL_UNDERSCORE, __VA_ARGS__)) 301 #define Z_SHELL_SUBCMD_SECTION_TAG(...) MACRO_MAP_CAT(Z_SHELL_UNDERSCORE, __VA_ARGS__) 302 #define Z_SHELL_SUBCMD_SET_SECTION_TAG(x) \ 303 Z_SHELL_SUBCMD_SECTION_TAG(NUM_VA_ARGS_LESS_1 x, __DEBRACKET x) 304 #define Z_SHELL_SUBCMD_ADD_SECTION_TAG(x, y) \ 305 Z_SHELL_SUBCMD_SECTION_TAG(NUM_VA_ARGS_LESS_1 x, __DEBRACKET x, y) 306 307 /** @brief Create set of subcommands. 308 * 309 * Commands to this set are added using @ref SHELL_SUBCMD_ADD and @ref SHELL_SUBCMD_COND_ADD. 310 * Commands can be added from multiple files. 311 * 312 * @param[in] _name Name of the set. @p _name is used to refer the set in the parent 313 * command. 314 * 315 * @param[in] _parent Set of comma separated parent commands in parenthesis, e.g. 316 * (foo_cmd) if subcommands are for the root command "foo_cmd". 317 */ 318 319 #define SHELL_SUBCMD_SET_CREATE(_name, _parent) \ 320 static const TYPE_SECTION_ITERABLE(struct shell_static_entry, _name, shell_subcmds, \ 321 Z_SHELL_SUBCMD_SET_SECTION_TAG(_parent)) 322 323 324 /** @brief Conditionally add command to the set of subcommands. 325 * 326 * Add command to the set created with @ref SHELL_SUBCMD_SET_CREATE. 327 * 328 * @note The name of the section is formed as concatenation of number of parent 329 * commands, names of all parent commands and own syntax. Number of parent commands 330 * is added to ensure that section prefix is unique. Without it subcommands of 331 * (foo) and (foo, cmd1) would mix. 332 * 333 * @param[in] _flag Compile time flag. Command is present only if flag 334 * exists and equals 1. 335 * @param[in] _parent Parent command sequence. Comma separated in parenthesis. 336 * @param[in] _syntax Command syntax (for example: history). 337 * @param[in] _subcmd Pointer to a subcommands array. 338 * @param[in] _help Pointer to a command help string. 339 * @param[in] _handler Pointer to a function handler. 340 * @param[in] _mand Number of mandatory arguments including command name. 341 * @param[in] _opt Number of optional arguments. 342 */ 343 #define SHELL_SUBCMD_COND_ADD(_flag, _parent, _syntax, _subcmd, _help, _handler, \ 344 _mand, _opt) \ 345 COND_CODE_1(_flag, \ 346 (static const TYPE_SECTION_ITERABLE(struct shell_static_entry, \ 347 Z_SHELL_SUBCMD_NAME(__DEBRACKET _parent, _syntax), \ 348 shell_subcmds, \ 349 Z_SHELL_SUBCMD_ADD_SECTION_TAG(_parent, _syntax)) = \ 350 SHELL_EXPR_CMD_ARG(1, _syntax, _subcmd, _help, \ 351 _handler, _mand, _opt)\ 352 ), \ 353 (static shell_cmd_handler dummy_handler_##_syntax __unused = _handler;\ 354 static const union shell_cmd_entry dummy_subcmd_##_syntax __unused = { \ 355 .entry = (const struct shell_static_entry *)_subcmd\ 356 } \ 357 ) \ 358 ) 359 360 /** @brief Add command to the set of subcommands. 361 * 362 * Add command to the set created with @ref SHELL_SUBCMD_SET_CREATE. 363 * 364 * @param[in] _parent Parent command sequence. Comma separated in parenthesis. 365 * @param[in] _syntax Command syntax (for example: history). 366 * @param[in] _subcmd Pointer to a subcommands array. 367 * @param[in] _help Pointer to a command help string. 368 * @param[in] _handler Pointer to a function handler. 369 * @param[in] _mand Number of mandatory arguments including command name. 370 * @param[in] _opt Number of optional arguments. 371 */ 372 #define SHELL_SUBCMD_ADD(_parent, _syntax, _subcmd, _help, _handler, _mand, _opt) \ 373 SHELL_SUBCMD_COND_ADD(1, _parent, _syntax, _subcmd, _help, _handler, _mand, _opt) 374 375 /** 376 * @brief Define ending subcommands set. 377 * 378 */ 379 #define SHELL_SUBCMD_SET_END {NULL} 380 381 /** 382 * @brief Macro for creating a dynamic entry. 383 * 384 * @param[in] name Name of the dynamic entry. 385 * @param[in] get Pointer to the function returning dynamic commands array 386 */ 387 #define SHELL_DYNAMIC_CMD_CREATE(name, get) \ 388 static const TYPE_SECTION_ITERABLE(union shell_cmd_entry, name, \ 389 shell_dynamic_subcmds, name) = \ 390 { \ 391 .dynamic_get = get \ 392 } 393 394 /** 395 * @brief Initializes a shell command with arguments. 396 * 397 * @note If a command will be called with wrong number of arguments shell will 398 * print an error message and command handler will not be called. 399 * 400 * @param[in] syntax Command syntax (for example: history). 401 * @param[in] subcmd Pointer to a subcommands array. 402 * @param[in] help Pointer to a command help string. 403 * @param[in] handler Pointer to a function handler. 404 * @param[in] mand Number of mandatory arguments including command name. 405 * @param[in] opt Number of optional arguments. 406 */ 407 #define SHELL_CMD_ARG(syntax, subcmd, help, handler, mand, opt) \ 408 SHELL_EXPR_CMD_ARG(1, syntax, subcmd, help, handler, mand, opt) 409 410 /** 411 * @brief Initializes a conditional shell command with arguments. 412 * 413 * @see SHELL_CMD_ARG. Based on the flag, creates a valid entry or an empty 414 * command which is ignored by the shell. It is an alternative to \#ifdefs 415 * around command registration and command handler. However, empty structure is 416 * present in the flash even if command is disabled (subcommands and handler are 417 * removed). Macro internally handles case if flag is not defined so flag must 418 * be provided without any wrapper, e.g.: SHELL_COND_CMD_ARG(CONFIG_FOO, ...) 419 * 420 * @param[in] flag Compile time flag. Command is present only if flag 421 * exists and equals 1. 422 * @param[in] syntax Command syntax (for example: history). 423 * @param[in] subcmd Pointer to a subcommands array. 424 * @param[in] help Pointer to a command help string. 425 * @param[in] handler Pointer to a function handler. 426 * @param[in] mand Number of mandatory arguments including command name. 427 * @param[in] opt Number of optional arguments. 428 */ 429 #define SHELL_COND_CMD_ARG(flag, syntax, subcmd, help, handler, mand, opt) \ 430 SHELL_EXPR_CMD_ARG(IS_ENABLED(flag), syntax, subcmd, help, \ 431 handler, mand, opt) 432 433 /** 434 * @brief Initializes a conditional shell command with arguments if expression 435 * gives non-zero result at compile time. 436 * 437 * @see SHELL_CMD_ARG. Based on the expression, creates a valid entry or an 438 * empty command which is ignored by the shell. It should be used instead of 439 * @ref SHELL_COND_CMD_ARG if condition is not a single configuration flag, 440 * e.g.: 441 * SHELL_EXPR_CMD_ARG(IS_ENABLED(CONFIG_FOO) && 442 * IS_ENABLED(CONFIG_FOO_SETTING_1), ...) 443 * 444 * @param[in] _expr Expression. 445 * @param[in] _syntax Command syntax (for example: history). 446 * @param[in] _subcmd Pointer to a subcommands array. 447 * @param[in] _help Pointer to a command help string. 448 * @param[in] _handler Pointer to a function handler. 449 * @param[in] _mand Number of mandatory arguments including command name. 450 * @param[in] _opt Number of optional arguments. 451 */ 452 #define SHELL_EXPR_CMD_ARG(_expr, _syntax, _subcmd, _help, _handler, \ 453 _mand, _opt) \ 454 { \ 455 .syntax = (_expr) ? (const char *)STRINGIFY(_syntax) : "", \ 456 .help = (_expr) ? (const char *)_help : NULL, \ 457 .subcmd = (const union shell_cmd_entry *)((_expr) ? \ 458 _subcmd : NULL), \ 459 .handler = (shell_cmd_handler)((_expr) ? _handler : NULL), \ 460 .args = { .mandatory = _mand, .optional = _opt} \ 461 } 462 463 /** 464 * @brief Initializes a shell command. 465 * 466 * @param[in] _syntax Command syntax (for example: history). 467 * @param[in] _subcmd Pointer to a subcommands array. 468 * @param[in] _help Pointer to a command help string. 469 * @param[in] _handler Pointer to a function handler. 470 */ 471 #define SHELL_CMD(_syntax, _subcmd, _help, _handler) \ 472 SHELL_CMD_ARG(_syntax, _subcmd, _help, _handler, 0, 0) 473 474 /** 475 * @brief Initializes a conditional shell command. 476 * 477 * @see SHELL_COND_CMD_ARG. 478 * 479 * @param[in] _flag Compile time flag. Command is present only if flag 480 * exists and equals 1. 481 * @param[in] _syntax Command syntax (for example: history). 482 * @param[in] _subcmd Pointer to a subcommands array. 483 * @param[in] _help Pointer to a command help string. 484 * @param[in] _handler Pointer to a function handler. 485 */ 486 #define SHELL_COND_CMD(_flag, _syntax, _subcmd, _help, _handler) \ 487 SHELL_COND_CMD_ARG(_flag, _syntax, _subcmd, _help, _handler, 0, 0) 488 489 /** 490 * @brief Initializes shell command if expression gives non-zero result at 491 * compile time. 492 * 493 * @see SHELL_EXPR_CMD_ARG. 494 * 495 * @param[in] _expr Compile time expression. Command is present only if 496 * expression is non-zero. 497 * @param[in] _syntax Command syntax (for example: history). 498 * @param[in] _subcmd Pointer to a subcommands array. 499 * @param[in] _help Pointer to a command help string. 500 * @param[in] _handler Pointer to a function handler. 501 */ 502 #define SHELL_EXPR_CMD(_expr, _syntax, _subcmd, _help, _handler) \ 503 SHELL_EXPR_CMD_ARG(_expr, _syntax, _subcmd, _help, _handler, 0, 0) 504 505 /* Internal macro used for creating handlers for dictionary commands. */ 506 #define Z_SHELL_CMD_DICT_HANDLER_CREATE(_data, _handler) \ 507 static int UTIL_CAT(UTIL_CAT(cmd_dict_, UTIL_CAT(_handler, _)), \ 508 GET_ARG_N(1, __DEBRACKET _data))( \ 509 const struct shell *sh, size_t argc, char **argv) \ 510 { \ 511 return _handler(sh, argc, argv, \ 512 (void *)GET_ARG_N(2, __DEBRACKET _data)); \ 513 } 514 515 /* Internal macro used for creating dictionary commands. */ 516 #define SHELL_CMD_DICT_CREATE(_data, _handler) \ 517 SHELL_CMD_ARG(GET_ARG_N(1, __DEBRACKET _data), NULL, GET_ARG_N(3, __DEBRACKET _data), \ 518 UTIL_CAT(UTIL_CAT(cmd_dict_, UTIL_CAT(_handler, _)), \ 519 GET_ARG_N(1, __DEBRACKET _data)), 1, 0) 520 521 /** 522 * @brief Initializes shell dictionary commands. 523 * 524 * This is a special kind of static commands. Dictionary commands can be used 525 * every time you want to use a pair: (string <-> corresponding data) in 526 * a command handler. The string is usually a verbal description of a given 527 * data. The idea is to use the string as a command syntax that can be prompted 528 * by the shell and corresponding data can be used to process the command. 529 * 530 * @param[in] _name Name of the dictionary subcommand set 531 * @param[in] _handler Command handler common for all dictionary commands. 532 * @see shell_dict_cmd_handler 533 * @param[in] ... Dictionary triplets: (command_syntax, value, helper). Value will be 534 * passed to the _handler as user data. 535 * 536 * Example usage: 537 * @code{.c} 538 * static int my_handler(const struct shell *sh, 539 * size_t argc, char **argv, void *data) 540 * { 541 * int val = (int)data; 542 * 543 * shell_print(sh, "(syntax, value) : (%s, %d)", argv[0], val); 544 * return 0; 545 * } 546 * 547 * SHELL_SUBCMD_DICT_SET_CREATE(sub_dict_cmds, my_handler, 548 * (value_0, 0, "value 0"), (value_1, 1, "value 1"), 549 * (value_2, 2, "value 2"), (value_3, 3, "value 3") 550 * ); 551 * SHELL_CMD_REGISTER(dictionary, &sub_dict_cmds, NULL, NULL); 552 * @endcode 553 */ 554 #define SHELL_SUBCMD_DICT_SET_CREATE(_name, _handler, ...) \ 555 FOR_EACH_FIXED_ARG(Z_SHELL_CMD_DICT_HANDLER_CREATE, (), \ 556 _handler, __VA_ARGS__) \ 557 SHELL_STATIC_SUBCMD_SET_CREATE(_name, \ 558 FOR_EACH_FIXED_ARG(SHELL_CMD_DICT_CREATE, (,), _handler, __VA_ARGS__), \ 559 SHELL_SUBCMD_SET_END \ 560 ) 561 562 /** 563 * @internal @brief Internal shell state in response to data received from the 564 * terminal. 565 */ 566 enum shell_receive_state { 567 SHELL_RECEIVE_DEFAULT, 568 SHELL_RECEIVE_ESC, 569 SHELL_RECEIVE_ESC_SEQ, 570 SHELL_RECEIVE_TILDE_EXP 571 }; 572 573 /** 574 * @internal @brief Internal shell state. 575 */ 576 enum shell_state { 577 SHELL_STATE_UNINITIALIZED, 578 SHELL_STATE_INITIALIZED, 579 SHELL_STATE_ACTIVE, 580 SHELL_STATE_PANIC_MODE_ACTIVE, /*!< Panic activated.*/ 581 SHELL_STATE_PANIC_MODE_INACTIVE /*!< Panic requested, not supported.*/ 582 }; 583 584 /** @brief Shell transport event. */ 585 enum shell_transport_evt { 586 SHELL_TRANSPORT_EVT_RX_RDY, 587 SHELL_TRANSPORT_EVT_TX_RDY 588 }; 589 590 typedef void (*shell_transport_handler_t)(enum shell_transport_evt evt, 591 void *context); 592 593 594 typedef void (*shell_uninit_cb_t)(const struct shell *sh, int res); 595 596 /** @brief Bypass callback. 597 * 598 * @param sh Shell instance. 599 * @param data Raw data from transport. 600 * @param len Data length. 601 */ 602 typedef void (*shell_bypass_cb_t)(const struct shell *sh, 603 uint8_t *data, 604 size_t len); 605 606 struct shell_transport; 607 608 /** 609 * @struct shell_transport_api 610 * @brief Unified shell transport interface. 611 */ 612 struct shell_transport_api { 613 /** 614 * @brief Function for initializing the shell transport interface. 615 * 616 * @param[in] transport Pointer to the transfer instance. 617 * @param[in] config Pointer to instance configuration. 618 * @param[in] evt_handler Event handler. 619 * @param[in] context Pointer to the context passed to event 620 * handler. 621 * 622 * @return Standard error code. 623 */ 624 int (*init)(const struct shell_transport *transport, 625 const void *config, 626 shell_transport_handler_t evt_handler, 627 void *context); 628 629 /** 630 * @brief Function for uninitializing the shell transport interface. 631 * 632 * @param[in] transport Pointer to the transfer instance. 633 * 634 * @return Standard error code. 635 */ 636 int (*uninit)(const struct shell_transport *transport); 637 638 /** 639 * @brief Function for enabling transport in given TX mode. 640 * 641 * Function can be used to reconfigure TX to work in blocking mode. 642 * 643 * @param transport Pointer to the transfer instance. 644 * @param blocking_tx If true, the transport TX is enabled in blocking 645 * mode. 646 * 647 * @return NRF_SUCCESS on successful enabling, error otherwise (also if 648 * not supported). 649 */ 650 int (*enable)(const struct shell_transport *transport, 651 bool blocking_tx); 652 653 /** 654 * @brief Function for writing data to the transport interface. 655 * 656 * @param[in] transport Pointer to the transfer instance. 657 * @param[in] data Pointer to the source buffer. 658 * @param[in] length Source buffer length. 659 * @param[out] cnt Pointer to the sent bytes counter. 660 * 661 * @return Standard error code. 662 */ 663 int (*write)(const struct shell_transport *transport, 664 const void *data, size_t length, size_t *cnt); 665 666 /** 667 * @brief Function for reading data from the transport interface. 668 * 669 * @param[in] transport Pointer to the transfer instance. 670 * @param[in] data Pointer to the destination buffer. 671 * @param[in] length Destination buffer length. 672 * @param[out] cnt Pointer to the received bytes counter. 673 * 674 * @return Standard error code. 675 */ 676 int (*read)(const struct shell_transport *transport, 677 void *data, size_t length, size_t *cnt); 678 679 /** 680 * @brief Function called in shell thread loop. 681 * 682 * Can be used for backend operations that require longer execution time 683 * 684 * @param[in] transport Pointer to the transfer instance. 685 */ 686 void (*update)(const struct shell_transport *transport); 687 688 }; 689 690 struct shell_transport { 691 const struct shell_transport_api *api; 692 void *ctx; 693 }; 694 695 /** 696 * @brief Shell statistics structure. 697 */ 698 struct shell_stats { 699 atomic_t log_lost_cnt; /*!< Lost log counter.*/ 700 }; 701 702 #ifdef CONFIG_SHELL_STATS 703 #define Z_SHELL_STATS_DEFINE(_name) static struct shell_stats _name##_stats 704 #define Z_SHELL_STATS_PTR(_name) (&(_name##_stats)) 705 #else 706 #define Z_SHELL_STATS_DEFINE(_name) 707 #define Z_SHELL_STATS_PTR(_name) NULL 708 #endif /* CONFIG_SHELL_STATS */ 709 710 /** 711 * @internal @brief Flags for shell backend configuration. 712 */ 713 struct shell_backend_config_flags { 714 uint32_t insert_mode :1; /*!< Controls insert mode for text introduction */ 715 uint32_t echo :1; /*!< Controls shell echo */ 716 uint32_t obscure :1; /*!< If echo on, print asterisk instead */ 717 uint32_t mode_delete :1; /*!< Operation mode of backspace key */ 718 uint32_t use_colors :1; /*!< Controls colored syntax */ 719 uint32_t use_vt100 :1; /*!< Controls VT100 commands usage in shell */ 720 }; 721 722 BUILD_ASSERT((sizeof(struct shell_backend_config_flags) == sizeof(uint32_t)), 723 "Structure must fit in 4 bytes"); 724 725 /** 726 * @internal @brief Default backend configuration. 727 */ 728 #define SHELL_DEFAULT_BACKEND_CONFIG_FLAGS \ 729 { \ 730 .insert_mode = 0, \ 731 .echo = 1, \ 732 .obscure = IS_ENABLED(CONFIG_SHELL_START_OBSCURED), \ 733 .mode_delete = 1, \ 734 .use_colors = 1, \ 735 .use_vt100 = 1, \ 736 }; 737 738 struct shell_backend_ctx_flags { 739 uint32_t processing :1; /*!< Shell is executing process function */ 740 uint32_t tx_rdy :1; 741 uint32_t history_exit :1; /*!< Request to exit history mode */ 742 uint32_t last_nl :8; /*!< Last received new line character */ 743 uint32_t cmd_ctx :1; /*!< Shell is executing command */ 744 uint32_t print_noinit :1; /*!< Print request from not initialized shell */ 745 uint32_t sync_mode :1; /*!< Shell in synchronous mode */ 746 uint32_t handle_log :1; /*!< Shell is handling logger backend */ 747 }; 748 749 BUILD_ASSERT((sizeof(struct shell_backend_ctx_flags) == sizeof(uint32_t)), 750 "Structure must fit in 4 bytes"); 751 752 /** 753 * @internal @brief Union for internal shell usage. 754 */ 755 union shell_backend_cfg { 756 atomic_t value; 757 struct shell_backend_config_flags flags; 758 }; 759 760 /** 761 * @internal @brief Union for internal shell usage. 762 */ 763 union shell_backend_ctx { 764 uint32_t value; 765 struct shell_backend_ctx_flags flags; 766 }; 767 768 enum shell_signal { 769 SHELL_SIGNAL_RXRDY, 770 SHELL_SIGNAL_LOG_MSG, 771 SHELL_SIGNAL_KILL, 772 SHELL_SIGNAL_TXDONE, /* TXDONE must be last one before SHELL_SIGNALS */ 773 SHELL_SIGNALS 774 }; 775 776 /** 777 * @brief Shell instance context. 778 */ 779 struct shell_ctx { 780 const char *prompt; /*!< shell current prompt. */ 781 782 enum shell_state state; /*!< Internal module state.*/ 783 enum shell_receive_state receive_state;/*!< Escape sequence indicator.*/ 784 785 /** Currently executed command.*/ 786 struct shell_static_entry active_cmd; 787 788 /** New root command. If NULL shell uses default root commands. */ 789 const struct shell_static_entry *selected_cmd; 790 791 /** VT100 color and cursor position, terminal width.*/ 792 struct shell_vt100_ctx vt100_ctx; 793 794 /** Callback called from shell thread context when unitialization is 795 * completed just before aborting shell thread. 796 */ 797 shell_uninit_cb_t uninit_cb; 798 799 /** When bypass is set, all incoming data is passed to the callback. */ 800 shell_bypass_cb_t bypass; 801 802 /*!< Logging level for a backend. */ 803 uint32_t log_level; 804 805 #if defined CONFIG_SHELL_GETOPT 806 /*!< getopt context for a shell backend. */ 807 struct getopt_state getopt; 808 #endif 809 810 uint16_t cmd_buff_len; /*!< Command length.*/ 811 uint16_t cmd_buff_pos; /*!< Command buffer cursor position.*/ 812 813 uint16_t cmd_tmp_buff_len; /*!< Command length in tmp buffer.*/ 814 815 /** Command input buffer.*/ 816 char cmd_buff[CONFIG_SHELL_CMD_BUFF_SIZE]; 817 818 /** Command temporary buffer.*/ 819 char temp_buff[CONFIG_SHELL_CMD_BUFF_SIZE]; 820 821 /** Printf buffer size.*/ 822 char printf_buff[CONFIG_SHELL_PRINTF_BUFF_SIZE]; 823 824 volatile union shell_backend_cfg cfg; 825 volatile union shell_backend_ctx ctx; 826 827 struct k_poll_signal signals[SHELL_SIGNALS]; 828 829 /** Events that should be used only internally by shell thread. 830 * Event for SHELL_SIGNAL_TXDONE is initialized but unused. 831 */ 832 struct k_poll_event events[SHELL_SIGNALS]; 833 834 struct k_mutex wr_mtx; 835 k_tid_t tid; 836 int ret_val; 837 }; 838 839 extern const struct log_backend_api log_backend_shell_api; 840 841 /** 842 * @brief Flags for setting shell output newline sequence. 843 */ 844 enum shell_flag { 845 SHELL_FLAG_CRLF_DEFAULT = (1<<0), /*!< Do not map CR or LF */ 846 SHELL_FLAG_OLF_CRLF = (1<<1) /*!< Map LF to CRLF on output */ 847 }; 848 849 /** 850 * @brief Shell instance internals. 851 */ 852 struct shell { 853 const char *default_prompt; /*!< shell default prompt. */ 854 855 const struct shell_transport *iface; /*!< Transport interface.*/ 856 struct shell_ctx *ctx; /*!< Internal context.*/ 857 858 struct shell_history *history; 859 860 const enum shell_flag shell_flag; 861 862 const struct shell_fprintf *fprintf_ctx; 863 864 struct shell_stats *stats; 865 866 const struct shell_log_backend *log_backend; 867 868 LOG_INSTANCE_PTR_DECLARE(log); 869 870 const char *name; 871 struct k_thread *thread; 872 k_thread_stack_t *stack; 873 }; 874 875 extern void z_shell_print_stream(const void *user_ctx, const char *data, 876 size_t data_len); 877 /** 878 * @brief Macro for defining a shell instance. 879 * 880 * @param[in] _name Instance name. 881 * @param[in] _prompt Shell default prompt string. 882 * @param[in] _transport_iface Pointer to the transport interface. 883 * @param[in] _log_queue_size Logger processing queue size. 884 * @param[in] _log_timeout Logger thread timeout in milliseconds on full 885 * log queue. If queue is full logger thread is 886 * blocked for given amount of time before log 887 * message is dropped. 888 * @param[in] _shell_flag Shell output newline sequence. 889 */ 890 #define SHELL_DEFINE(_name, _prompt, _transport_iface, \ 891 _log_queue_size, _log_timeout, _shell_flag) \ 892 static const struct shell _name; \ 893 static struct shell_ctx UTIL_CAT(_name, _ctx); \ 894 static uint8_t _name##_out_buffer[CONFIG_SHELL_PRINTF_BUFF_SIZE]; \ 895 Z_SHELL_LOG_BACKEND_DEFINE(_name, _name##_out_buffer, \ 896 CONFIG_SHELL_PRINTF_BUFF_SIZE, \ 897 _log_queue_size, _log_timeout); \ 898 Z_SHELL_HISTORY_DEFINE(_name##_history, CONFIG_SHELL_HISTORY_BUFFER); \ 899 Z_SHELL_FPRINTF_DEFINE(_name##_fprintf, &_name, _name##_out_buffer, \ 900 CONFIG_SHELL_PRINTF_BUFF_SIZE, \ 901 true, z_shell_print_stream); \ 902 LOG_INSTANCE_REGISTER(shell, _name, CONFIG_SHELL_LOG_LEVEL); \ 903 Z_SHELL_STATS_DEFINE(_name); \ 904 static K_KERNEL_STACK_DEFINE(_name##_stack, CONFIG_SHELL_STACK_SIZE); \ 905 static struct k_thread _name##_thread; \ 906 static const STRUCT_SECTION_ITERABLE(shell, _name) = { \ 907 .default_prompt = _prompt, \ 908 .iface = _transport_iface, \ 909 .ctx = &UTIL_CAT(_name, _ctx), \ 910 .history = IS_ENABLED(CONFIG_SHELL_HISTORY) ? \ 911 &_name##_history : NULL, \ 912 .shell_flag = _shell_flag, \ 913 .fprintf_ctx = &_name##_fprintf, \ 914 .stats = Z_SHELL_STATS_PTR(_name), \ 915 .log_backend = Z_SHELL_LOG_BACKEND_PTR(_name), \ 916 LOG_INSTANCE_PTR_INIT(log, shell, _name) \ 917 .name = STRINGIFY(_name), \ 918 .thread = &_name##_thread, \ 919 .stack = _name##_stack \ 920 } 921 922 /** 923 * @brief Function for initializing a transport layer and internal shell state. 924 * 925 * @param[in] sh Pointer to shell instance. 926 * @param[in] transport_config Transport configuration during initialization. 927 * @param[in] cfg_flags Initial backend configuration flags. 928 * Shell will copy this data. 929 * @param[in] log_backend If true, the console will be used as logger 930 * backend. 931 * @param[in] init_log_level Default severity level for the logger. 932 * 933 * @return Standard error code. 934 */ 935 int shell_init(const struct shell *sh, const void *transport_config, 936 struct shell_backend_config_flags cfg_flags, 937 bool log_backend, uint32_t init_log_level); 938 939 /** 940 * @brief Uninitializes the transport layer and the internal shell state. 941 * 942 * @param sh Pointer to shell instance. 943 * @param cb Callback called when uninitialization is completed. 944 */ 945 void shell_uninit(const struct shell *sh, shell_uninit_cb_t cb); 946 947 /** 948 * @brief Function for starting shell processing. 949 * 950 * @param sh Pointer to the shell instance. 951 * 952 * @return Standard error code. 953 */ 954 int shell_start(const struct shell *sh); 955 956 /** 957 * @brief Function for stopping shell processing. 958 * 959 * @param sh Pointer to shell instance. 960 * 961 * @return Standard error code. 962 */ 963 int shell_stop(const struct shell *sh); 964 965 /** 966 * @brief Terminal default text color for shell_fprintf function. 967 */ 968 #define SHELL_NORMAL SHELL_VT100_COLOR_DEFAULT 969 970 /** 971 * @brief Green text color for shell_fprintf function. 972 */ 973 #define SHELL_INFO SHELL_VT100_COLOR_GREEN 974 975 /** 976 * @brief Cyan text color for shell_fprintf function. 977 */ 978 #define SHELL_OPTION SHELL_VT100_COLOR_CYAN 979 980 /** 981 * @brief Yellow text color for shell_fprintf function. 982 */ 983 #define SHELL_WARNING SHELL_VT100_COLOR_YELLOW 984 985 /** 986 * @brief Red text color for shell_fprintf function. 987 */ 988 #define SHELL_ERROR SHELL_VT100_COLOR_RED 989 990 /** 991 * @brief printf-like function which sends formatted data stream to the shell. 992 * 993 * This function can be used from the command handler or from threads, but not 994 * from an interrupt context. 995 * 996 * @param[in] sh Pointer to the shell instance. 997 * @param[in] color Printed text color. 998 * @param[in] fmt Format string. 999 * @param[in] ... List of parameters to print. 1000 */ 1001 void __printf_like(3, 4) shell_fprintf(const struct shell *sh, 1002 enum shell_vt100_color color, 1003 const char *fmt, ...); 1004 1005 /** 1006 * @brief vprintf-like function which sends formatted data stream to the shell. 1007 * 1008 * This function can be used from the command handler or from threads, but not 1009 * from an interrupt context. It is similar to shell_fprintf() but takes a 1010 * va_list instead of variable arguments. 1011 * 1012 * @param[in] sh Pointer to the shell instance. 1013 * @param[in] color Printed text color. 1014 * @param[in] fmt Format string. 1015 * @param[in] args List of parameters to print. 1016 */ 1017 void shell_vfprintf(const struct shell *sh, enum shell_vt100_color color, 1018 const char *fmt, va_list args); 1019 1020 /** 1021 * @brief Print a line of data in hexadecimal format. 1022 * 1023 * Each line shows the offset, bytes and then ASCII representation. 1024 * 1025 * For example: 1026 * 1027 * 00008010: 20 25 00 20 2f 48 00 08 80 05 00 20 af 46 00 1028 * | %. /H.. ... .F. | 1029 * 1030 * @param[in] sh Pointer to the shell instance. 1031 * @param[in] offset Offset to show for this line. 1032 * @param[in] data Pointer to data. 1033 * @param[in] len Length of data. 1034 */ 1035 void shell_hexdump_line(const struct shell *sh, unsigned int offset, 1036 const uint8_t *data, size_t len); 1037 1038 /** 1039 * @brief Print data in hexadecimal format. 1040 * 1041 * @param[in] sh Pointer to the shell instance. 1042 * @param[in] data Pointer to data. 1043 * @param[in] len Length of data. 1044 */ 1045 void shell_hexdump(const struct shell *sh, const uint8_t *data, size_t len); 1046 1047 /** 1048 * @brief Print info message to the shell. 1049 * 1050 * See @ref shell_fprintf. 1051 * 1052 * @param[in] _sh Pointer to the shell instance. 1053 * @param[in] _ft Format string. 1054 * @param[in] ... List of parameters to print. 1055 */ 1056 #define shell_info(_sh, _ft, ...) \ 1057 shell_fprintf(_sh, SHELL_INFO, _ft "\n", ##__VA_ARGS__) 1058 1059 /** 1060 * @brief Print normal message to the shell. 1061 * 1062 * See @ref shell_fprintf. 1063 * 1064 * @param[in] _sh Pointer to the shell instance. 1065 * @param[in] _ft Format string. 1066 * @param[in] ... List of parameters to print. 1067 */ 1068 #define shell_print(_sh, _ft, ...) \ 1069 shell_fprintf(_sh, SHELL_NORMAL, _ft "\n", ##__VA_ARGS__) 1070 1071 /** 1072 * @brief Print warning message to the shell. 1073 * 1074 * See @ref shell_fprintf. 1075 * 1076 * @param[in] _sh Pointer to the shell instance. 1077 * @param[in] _ft Format string. 1078 * @param[in] ... List of parameters to print. 1079 */ 1080 #define shell_warn(_sh, _ft, ...) \ 1081 shell_fprintf(_sh, SHELL_WARNING, _ft "\n", ##__VA_ARGS__) 1082 1083 /** 1084 * @brief Print error message to the shell. 1085 * 1086 * See @ref shell_fprintf. 1087 * 1088 * @param[in] _sh Pointer to the shell instance. 1089 * @param[in] _ft Format string. 1090 * @param[in] ... List of parameters to print. 1091 */ 1092 #define shell_error(_sh, _ft, ...) \ 1093 shell_fprintf(_sh, SHELL_ERROR, _ft "\n", ##__VA_ARGS__) 1094 1095 /** 1096 * @brief Process function, which should be executed when data is ready in the 1097 * transport interface. To be used if shell thread is disabled. 1098 * 1099 * @param[in] sh Pointer to the shell instance. 1100 */ 1101 void shell_process(const struct shell *sh); 1102 1103 /** 1104 * @brief Change displayed shell prompt. 1105 * 1106 * @param[in] sh Pointer to the shell instance. 1107 * @param[in] prompt New shell prompt. 1108 * 1109 * @return 0 Success. 1110 * @return -EINVAL Pointer to new prompt is not correct. 1111 */ 1112 int shell_prompt_change(const struct shell *sh, const char *prompt); 1113 1114 /** 1115 * @brief Prints the current command help. 1116 * 1117 * Function will print a help string with: the currently entered command 1118 * and subcommands (if they exist). 1119 * 1120 * @param[in] sh Pointer to the shell instance. 1121 */ 1122 void shell_help(const struct shell *sh); 1123 1124 /** @brief Command's help has been printed */ 1125 #define SHELL_CMD_HELP_PRINTED (1) 1126 1127 /** @brief Execute command. 1128 * 1129 * Pass command line to shell to execute. 1130 * 1131 * Note: This by no means makes any of the commands a stable interface, so 1132 * this function should only be used for debugging/diagnostic. 1133 * 1134 * This function must not be called from shell command context! 1135 1136 * 1137 * @param[in] sh Pointer to the shell instance. 1138 * It can be NULL when the 1139 * @kconfig{CONFIG_SHELL_BACKEND_DUMMY} option is enabled. 1140 * @param[in] cmd Command to be executed. 1141 * 1142 * @return Result of the execution 1143 */ 1144 int shell_execute_cmd(const struct shell *sh, const char *cmd); 1145 1146 /** @brief Set root command for all shell instances. 1147 * 1148 * It allows setting from the code the root command. It is an equivalent of 1149 * calling select command with one of the root commands as the argument 1150 * (e.g "select log") except it sets command for all shell instances. 1151 * 1152 * @param cmd String with one of the root commands or null pointer to reset. 1153 * 1154 * @retval 0 if root command is set. 1155 * @retval -EINVAL if invalid root command is provided. 1156 */ 1157 int shell_set_root_cmd(const char *cmd); 1158 1159 /** @brief Set bypass callback. 1160 * 1161 * Bypass callback is called whenever data is received. Shell is bypassed and 1162 * data is passed directly to the callback. Use null to disable bypass functionality. 1163 * 1164 * @param[in] sh Pointer to the shell instance. 1165 * @param[in] bypass Bypass callback or null to disable. 1166 */ 1167 void shell_set_bypass(const struct shell *sh, shell_bypass_cb_t bypass); 1168 1169 /** @brief Get shell readiness to execute commands. 1170 * 1171 * @param[in] sh Pointer to the shell instance. 1172 * 1173 * @retval true Shell backend is ready to execute commands. 1174 * @retval false Shell backend is not initialized or not started. 1175 */ 1176 bool shell_ready(const struct shell *sh); 1177 1178 /** 1179 * @brief Allow application to control text insert mode. 1180 * Value is modified atomically and the previous value is returned. 1181 * 1182 * @param[in] sh Pointer to the shell instance. 1183 * @param[in] val Insert mode. 1184 * 1185 * @retval 0 or 1: previous value 1186 * @retval -EINVAL if shell is NULL. 1187 */ 1188 int shell_insert_mode_set(const struct shell *sh, bool val); 1189 1190 /** 1191 * @brief Allow application to control whether terminal output uses colored 1192 * syntax. 1193 * Value is modified atomically and the previous value is returned. 1194 * 1195 * @param[in] sh Pointer to the shell instance. 1196 * @param[in] val Color mode. 1197 * 1198 * @retval 0 or 1: previous value 1199 * @retval -EINVAL if shell is NULL. 1200 */ 1201 int shell_use_colors_set(const struct shell *sh, bool val); 1202 1203 /** 1204 * @brief Allow application to control whether terminal is using vt100 commands. 1205 * Value is modified atomically and the previous value is returned. 1206 * 1207 * @param[in] sh Pointer to the shell instance. 1208 * @param[in] val vt100 mode. 1209 * 1210 * @retval 0 or 1: previous value 1211 * @retval -EINVAL if shell is NULL. 1212 */ 1213 int shell_use_vt100_set(const struct shell *sh, bool val); 1214 1215 /** 1216 * @brief Allow application to control whether user input is echoed back. 1217 * Value is modified atomically and the previous value is returned. 1218 * 1219 * @param[in] sh Pointer to the shell instance. 1220 * @param[in] val Echo mode. 1221 * 1222 * @retval 0 or 1: previous value 1223 * @retval -EINVAL if shell is NULL. 1224 */ 1225 int shell_echo_set(const struct shell *sh, bool val); 1226 1227 /** 1228 * @brief Allow application to control whether user input is obscured with 1229 * asterisks -- useful for implementing passwords. 1230 * Value is modified atomically and the previous value is returned. 1231 * 1232 * @param[in] sh Pointer to the shell instance. 1233 * @param[in] obscure Obscure mode. 1234 * 1235 * @retval 0 or 1: previous value. 1236 * @retval -EINVAL if shell is NULL. 1237 */ 1238 int shell_obscure_set(const struct shell *sh, bool obscure); 1239 1240 /** 1241 * @brief Allow application to control whether the delete key backspaces or 1242 * deletes. 1243 * Value is modified atomically and the previous value is returned. 1244 * 1245 * @param[in] sh Pointer to the shell instance. 1246 * @param[in] val Delete mode. 1247 * 1248 * @retval 0 or 1: previous value 1249 * @retval -EINVAL if shell is NULL. 1250 */ 1251 int shell_mode_delete_set(const struct shell *sh, bool val); 1252 1253 /** 1254 * @brief Retrieve return value of most recently executed shell command. 1255 * 1256 * @param[in] sh Pointer to the shell instance 1257 * 1258 * @retval return value of previous command 1259 */ 1260 int shell_get_return_value(const struct shell *sh); 1261 1262 /** 1263 * @} 1264 */ 1265 1266 #ifdef __cplusplus 1267 } 1268 #endif 1269 1270 #endif /* SHELL_H__ */ 1271