nrf_cli.h 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704
  1. /**
  2. * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without modification,
  7. * are permitted provided that the following conditions are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright notice, this
  10. * list of conditions and the following disclaimer.
  11. *
  12. * 2. Redistributions in binary form, except as embedded into a Nordic
  13. * Semiconductor ASA integrated circuit in a product or a software update for
  14. * such product, must reproduce the above copyright notice, this list of
  15. * conditions and the following disclaimer in the documentation and/or other
  16. * materials provided with the distribution.
  17. *
  18. * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
  19. * contributors may be used to endorse or promote products derived from this
  20. * software without specific prior written permission.
  21. *
  22. * 4. This software, with or without modification, must only be used with a
  23. * Nordic Semiconductor ASA integrated circuit.
  24. *
  25. * 5. Any software provided in binary form under this license must not be reverse
  26. * engineered, decompiled, modified and/or disassembled.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
  29. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30. * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
  31. * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
  32. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  33. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  34. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  35. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  37. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. *
  39. */
  40. #ifndef NRF_CLI_H__
  41. #define NRF_CLI_H__
  42. #include "sdk_common.h"
  43. #include "nrf_cli_types.h"
  44. #include "nrf_section.h"
  45. #include "nrf_log_backend_interface.h"
  46. #include "nrf_queue.h"
  47. #include "nrf_log_ctrl.h"
  48. #include "app_util_platform.h"
  49. #include "nrf_memobj.h"
  50. #if NRF_MODULE_ENABLED(NRF_CLI_USES_TASK_MANAGER)
  51. #include "task_manager.h"
  52. #endif
  53. #include "nrf_fprintf.h"
  54. #include "nrf_fprintf_format.h"
  55. #ifdef __cplusplus
  56. extern "C" {
  57. #endif
  58. #define NRF_CLI_RX_BUFF_SIZE 16
  59. /* CLI reserves top task manager flags, bits 0...18 are available for application. */
  60. #define NRF_CLI_TRANSPORT_TX_RDY_TASK_EVT (1UL << 19)
  61. #define NRF_CLI_TRANSPORT_RX_RDY_TASK_EVT (1UL << 20)
  62. #define NRF_CLI_LOG_PENDING_TASK_EVT (1UL << 21)
  63. #define NRF_CLI_CMD_EXECUTE_EVT (1UL << 22)
  64. #define NRF_CLI_KILL_TASK_EVT (1UL << 23)
  65. #define NRF_CLI_TASK_EVTS (NRF_CLI_TRANSPORT_TX_RDY_TASK_EVT | \
  66. NRF_CLI_TRANSPORT_RX_RDY_TASK_EVT | \
  67. NRF_CLI_LOG_PENDING_TASK_EVT | \
  68. NRF_CLI_CMD_EXECUTE_EVT | \
  69. NRF_CLI_KILL_TASK_EVT)
  70. /**
  71. * @defgroup nrf_cli Command Line Interface
  72. * @ingroup app_common
  73. *
  74. * @brief Module for unified command line handling.
  75. *
  76. * @{
  77. */
  78. /**
  79. * @brief Aliases to: @ref nrf_cli, @ref nrf_cli_cmd_entry, and @ref nrf_cli_static_entry.
  80. * Must be created here to satisfy module declaration order dependencies.
  81. */
  82. typedef struct nrf_cli nrf_cli_t;
  83. typedef struct nrf_cli_cmd_entry nrf_cli_cmd_entry_t;
  84. typedef struct nrf_cli_static_entry nrf_cli_static_entry_t;
  85. /**
  86. * @brief CLI dynamic command descriptor.
  87. *
  88. * @details Function shall fill the received @ref nrf_cli_static_entry structure with requested (idx)
  89. * dynamic subcommand data. If there is more than one dynamic subcommand available,
  90. * the function shall ensure that the returned commands: p_static->p_syntax are sorted in
  91. * alphabetical order. If idx exceeds the available dynamic subcommands, the function must write
  92. * to p_static->p_syntax NULL value. This will indicate to the CLI module that
  93. * there are no more dynamic commands to read.
  94. */
  95. typedef void (*nrf_cli_dynamic_get)(size_t idx, nrf_cli_static_entry_t * p_static);
  96. /**
  97. * @brief CLI command descriptor.
  98. */
  99. struct nrf_cli_cmd_entry
  100. {
  101. bool is_dynamic;
  102. union
  103. {
  104. nrf_cli_dynamic_get p_dynamic_get; //!< Pointer to function returning dynamic commands.
  105. nrf_cli_static_entry_t const * p_static; //!< Pointer to array of static commands.
  106. } u;
  107. };
  108. /**
  109. * @brief CLI command handler prototype.
  110. */
  111. typedef void (*nrf_cli_cmd_handler)(nrf_cli_t const * p_cli, size_t argc, char **argv);
  112. /**
  113. * @brief CLI static command descriptor.
  114. */
  115. struct nrf_cli_static_entry
  116. {
  117. char const * p_syntax; //!< Command syntax strings.
  118. char const * p_help; //!< Command help string.
  119. nrf_cli_cmd_entry_t const * p_subcmd; //!< Pointer to subcommand.
  120. nrf_cli_cmd_handler handler; //!< Command handler.
  121. };
  122. /**
  123. * @brief Macro for defining and adding a root command (level 0).
  124. *
  125. * @note Each root command shall have unique syntax.
  126. *
  127. * @param[in] p_syntax Command syntax (for example: history).
  128. * @param[in] p_subcmd Pointer to a subcommands array.
  129. * @param[in] p_help Pointer to a command help string.
  130. * @param[in] p_handler Pointer to a function handler.
  131. */
  132. #define NRF_CLI_CMD_REGISTER(p_syntax, p_subcmd, p_help, p_handler) \
  133. nrf_cli_static_entry_t const CONCAT_3(nrf_cli_, p_syntax, _raw) = \
  134. NRF_CLI_CMD(p_syntax, p_subcmd, p_help, p_handler); \
  135. NRF_SECTION_ITEM_REGISTER(cli_command, \
  136. nrf_cli_cmd_entry_t const CONCAT_3(nrf_cli_, p_syntax, _const)) = { \
  137. .is_dynamic = false, \
  138. .u = {.p_static = &CONCAT_3(nrf_cli_, p_syntax, _raw)} \
  139. }; \
  140. NRF_SECTION_ITEM_REGISTER(cli_sorted_cmd_ptrs, char const * CONCAT_2(p_syntax, _str_ptr))
  141. /**
  142. * @brief Macro for creating a subcommand set. It must be used outside of any function body.
  143. *
  144. * @param[in] name Name of the subcommand set.
  145. */
  146. #define NRF_CLI_CREATE_STATIC_SUBCMD_SET(name) \
  147. /*lint -save -e85 -e31*/ \
  148. static nrf_cli_static_entry_t const CONCAT_2(name, _raw)[]; \
  149. static nrf_cli_cmd_entry_t const name = { \
  150. .is_dynamic = false, \
  151. .u = {.p_static = CONCAT_2(name, _raw) } \
  152. }; \
  153. static nrf_cli_static_entry_t const CONCAT_2(name, _raw)[] = /*lint -restore*/
  154. /**
  155. * @brief Define ending subcommands set.
  156. *
  157. */
  158. #define NRF_CLI_SUBCMD_SET_END {NULL}
  159. /**
  160. * @brief Macro for creating a dynamic entry.
  161. *
  162. * @param[in] name Name of the dynamic entry.
  163. * @param[in] p_get Pointer to the function returning dynamic commands array @ref nrf_cli_dynamic_get.
  164. */
  165. #define NRF_CLI_CREATE_DYNAMIC_CMD(name, p_get) \
  166. /*lint -save -e19*/ \
  167. static nrf_cli_cmd_entry_t const name = { \
  168. .is_dynamic = true, \
  169. .u = { .p_dynamic_get = p_get } \
  170. }; /*lint -restore*/
  171. /** @brief Macro for creating subcommands when C++ compiler is used.
  172. *
  173. * Example usage:
  174. * @code
  175. * NRF_CLI_CPP_CREATE_STATIC_SUBCMD_SET(cmd_syntax,
  176. * NRF_CLI_CMD(abc, ...),
  177. * NRF_CLI_CMD(def, ...),
  178. * NRF_CLI_SUBCMD_SET_END
  179. * );
  180. * @endcode
  181. */
  182. #define NRF_CLI_CPP_CREATE_STATIC_SUBCMD_SET(name, ...) \
  183. static nrf_cli_static_entry_t const CONCAT_2(name, _raw)[] = { \
  184. __VA_ARGS__ \
  185. }; \
  186. static nrf_cli_cmd_entry_t const name = { \
  187. .is_dynamic = false, \
  188. .u = { .p_static = CONCAT_2(name, _raw) } \
  189. }
  190. /**
  191. * @brief Initializes a CLI command (@ref nrf_cli_static_entry).
  192. *
  193. * @param[in] _p_syntax Command syntax (for example: history).
  194. * @param[in] _p_subcmd Pointer to a subcommands array.
  195. * @param[in] _p_help Pointer to a command help string.
  196. * @param[in] _p_handler Pointer to a function handler.
  197. */
  198. #define NRF_CLI_CMD(_p_syntax, _p_subcmd, _p_help, _p_handler) { \
  199. .p_syntax = (const char *) STRINGIFY(_p_syntax), \
  200. .p_help = (const char *) _p_help, \
  201. .p_subcmd = _p_subcmd, \
  202. .handler = _p_handler \
  203. }
  204. /**
  205. * @internal @brief Internal CLI state in response to data received from the terminal.
  206. */
  207. typedef enum
  208. {
  209. NRF_CLI_RECEIVE_DEFAULT,
  210. NRF_CLI_RECEIVE_ESC,
  211. NRF_CLI_RECEIVE_ESC_SEQ,
  212. NRF_CLI_RECEIVE_TILDE_EXP
  213. } nrf_cli_receive_t;
  214. /**
  215. * @internal @brief Internal CLI state.
  216. */
  217. typedef enum
  218. {
  219. NRF_CLI_STATE_UNINITIALIZED, //!< State uninitialized.
  220. NRF_CLI_STATE_INITIALIZED, //!< State initialized but not active.
  221. NRF_CLI_STATE_ACTIVE, //!< State active.
  222. NRF_CLI_STATE_PANIC_MODE_ACTIVE, //!< State panic mode activated.
  223. NRF_CLI_STATE_PANIC_MODE_INACTIVE //!< State panic mode requested but not supported.
  224. } nrf_cli_state_t;
  225. /**
  226. * @brief Event type from CLI transport.
  227. */
  228. typedef enum
  229. {
  230. NRF_CLI_TRANSPORT_EVT_RX_RDY,
  231. NRF_CLI_TRANSPORT_EVT_TX_RDY
  232. } nrf_cli_transport_evt_t;
  233. typedef void (*nrf_cli_transport_handler_t)(nrf_cli_transport_evt_t evt_type, void * p_context);
  234. typedef struct nrf_cli_transport_s nrf_cli_transport_t;
  235. /**
  236. * @brief Unified CLI transport interface.
  237. */
  238. typedef struct
  239. {
  240. /**
  241. * @brief Function for initializing the CLI transport interface.
  242. *
  243. * @param[in] p_transport Pointer to the transfer instance.
  244. * @param[in] p_config Pointer to instance configuration.
  245. * @param[in] evt_handler Event handler.
  246. * @param[in] p_context Pointer to the context passed to event handler.
  247. *
  248. * @return Standard error code.
  249. */
  250. ret_code_t (*init)(nrf_cli_transport_t const * p_transport,
  251. void const * p_config,
  252. nrf_cli_transport_handler_t evt_handler,
  253. void * p_context);
  254. /**
  255. * @brief Function for uninitializing the CLI transport interface.
  256. *
  257. * @param[in] p_transport Pointer to the transfer instance.
  258. *
  259. * @return Standard error code.
  260. */
  261. ret_code_t (*uninit)(nrf_cli_transport_t const * p_transport);
  262. /**
  263. * @brief Function for reconfiguring the transport to work in blocking mode.
  264. *
  265. * @param p_transport Pointer to the transfer instance.
  266. * @param blocking If true, the transport is enabled in blocking mode.
  267. *
  268. * @return NRF_SUCCESS on successful enabling, error otherwise (also if not supported).
  269. */
  270. ret_code_t (*enable)(nrf_cli_transport_t const * p_transport,
  271. bool blocking);
  272. /**
  273. * @brief Function for writing data to the transport interface.
  274. *
  275. * @param[in] p_transport Pointer to the transfer instance.
  276. * @param[in] p_data Pointer to the source buffer.
  277. * @param[in] length Source buffer length.
  278. * @param[in] p_cnt Pointer to the sent bytes counter.
  279. *
  280. * @return Standard error code.
  281. */
  282. ret_code_t (*write)(nrf_cli_transport_t const * p_transport,
  283. const void * p_data,
  284. size_t length,
  285. size_t * p_cnt);
  286. /**
  287. * @brief Function for reading data from the transport interface.
  288. *
  289. * @param[in] p_transport Pointer to the transfer instance.
  290. * @param[in] p_data Pointer to the destination buffer.
  291. * @param[in] length Destination buffer length.
  292. * @param[in] p_cnt Pointer to the received bytes counter.
  293. *
  294. * @return Standard error code.
  295. */
  296. ret_code_t (*read)(nrf_cli_transport_t const * p_transport,
  297. void * p_data,
  298. size_t length,
  299. size_t * p_cnt);
  300. } nrf_cli_transport_api_t;
  301. struct nrf_cli_transport_s
  302. {
  303. nrf_cli_transport_api_t const * p_api;
  304. };
  305. #if NRF_MODULE_ENABLED(NRF_CLI_HISTORY)
  306. /**
  307. * @brief CLI history object header.
  308. */
  309. typedef PACKED_STRUCT
  310. {
  311. nrf_memobj_t * p_prev; //!< Pointer to the next object.
  312. nrf_memobj_t * p_next; //!< Pointer to the previous object.
  313. nrf_cli_cmd_len_t cmd_len; //!< Command length.
  314. } nrf_cli_memobj_header_t;
  315. #endif
  316. #if NRF_MODULE_ENABLED(NRF_CLI_STATISTICS)
  317. typedef struct
  318. {
  319. uint32_t log_lost_cnt; //!< Lost log counter.
  320. } nrf_cli_statistics_t;
  321. #endif
  322. /**
  323. * @internal @brief Flags for internal CLI usage.
  324. */
  325. typedef struct
  326. {
  327. uint32_t insert_mode : 1; //!< Enables or disables console insert mode for text introduction.
  328. uint32_t show_help : 1; //!< Shows help if the command was called with -h or --help parameter.
  329. uint32_t use_colors : 1; //!< Enables or disables colored syntax.
  330. uint32_t echo : 1; //!< Enables or disables CLI echo.
  331. uint32_t processing : 1; //!< CLI is executing process function.
  332. uint32_t tx_rdy : 1;
  333. uint32_t last_nl : 8; //!< The last received newline character.
  334. } nrf_cli_flag_t;
  335. STATIC_ASSERT(sizeof(nrf_cli_flag_t) == sizeof(uint32_t));
  336. /**
  337. * @internal @brief Union for internal CLI usage.
  338. */
  339. typedef union
  340. {
  341. uint32_t value;
  342. nrf_cli_flag_t flag;
  343. } nrf_cli_internal_t;
  344. /**
  345. * @brief CLI instance context.
  346. */
  347. typedef struct
  348. {
  349. nrf_cli_state_t state; //!< Internal module state.
  350. nrf_cli_receive_t receive_state; //!< Escape sequence indicator.
  351. nrf_cli_static_entry_t active_cmd; //!< Currently executed command
  352. nrf_cli_vt100_ctx_t vt100_ctx; //!< VT100 color and cursor position, terminal width.
  353. nrf_cli_cmd_len_t cmd_buff_len; //!< Command length.
  354. nrf_cli_cmd_len_t cmd_buff_pos; //!< Command buffer cursor position.
  355. #if NRF_MODULE_ENABLED(NRF_CLI_WILDCARD)
  356. nrf_cli_cmd_len_t cmd_tmp_buff_len; //!< Command length in tmp buffer
  357. #endif
  358. char cmd_buff[NRF_CLI_CMD_BUFF_SIZE]; //!< Command input buffer.
  359. char temp_buff[NRF_CLI_CMD_BUFF_SIZE]; //!< Temporary buffer used by various functions.
  360. char printf_buff[NRF_CLI_PRINTF_BUFF_SIZE]; //!< Printf buffer size.
  361. #if NRF_MODULE_ENABLED(NRF_CLI_STATISTICS)
  362. nrf_cli_statistics_t statistics; //!< CLI statistics.
  363. #endif
  364. #if NRF_MODULE_ENABLED(NRF_CLI_USES_TASK_MANAGER)
  365. task_id_t task_id;
  366. #endif
  367. #if NRF_MODULE_ENABLED(NRF_CLI_HISTORY)
  368. nrf_memobj_t * p_cmd_list_head; //!< Pointer to the head of history list.
  369. nrf_memobj_t * p_cmd_list_tail; //!< Pointer to the tail of history list.
  370. nrf_memobj_t * p_cmd_list_element; //!< Pointer to an element of history list.
  371. #endif
  372. volatile nrf_cli_internal_t internal; //!< Internal CLI data
  373. } nrf_cli_ctx_t;
  374. extern const nrf_log_backend_api_t nrf_log_backend_cli_api;
  375. typedef struct
  376. {
  377. nrf_queue_t const * p_queue;
  378. void * p_context;
  379. nrf_cli_t const * p_cli;
  380. } nrf_cli_log_backend_t;
  381. #if NRF_CLI_LOG_BACKEND && NRF_MODULE_ENABLED(NRF_LOG)
  382. #define NRF_LOG_BACKEND_CLI_DEF(_name_, _queue_size_) \
  383. NRF_QUEUE_DEF(nrf_log_entry_t, \
  384. CONCAT_2(_name_, _queue),_queue_size_, NRF_QUEUE_MODE_NO_OVERFLOW); \
  385. static nrf_cli_log_backend_t CONCAT_2(cli_log_backend,_name_) = { \
  386. .p_queue = &CONCAT_2(_name_, _queue), \
  387. }; \
  388. NRF_LOG_BACKEND_DEF(_name_, nrf_log_backend_cli_api, &CONCAT_2(cli_log_backend,_name_))
  389. #define NRF_CLI_BACKEND_PTR(_name_) &CONCAT_2(_name_, _log_backend)
  390. #else
  391. #define NRF_LOG_BACKEND_CLI_DEF(_name_, _queue_sz_)
  392. #define NRF_CLI_BACKEND_PTR(_name_) NULL
  393. #endif
  394. #if NRF_MODULE_ENABLED(NRF_CLI_HISTORY)
  395. /* Header consists memory for cmd length and pointer to: prev and next element. */
  396. #define NRF_CLI_HISTORY_HEADER_SIZE (sizeof(nrf_cli_memobj_header_t))
  397. #define NRF_CLI_HISTORY_MEM_OBJ(name) \
  398. NRF_MEMOBJ_POOL_DEF(CONCAT_2(name, _cmd_hist_memobj), \
  399. NRF_CLI_HISTORY_HEADER_SIZE + \
  400. NRF_CLI_HISTORY_ELEMENT_SIZE, \
  401. NRF_CLI_HISTORY_ELEMENT_COUNT)
  402. #define NRF_CLI_MEMOBJ_PTR(_name_) &CONCAT_2(_name_, _cmd_hist_memobj)
  403. #else
  404. #define NRF_CLI_MEMOBJ_PTR(_name_) NULL
  405. #define NRF_CLI_HISTORY_MEM_OBJ(name)
  406. #endif
  407. /**
  408. * @brief CLI instance internals.
  409. *
  410. * @ref nrf_cli_t
  411. */
  412. struct nrf_cli
  413. {
  414. char const * const p_name; //!< Terminal name.
  415. nrf_cli_transport_t const * p_iface; //!< Transport interface.
  416. nrf_cli_ctx_t * p_ctx; //!< Internal context.
  417. nrf_log_backend_t const * p_log_backend; //!< Logger backend.
  418. nrf_fprintf_ctx_t * p_fprintf_ctx; //!< fprintf context.
  419. nrf_memobj_pool_t const * p_cmd_hist_mempool; //!< Memory reserved for commands history.
  420. };
  421. /**
  422. * @brief Macro for defining a command line interface instance.
  423. *
  424. * @param[in] name Instance name.
  425. * @param[in] cli_prefix CLI prefix string.
  426. * @param[in] p_transport_iface Pointer to the transport interface.
  427. * @param[in] newline_ch Deprecated parameter, not used any more. Any uint8_t value can be used.
  428. * @param[in] log_queue_size Logger processing queue size.
  429. */
  430. #define NRF_CLI_DEF(name, cli_prefix, p_transport_iface, newline_ch, log_queue_size) \
  431. static nrf_cli_t const name; \
  432. static nrf_cli_ctx_t CONCAT_2(name, _ctx); \
  433. NRF_FPRINTF_DEF(CONCAT_2(name, _fprintf_ctx), \
  434. &name, \
  435. CONCAT_2(name, _ctx).printf_buff, \
  436. NRF_CLI_PRINTF_BUFF_SIZE, \
  437. false, \
  438. nrf_cli_print_stream); \
  439. NRF_LOG_BACKEND_CLI_DEF(CONCAT_2(name, _log_backend), log_queue_size); \
  440. NRF_CLI_HISTORY_MEM_OBJ(name); \
  441. /*lint -save -e31*/ \
  442. static nrf_cli_t const name = { \
  443. .p_name = cli_prefix, \
  444. .p_iface = p_transport_iface, \
  445. .p_ctx = &CONCAT_2(name, _ctx), \
  446. .p_log_backend = NRF_CLI_BACKEND_PTR(name), \
  447. .p_fprintf_ctx = &CONCAT_2(name, _fprintf_ctx), \
  448. .p_cmd_hist_mempool = NRF_CLI_MEMOBJ_PTR(name), \
  449. } /*lint -restore*/
  450. /**
  451. * @brief Function for initializing a transport layer and internal CLI state.
  452. *
  453. * @param[in] p_cli Pointer to CLI instance.
  454. * @param[in] p_transport_config Configuration forwarded to the transport during initialization.
  455. * @param[in] use_colors Enables colored prints.
  456. * @param[in] log_backend If true, the console will be used as logger backend.
  457. * @param[in] init_lvl Default severity level for the logger.
  458. *
  459. * @return Standard error code.
  460. */
  461. ret_code_t nrf_cli_init(nrf_cli_t const * p_cli,
  462. void const * p_transport_config,
  463. bool use_colors,
  464. bool log_backend,
  465. nrf_log_severity_t init_lvl);
  466. ret_code_t nrf_cli_task_create(nrf_cli_t const * p_cli);
  467. /**
  468. * @brief Function for uninitializing a transport layer and internal CLI state.
  469. * If function returns NRF_ERROR_BUSY, you must call @ref nrf_cli_process before calling
  470. * nrf_cli_uninit again.
  471. *
  472. * @param p_cli Pointer to CLI instance.
  473. *
  474. * @return Standard error code.
  475. */
  476. ret_code_t nrf_cli_uninit(nrf_cli_t const * p_cli);
  477. /**
  478. * @brief Function for starting CLI processing.
  479. *
  480. * @param p_cli Pointer to the CLI instance.
  481. *
  482. * @return Standard error code.
  483. */
  484. ret_code_t nrf_cli_start(nrf_cli_t const * p_cli);
  485. /**
  486. * @brief Function for stopping CLI processing.
  487. *
  488. * @param p_cli Pointer to CLI instance.
  489. *
  490. * @return Standard error code.
  491. */
  492. ret_code_t nrf_cli_stop(nrf_cli_t const * p_cli);
  493. /**
  494. * @brief CLI colors for @ref nrf_cli_fprintf function.
  495. */
  496. #define NRF_CLI_DEFAULT NRF_CLI_VT100_COLOR_DEFAULT /**< Turn off character attributes. */
  497. #define NRF_CLI_NORMAL NRF_CLI_VT100_COLOR_WHITE /**< Normal color printf. */
  498. #define NRF_CLI_INFO NRF_CLI_VT100_COLOR_GREEN /**< Info color printf. */
  499. #define NRF_CLI_OPTION NRF_CLI_VT100_COLOR_CYAN /**< Option color printf. */
  500. #define NRF_CLI_WARNING NRF_CLI_VT100_COLOR_YELLOW /**< Warning color printf. */
  501. #define NRF_CLI_ERROR NRF_CLI_VT100_COLOR_RED /**< Error color printf. */
  502. /**
  503. * @brief Printf-like function which sends formatted data stream to the CLI.
  504. * This function shall not be used outside of the CLI module or CLI command context.
  505. *
  506. * @param[in] p_cli Pointer to the CLI instance.
  507. * @param[in] color Printf color.
  508. * @param[in] p_fmt Format string.
  509. * @param[in] ... List of parameters to print.
  510. */
  511. void nrf_cli_fprintf(nrf_cli_t const * p_cli,
  512. nrf_cli_vt100_color_t color,
  513. char const * p_fmt,
  514. ...);
  515. /**
  516. * @brief Print an info message to the CLI.
  517. *
  518. * See @ref nrf_cli_fprintf.
  519. *
  520. * @param[in] _p_cli Pointer to the CLI instance.
  521. * @param[in] _ft Format string.
  522. * @param[in] ... List of parameters to print.
  523. */
  524. #define nrf_cli_info(_p_cli, _ft, ...) \
  525. nrf_cli_fprintf(_p_cli, NRF_CLI_INFO, _ft "\n", ##__VA_ARGS__)
  526. /**
  527. * @brief Print a normal message to the CLI.
  528. *
  529. * See @ref nrf_cli_fprintf.
  530. *
  531. * @param[in] _p_cli Pointer to the CLI instance.
  532. * @param[in] _ft Format string.
  533. * @param[in] ... List of parameters to print.
  534. */
  535. #define nrf_cli_print(_p_cli, _ft, ...) \
  536. nrf_cli_fprintf(_p_cli, NRF_CLI_DEFAULT, _ft "\n", ##__VA_ARGS__)
  537. /**
  538. * @brief Print a warning message to the CLI.
  539. *
  540. * See @ref nrf_cli_fprintf.
  541. *
  542. * @param[in] _p_cli Pointer to the CLI instance.
  543. * @param[in] _ft Format string.
  544. * @param[in] ... List of parameters to print.
  545. */
  546. #define nrf_cli_warn(_p_cli, _ft, ...) \
  547. nrf_cli_fprintf(_p_cli, NRF_CLI_WARNING, _ft "\n", ##__VA_ARGS__)
  548. /**
  549. * @brief Print an error message to the CLI.
  550. *
  551. * See @ref nrf_cli_fprintf.
  552. *
  553. * @param[in] _p_cli Pointer to the CLI instance.
  554. * @param[in] _ft Format string.
  555. * @param[in] ... List of parameters to print.
  556. */
  557. #define nrf_cli_error(_p_cli, _ft, ...) \
  558. nrf_cli_fprintf(_p_cli, NRF_CLI_ERROR, _ft "\n", ##__VA_ARGS__)
  559. /**
  560. * @brief Process function, which should be executed when data is ready in the transport interface.
  561. *
  562. * @param[in] p_cli Pointer to the CLI instance.
  563. */
  564. void nrf_cli_process(nrf_cli_t const * p_cli);
  565. /**
  566. * @brief Option descriptor.
  567. */
  568. typedef struct nrf_cli_getopt_option
  569. {
  570. char const * p_optname; //!< Option long name.
  571. char const * p_optname_short; //!< Option short name.
  572. char const * p_optname_help; //!< Option help string.
  573. } nrf_cli_getopt_option_t;
  574. /**
  575. * @brief Option structure initializer @ref nrf_cli_getopt_option.
  576. *
  577. * @param[in] _p_optname Option name long.
  578. * @param[in] _p_shortname Option name short.
  579. * @param[in] _p_help Option help string.
  580. */
  581. #define NRF_CLI_OPT(_p_optname, _p_shortname, _p_help) { \
  582. .p_optname = _p_optname, \
  583. .p_optname_short = _p_shortname, \
  584. .p_optname_help = _p_help, \
  585. }
  586. /**
  587. * @brief Informs that a command has been called with -h or --help option.
  588. *
  589. * @param[in] p_cli Pointer to the CLI instance.
  590. *
  591. * @return True if help has been requested.
  592. */
  593. __STATIC_INLINE bool nrf_cli_help_requested(nrf_cli_t const * p_cli);
  594. #ifndef SUPPRESS_INLINE_IMPLEMENTATION
  595. __STATIC_INLINE bool nrf_cli_help_requested(nrf_cli_t const * p_cli)
  596. {
  597. return p_cli->p_ctx->internal.flag.show_help;
  598. }
  599. #endif
  600. /**
  601. * @brief Prints the current command help.
  602. * @details Function will print a help string with: the currently entered command, its options,
  603. * and subcommands (if they exist).
  604. *
  605. * @param[in] p_cli Pointer to the CLI instance.
  606. * @param[in] p_opt Pointer to the optional option array.
  607. * @param[in] opt_len Option array size.
  608. */
  609. void nrf_cli_help_print(nrf_cli_t const * p_cli,
  610. nrf_cli_getopt_option_t const * p_opt,
  611. size_t opt_len);
  612. /**
  613. * @internal @brief This function shall not be used directly, it is required by the
  614. * nrf_fprintf module.
  615. *
  616. * @param[in] p_user_ctx Pointer to the context for the CLI instance.
  617. * @param[in] p_data Pointer to the data buffer.
  618. * @param[in] data_len Data buffer size.
  619. */
  620. void nrf_cli_print_stream(void const * p_user_ctx, char const * p_data, size_t data_len);
  621. /** @} */
  622. #ifdef __cplusplus
  623. }
  624. #endif
  625. #endif /* NRF_CLI_H__ */