1@page cli cli
2
3[更正文档](https://gitee.com/alios-things/cli/edit/master/README.md)      [贡献说明](https://help.aliyun.com/document_detail/302301.html)
4
5# 概述
6在日常嵌入式开发中,用户经常会自行实现一套类似Linux Shell的交互工具来实现通过串口命令控制设备进入某种特定的状态,或执行某个特定的操作。如系统自检,模拟运行,或者进入手动模式进行设备点动。AliOS Things原生实现了一套名为CLI(Command-Line Interface)的命令行交互工具,在提供基本的系统交互命令的基础上,也支持用户自定义命令。
7组件支持以下功能:
8- cli commands register
9- cli commands unregister
10- cli commands show
11- fs cmds support
12## 版权信息
13> Apache license v2.0
14
15## 目录结构
16```tree
17├── include
18│   └── aos
19│       └── cli.h        # cli的对外AOS API
20├── package.yaml         # 编译配置文件
21├── README.md
22└── src
23    ├── cli_adapt.c      # cli适配层
24    ├── cli_adapt.h
25    ├── cli_aos.c        # cli-aos接口层
26    ├── cli_api.h
27    ├── cli.c            # cli核心管理
28    ├── cli_console.c    # cli console管理
29    ├── cli_console.h
30    ├── uart_console.c   # cli使用Uart串口输入输出(默认方式)
31    ├── telnet_console.c # cli使用telnet局域网输入输出(可选方式)
32    ├── cli_uagent.c     # cli使用远程调试终端输入输出(可选方式)
33    ├── iobox            # 文件系统操作命令集
34    │   ├── cat.c
35    │   ├── cd.c
36    │   ├── cp.c
37    │   ├── df.c
38    │   ├── echo.c
39    │   ├── hexdump.c
40    │   ├── ls.c
41    │   ├── lsfs.c
42    │   ├── mkdir.c
43    │   ├── mv.c
44    │   ├── path_helper.c
45    │   ├── path_helper.h
46    │   ├── pwd.c
47    │   ├── rm.c
48    │   └── touch.c
49```
50
51## 依赖组件
52* rhino
53* driver
54* vfs(使用文件系统操作命令)
55* littlefs(使用文件系统操作命令)
56
57
58# 常用配置
59系统中相关配置已有默认值,如需修改配置,在相应app下的package.yaml中**def_config**节点修改。例如:若运行的app为helloworld_demo,则在helloworld_demo下的package.yaml中修改:
60> cli 输入缓冲区大小: 默认256 bytes,即cli单次可接收的输入最大字节数
61```yaml
62def_config:
63  CLI_INBUF_SIZE: 256
64```
65> cli 输出缓冲区大小: 默认512 bytes,即cli命令中单个printf输出的最大字节数
66```yaml
67def_config:
68  CLI_OUTBUF_SIZE: 512
69```
70> 可注册的cli命令最大值,默认最多可注册128个命令(通过help命令查看)
71```yaml
72def_config:
73  CLI_MAX_COMMANDS: 128
74```
75> 单个cli命令可带参数的最大值,默认最多可带16个参数
76```yaml
77def_config:
78  CLI_MAX_ARG_NUM: 16
79```
80> 可连续执行的cli命令数量(命令中间用分号;间隔),默认为4个
81```yaml
82def_config:
83  CLI_MAX_ONCECMD_NUM: 4
84```
85> cli后台任务的优先级,默认为60
86```yaml
87def_config:
88  CLI_TASK_PRIORITY: 60
89```
90> cli后台任务的栈大小,默认为2KB(2048Bytes)
91```yaml
92def_config:
93  CLI_CONFIG_STACK_SIZE: 2048
94```
95> cli使用telnet接管输入输出,此功能默认不开
96```yaml
97def_config:
98  CLI_TELNET_ENABLE: 0
99```
100> cli使用uagent接管输入输出,即cli日志输入输出在远程诊断终端上,此功能默认不开
101```yaml
102def_config:
103  CLI_UAGENT_ENABLE: 0
104```
105
106> cli输出增加不可见字符,用于SmartTrace工具中,此功能默认关闭
107```yaml
108def_config:
109  CLI_SEPRATED_CONSOLE: 0
110```
111
112> cli使能文件系统操作命令,此功能默认不开
113```yaml
114def_config:
115  CLI_IOBOX_ENABLE: 0
116```
117# API说明
118- 参考 [cli_aos_api](https://dev.g.alicdn.com/alios-things-3.3/doc/group__cli__aos__api.html)
119
120# 使用示例
121
122组件使用示例相关的代码下载、编译和固件烧录均依赖AliOS Things配套的开发工具,所以首先需要参考[《AliOS Things集成开发环境使用说明之搭建开发环境》](https://help.aliyun.com/document_detail/302378.html),下载安装。
123待开发环境搭建完成后,可以按照以下步骤进行示例的测试。
124
125
126## 步骤1 创建或打开工程
127
128**打开已有工程**
129
130如果用于测试的案例工程已存在,可参考[《AliOS Things集成开发环境使用说明之打开工程》](https://help.aliyun.com/document_detail/302381.html)打开已有工程。
131
132**创建新的工程**
133
134组件的示例代码可以通过编译链接到AliOS Things的任意案例(solution)来运行,这里选择helloworld_demo案例。helloworld_demo案例相关的源代码下载可参考[《AliOS Things集成开发环境使用说明之创建工程》](https://help.aliyun.com/document_detail/302379.html)135
136
137## 步骤2 添加组件
138
139案例下载完成后,以运行helloworld_demo为例,需要在helloworld_demo组件的package.yaml中添加对组件的依赖:
140
141```yaml
142
143depends:
144  - cli: master  # helloworld_demo中引入cli组件
145
146```
147
148## 步骤3 下载组件
149
150在已安装了  的开发环境工具栏中,选择Terminal -> New Terminal启动终端,并且默认工作路径为当前工程的workspace,此时在终端命令行中输入:
151
152```shell
153
154aos install cli
155
156```
157
158上述命令执行成功后,组件源码则被下载到了./components/cli路径中。
159
160## 步骤4 添加示例
161
162下面示例演示了注册cli命令的三种方式,分别是:
1631. 注册单个cli命令
1642. 同时注册对个cli命令
1653. 通过宏注册单个cli命令
166
167Example:
168包含头文件 **#include "aos/cli.h"**
169
170> 注册命令方式1:注册单个cli命令
171```C
172int ret;
173void test_cmd(char *buf, int32_t len, int32_t argc, char **argv)
174{
175    /* test_cmd 命令实现 */
176    aos_cli_printf("this is test cmd\r\n");
177}
178
179const struct cli_command cmd = {"test", "test cmd description", test_cmd};
180
181ret = aos_cli_register_command(&cmd);
182if (ret) {
183  /* 错误处理 */
184  aos_cli_printf("test cmd register fail\r\n");
185}
186```
187
188> 注册命令方式2:同时注册多个cli命令
189```C
190int ret;
191void test1_cmd(char *buf, int32_t len, int32_t argc, char **argv)
192{
193    /* test_cmd 命令实现 */
194    aos_cli_printf("this is test cmd1\r\n");
195}
196
197void test2_cmd(char *buf, int32_t len, int32_t argc, char **argv)
198{
199    /* test_cmd 命令实现 */
200    aos_cli_printf("this is test cmd2\r\n");
201}
202
203const struct cli_command cmds[] = {
204     { "test1", "show test1 info", test1_cmd },
205     { "test2", "show test2 info", test2_cmd },
206};
207
208ret = aos_cli_register_commands(&cmds, sizeof(cmds) / sizeof(struct cli_command));
209if (ret) {
210    /* 错误处理 */
211    aos_cli_printf("test cmds register fail\r\n");
212}
213```
214
215> 注册命令方式3:通过宏注册单个cli命令
216> 注意:这种方式不需要判断返回值,若注册失败,系统在初始化过程中会输出相应信息
217```C
218void test_cmd3(int32_t argc, char **argv)
219{
220    /* test_cmd3 命令实现 */
221    aos_cli_printf("this is test cmd3\r\n");
222}
223
224/* 宏的参数说明:
225 * 参数1. cmd具体实现
226 * 参数2. 在串口下输入的命令
227 * 参数3. cmd的描述信息
228 */
229ALIOS_CLI_CMD_REGISTER(test_cmd3, test3, show test3 info)
230```
231**代码示例**
232helloworld_demo注册cli命令,修改helloworld.c如下:
233```C
234#include "aos/init.h"
235#include "board.h"
236#include <aos/errno.h>
237#include <aos/kernel.h>
238#include <k_api.h>
239#include <stdio.h>
240#include <stdlib.h>
241#include "aos/cli.h" /* 加上头文件 */
242
243void test_cmd(char *buf, int32_t len, int32_t argc, char **argv)
244{
245    /* test_cmd 命令实现 */
246    aos_cli_printf("this is test cmd\r\n");
247}
248
249void test1_cmd(char *buf, int32_t len, int32_t argc, char **argv)
250{
251    /* test_cmd 命令实现 */
252    aos_cli_printf("this is test cmd1\r\n");
253}
254
255void test2_cmd(char *buf, int32_t len, int32_t argc, char **argv)
256{
257    /* test_cmd 命令实现 */
258    aos_cli_printf("this is test cmd2\r\n");
259}
260
261const struct cli_command cmd = {"test", "test cmd description", test_cmd};
262
263const struct cli_command cmds[] = {
264     { "test1", "show test1 info", test1_cmd },
265     { "test2", "show test2 info", test2_cmd },
266};
267
268
269int application_start(int argc, char *argv[])
270{
271    int count = 0;
272    int ret;
273
274    printf("nano entry here!\r\n");
275
276    ret = aos_cli_register_command(&cmd);
277    if (ret) {
278      /* 错误处理 */
279      aos_cli_printf("test cmd register fail\r\n");
280    }
281
282    ret = aos_cli_register_commands(&cmds, sizeof(cmds) / sizeof(struct cli_command));
283    if (ret) {
284        /* 错误处理 */
285        aos_cli_printf("test cmds register fail\r\n");
286    }
287
288    while (1) {
289        //printf("hello world! count %d \r\n", count++);
290        aos_msleep(1000);
291    };
292}
293
294void test_cmd3(int32_t argc, char **argv)
295{
296    /* test_cmd3 命令实现 */
297    aos_cli_printf("this is test cmd3\r\n");
298}
299
300/* 宏的参数说明:
301 * 参数1. cmd具体实现
302 * 参数2. 在串口下输入的命令
303 * 参数3. cmd的描述信息
304 */
305ALIOS_CLI_CMD_REGISTER(test_cmd3, test3, show test3 info)
306```
307
308## 步骤5 编译固件
309
310在示例代码已经添加至组件的配置文件,并且helloworld_demo已添加了对该组件的依赖后,就可以编译helloworld_demo案例来生成固件了,具体编译方法可参考[《AliOS Things集成开发环境使用说明之编译固件》](https://help.aliyun.com/document_detail/302384.html)311
312## 步骤6 烧录固件
313
314helloworld_demo案例的固件生成后,可参考[《AliOS Things集成开发环境使用说明之烧录固件》](https://help.aliyun.com/document_detail/302383.html)来烧录固件。
315
316## 步骤7 打开串口
317
318固件烧录完成后,可以通过串口查看示例的运行结果,打开串口的具体方法可参考[《AliOS Things集成开发环境使用说明之查看日志》](https://help.aliyun.com/document_detail/302382.html)319
320
321## 步骤8 测试示例
322
323**CLI命令行输入:**
324```shell
325help
326```
327
328> 可以看到注册的命令:
329```shell
330test
331test1
332test2
333test3
334```
335执行不同的命令,有相应的日志输出
336
337# FAQ
338Q1: 如何打开文件系统操作命令集?
339答:
340cli组件支持文件系统操作命令,默认关闭,打开方式为:
341以运行helloworld_demo为例,在其package.yaml中添加
342
343```yaml
344def_config:
345  CLI_IOBOX_ENABLE: 1
346```
347
348然后重新编译烧录,上电后输入help,即可看到
349ls
350ll
351mkdir
352cat
353df
354touch
355...
356等文件系统命令
357
358
359Q2:文件系统命令如何使用?
360答:
361cli组件支持文件系统操作命令,使用方法类似Linux常见shell命令,简单举例如下:
362
363lsfs - 列出当前系统注册的文件系统节点
364命令显示:
365/data
366表示当前文件系统(littlefs)注册的节点为/data
367
368df - 显示文件系统当前使用情况(单位:KB)
369命名显示:
370     Total      Used      Free   Use%    Mount
371      4792      2416      2376    50%    /data
372可以查看/data下文件的使用情况
373
374mkdir - 创建文件夹
375mkdir /data/123
376ll /data (或者 ls -l /data)
377命令显示:
378drwxrwxrwx root root 0B .
379drwxrwxrwx root root 0B ..
380drwxrwxrwx root root 0B aaa
381-rwxrwxrwx root root 21B demo
382drwxrwxrwx root root 0B font
383drwxrwxrwx root root 0B lib
384(注意:当前尚不支持可读/可写/可执行等权限设置)
385
386touch - 创建单个文件
387cd /data/aaa
388touch 123.txt
389ll
390命令显示:
391drwxrwxrwx root root 0B .
392drwxrwxrwx root root 0B ..
393-rwxrwxrwx root root 0B 123.txt
394
395pwd - 显示当前路径
396命令显示:
397/data/aaa
398
399echo
4001. 显示普通字符串:
401echo "hello,world!"
402
4032. 显示结果定向至文件
404echo "alibaba" > /data/aaa/123.txt
405cat /data/aaa/123.txt
406命令显示:
407alibaba
408
409