LV01-01-AliOSThings-13-CLI组件-02-CLI的使用方法

本文主要是CLI(command line)组件——CLI使用方法的相关笔记,若笔记中有错误或者不合适的地方,欢迎批评指正😃。

点击查看使用工具及版本
Windows版本 windows11
Ubuntu版本 Ubuntu22.04的64位版本
VMware® Workstation 16 Pro 16.2.3 build-19376536
终端软件 MobaXterm(Professional Edition v23.0 Build 5042 (license))
点击查看本文参考资料
分类 网址 说明
官方网站 阿里云 阿里云官网主页
阿里生活物联平台 生活物联网平台(飞燕平台)主页
AliGenie 天猫精灵开放平台AliGenie主页
阿里物联网平台 阿里物联网平台主页
Bluetooth 技术网站 蓝牙协议规范什么的可以来这里找
Telink Telink | Chips for a Smarter IoT (telink-semi.com)
Telink中文官网
开发手册 AliOS Things开发指南 AliOS Things开发指南,这里是最新版本,可以直接从官网找到
AliOS Things开发指南 AliOS Things应用开发指南,这里应该是3.3版本的完整开发文档
AliOS Things开发指南(3.0) AliOS Things应用开发指南,这里应该是3.0版本的完整开发文档
生活物联网平台开发文档 生活物联网平台(飞燕平台)开发文档
《设备端开发指南》
Wi-Fi IoT品类定义与功能开发 天猫精灵IoT开放平台——Wi-Fi IoT品类定义与功能开发
硬件平台 mk3080 WiFi开发板 WiFi开发板使用指南-阿里云开发者社区
esp8266开发板 一个教程:ESP8266-NodeMCU开发板详解-太极创客 (taichi-maker.com)
TLSR8258 Datasheet Datasheet for Telink BLE + IEEE802.15.4 MultiStandard Wireless SoC TLSR8258
参考资料 AliOS Things 3.0 应用开发指南 这个只是一篇参考文章,里面是一些环境搭建相关的,可以参考
IP知识百科 - 华为 (huawei.com) IP的一些相关知识点
点击查看相关文件下载
分类 网址 说明
蓝牙规范相关文档 Core Specification 5.2 核心规格 5.2,该规范定义了创建可互操作的Bluetooth 设备所需的技术。
《Core_v5.2.pdf》
Mesh Model(v1.1) 本Bluetooth 规范定义了模型(以及它们所需的状态和消息),这些模型用于在mesh 网络中的节点上执行基本功能,超出了Bluetooth Mesh 配置文件 规范中定义的基础模型。
本规范包括定义跨设备类型标准功能的通用模型,以及支持关键mesh 场景的模型,如照明控制、传感器、时间和场景。
《MshMDL_v1.1.pdf》
Mesh Profile(v1.0.1) 该Bluetooth 规范定义了基本要求,以实现可互操作的mesh 网络解决方案,用于Bluetooth 低能量无线技术。
《MshPRFv1.0.1.pdf》
Mesh Device Properties 本规范包含Bluetooth Mesh 配置文件 和Bluetooth Mesh 模型规范所要求的设备属性的定义。
但是跟之前的有些区别,我主要看的之前的版本:《MMeshDeviceProperties_v1.2.pdf》
GATT Specification Supplement GATT Specification Supplement | Bluetooth® Technology Website。
好像可以在线看:《GATT Specification Supplement》
Assigned Numbers GATT的一些类型定义可以在这里找。
AliOS Things alios-things/AliOS-Things Gitee上的AliOSThings SDK源码仓库
alibaba/AliOS-Things GitHub上的AliOSThings SDK源码仓库
天猫精灵蓝牙Mesh协议栈 alibaba-archive/genie-bt-mesh-stack GitHub上的天猫精灵蓝牙Mesh协议栈源码仓库。
之前是在alibaba/genie-bt-mesh-stack这个仓库。
写笔记的时候最新提交为faf523618a6a2560090fc423222b9db80984bb7a
蓝牙Mesh设备开发指南 阿里云生活服务平台开发手册——蓝牙设备开发一节中的内容

一、官方文档

1. CLI组件简介

image-20201009150540044

2. 有哪些API?

image-20201009150733592

这些API都在 AOS_SDK_PATH/include/aos/cli.h 中声明。

3. CLI运行基本原理

image-20201009150927704

4. CLI实现基本原理

基本的原理如下图所示:

cli任务

大概的原理是这样的:

image-20201009151811195

实际的cli组件,其实是rhino操作系统下的一个任务,这个任务函数名称为cli_main(AOS_SDK_PATH/core/cli/cli.c):

image-20231207222323585

然后在这个任务中队我们从串口输入的数据进行处理和解析,然后执行相应的命令。

二、CLI的API分析

1. aos_cli_init()

这个函数是CLI组件的初始化函数,它定义在AOS_SDK_PATH/core/cli/cli.c中:

image-20201009170057784

2. aos_cli_register_command()

它定义在AOS_SDK_PATH/core/cli/cli.c中:

image-20201009170243761

3. aos命令功能分析

image-20201009170608166

4. cli_command 结构体

4.1 name与help成员

image-20201009170744038

4.2 function函数指针

image-20201009170934174
  • outbuf&&len参数
image-20201009171820298
  • argc&&argv参数
1

cli组件会帮助我们做一些字符串的解析工作,会给我们两个参数就是argc和argv:

argc:表示有多少个字符串

argv:这是一个字符串数组,传入的字符串参数都会存放在这里面。

三、官方demo

我们来分析一下 AOS_SDK_PATH/application/example/debug_demo/debug_app.c。

1. aos_cli_init()的调用

我们先打开AOS_SDK_PATH/application/example/debug_demo/maintask.c,会看到如下代码:

1
2
3
4
5
6
7
8
9
10
void aos_maintask(void* arg)
{
board_init();
board_kinit_init(&kinit);
aos_components_init(&kinit);

#ifndef AOS_BINS
application_start(kinit.argc, kinit.argv); /* jump to app entry */
#endif
}

我们打开这个aos_components_init()函数():

1
2
3
4
5
6
7
8
9
10
11
//AOS_SDK_PATH/core/init/aos_init.c

int aos_components_init(kinit_t *kinit)
{
//中间部分省略......
#ifdef AOS_COMP_CLI
cli_service_init(kinit);
#endif
//中间部分省略......
return 0;
}

我们继续追踪这个 cli_service_init()

1
2
3
4
5
6
7
8
9
10
//AOS_SDK_PATH/core/init/aos_init.c
void cli_service_init(kinit_t *kinit)
{
if (kinit->cli_enable)
{
aos_cli_init();
//中间部分省略......
}
return;
}

可以看到在这里调用了 aos_cli_init()对CLI组件进行初始化。

2. debug_cmd_init()

接下来就是debug_cmd_init()函数了,我们看一下它做了什么:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//AOS_SDK_PATH/application/example/debug_demo/debug_app.c

static int debug_cmd_init(void)
{
int ret;

static struct cli_command debug_ins[] = {
{ "debug","show debug api", debug_cmd },
};

ret = aos_cli_register_commands(debug_ins, sizeof(debug_ins)/sizeof(struct cli_command));
if (ret) {
return ret;
}

return 0;
}

可以看到它主要是通过aos_cli_register_commands()函数注册了一个cli_command类型的命令,它们是这样对应的:

1
2
3
4
5
6
7
/* This struct is used to define the cli cmd format */
struct cli_command {
const char *name; /* "debug" */
const char *help; /* "show debug api" */

void (*function)(char *outbuf, int len, int argc, char **argv); /* static void debug_cmd(char *buf, int32_t len, int32_t argc, char **argv); */
};

3. debug_cmd()

这个函数主要就是用来解析参数啦:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
static void debug_cmd(char *buf, int32_t len, int32_t argc, char **argv)
{
unsigned int reason;

if (argc == 2) {
if (strcmp(argv[0], "debug")) {
printf("debug app cmd err\r\n");
return;
}

if (strcmp(argv[1], "help") == 0) {
debug_help_show();
} else if (strcmp(argv[1], "1") == 0) {
aos_debug_mm_overview(NULL);
} else if (strcmp(argv[1], "2") == 0) {
aos_debug_task_overview(NULL);
} else if (strcmp(argv[1], "3") == 0) {
aos_debug_buf_queue_overview(NULL);
} else if (strcmp(argv[1], "4") == 0) {
aos_debug_queue_overview(NULL);
} else if (strcmp(argv[1], "5") == 0) {
aos_debug_sem_overview(NULL);
} else if (strcmp(argv[1], "6") == 0) {
aos_debug_backtrace_now();
} else if (strcmp(argv[1], "7") == 0) {
aos_debug_backtrace_task("main_task");
} else if (strcmp(argv[1], "8") == 0) {
reason = aos_debug_reboot_reason_get();
switch (reason) {
case 1:
printf("watchdog trig\r\n");
break;
case 2:
printf("system coredump\r\n");
break;
case 3:
printf("system repower\r\n");
break;
case 4:
printf("syste, fatal err\r\n");
break;
default:
printf("system repower\r\n");
break;
}
} else if (strcmp(argv[1], "all") == 0) {
aos_debug_overview();
} else {
printf("debug app cmd not exist\r\n");
}
} else {
printf("debug app para err\r\n");
}
}

这里就是在解析不同的参数,然后执行对应的命令。