diff --git a/rt-thread-version/rt-thread-smart/_sidebar.md b/rt-thread-version/rt-thread-smart/_sidebar.md index 3e8e39f3f24006f04181911a1e3001defc7497b8..0c4dd4bd4b997b26d4a381fee9893fefad5b23ff 100644 --- a/rt-thread-version/rt-thread-smart/_sidebar.md +++ b/rt-thread-version/rt-thread-smart/_sidebar.md @@ -12,7 +12,7 @@ - 开发调试 - [使用VSCode调试用户态应用(Win)](/rt-thread-version/rt-thread-smart/debug/qemu-arm-win/qemu-arm-win.md) - - [smart插件的使用](/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/vsc-plug-in.md) + - [RT-Thread smart插件](/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/vsc-plug-in.md) diff --git a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/1.png b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/1.png deleted file mode 100644 index 7b6ed2c171bb707d78d34bb131ce541ab4b07d2c..0000000000000000000000000000000000000000 Binary files a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/1.png and /dev/null differ diff --git a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/10.png b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/10.png deleted file mode 100644 index 4aa6156fed6f248988dc2565f24774eaa5064f46..0000000000000000000000000000000000000000 Binary files a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/10.png and /dev/null differ diff --git a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/11.png b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/11.png deleted file mode 100644 index e1159d2ceb174d8fe5ff420423036c14ab755775..0000000000000000000000000000000000000000 Binary files a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/11.png and /dev/null differ diff --git a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/124.png b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/124.png deleted file mode 100644 index 36cf7577efceed5d995d45a550d80a296b14f453..0000000000000000000000000000000000000000 Binary files a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/124.png and /dev/null differ diff --git a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/132.png b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/132.png deleted file mode 100644 index c139114e3e810ccda21bfd36e15360999623ddd9..0000000000000000000000000000000000000000 Binary files a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/132.png and /dev/null differ diff --git a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/14.png b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/14.png deleted file mode 100644 index 62fe91c762c2bc212cf8355c07d0285e472c43c6..0000000000000000000000000000000000000000 Binary files a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/14.png and /dev/null differ diff --git a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/15.png b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/15.png deleted file mode 100644 index 59c7617856881bc6a48f38687a6960e277cb8ce5..0000000000000000000000000000000000000000 Binary files a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/15.png and /dev/null differ diff --git a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/16.png b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/16.png deleted file mode 100644 index c6556e01ff947563a8f0287e6a02f339d0f2efdf..0000000000000000000000000000000000000000 Binary files a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/16.png and /dev/null differ diff --git a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/17.png b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/17.png deleted file mode 100644 index 5486480ab3593b657f9b3fa8fb537fe18b01f303..0000000000000000000000000000000000000000 Binary files a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/17.png and /dev/null differ diff --git a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/18.png b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/18.png deleted file mode 100644 index 6fa6fefcdfb239e559413af5c736efa095e326f2..0000000000000000000000000000000000000000 Binary files a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/18.png and /dev/null differ diff --git a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/19.png b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/19.png deleted file mode 100644 index 13c6df71076f1d72077d7e78f434656b7bc5a4ef..0000000000000000000000000000000000000000 Binary files a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/19.png and /dev/null differ diff --git a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/2.png b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/2.png deleted file mode 100644 index 2303b9888af5c3c053624cb0195ab98576ea06e1..0000000000000000000000000000000000000000 Binary files a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/2.png and /dev/null differ diff --git a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/20.gif b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/20.gif deleted file mode 100644 index faaf1f9f71dc8037d3fdc327091220597b671038..0000000000000000000000000000000000000000 Binary files a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/20.gif and /dev/null differ diff --git a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/21.png b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/21.png deleted file mode 100644 index 72b66d0bd7bc476ba531f1a95c814adee153a818..0000000000000000000000000000000000000000 Binary files a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/21.png and /dev/null differ diff --git a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/22.gif b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/22.gif deleted file mode 100644 index 3f6580f1d46b757094257c1a6d12281216a7ed95..0000000000000000000000000000000000000000 Binary files a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/22.gif and /dev/null differ diff --git a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/3a.png b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/3a.png deleted file mode 100644 index fcc86e76532b2f06f5de757ab15007fe4b0705e2..0000000000000000000000000000000000000000 Binary files a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/3a.png and /dev/null differ diff --git a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/4.png b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/4.png deleted file mode 100644 index ba7f6f224f1e21da8cca119a1dc31a06ca3a351e..0000000000000000000000000000000000000000 Binary files a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/4.png and /dev/null differ diff --git a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/5.png b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/5.png deleted file mode 100644 index 61e5db091954068422f5d14282e3a28720c280eb..0000000000000000000000000000000000000000 Binary files a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/5.png and /dev/null differ diff --git a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/6.png b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/6.png deleted file mode 100644 index 70054f552ea47f1d59cf73d23aa5286eb498847a..0000000000000000000000000000000000000000 Binary files a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/6.png and /dev/null differ diff --git a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/7.png b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/7.png deleted file mode 100644 index 16f93a1d84e7db24383ae3856369b96ebf8c4ccf..0000000000000000000000000000000000000000 Binary files a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/7.png and /dev/null differ diff --git a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/8.png b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/8.png deleted file mode 100644 index 47a46437602a26a13c4154c25a170d7a41eae76c..0000000000000000000000000000000000000000 Binary files a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/8.png and /dev/null differ diff --git a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/9.png b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/9.png deleted file mode 100644 index a5c10b53f7e45388a18665de97502b4f52d9461a..0000000000000000000000000000000000000000 Binary files a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/9.png and /dev/null differ diff --git a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/creat-proj-1.png b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/creat-proj-1.png new file mode 100644 index 0000000000000000000000000000000000000000..b08fb4bceeca5ad049a9199b85147303b039add8 Binary files /dev/null and b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/creat-proj-1.png differ diff --git a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/creat-proj.png b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/creat-proj.png new file mode 100644 index 0000000000000000000000000000000000000000..01b255770d6054cfa9ab484a3c40784bccb5a98e Binary files /dev/null and b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/creat-proj.png differ diff --git a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/home-0.png b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/home-0.png new file mode 100644 index 0000000000000000000000000000000000000000..c02eb489a1a7c29f2a21ae5a4e998aa535a13554 Binary files /dev/null and b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/home-0.png differ diff --git a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/home.png b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/home.png new file mode 100644 index 0000000000000000000000000000000000000000..86285e3abe4d46d7330ffa3b5ffbead13fbfe30c Binary files /dev/null and b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/home.png differ diff --git a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/new-app.png b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/new-app.png new file mode 100644 index 0000000000000000000000000000000000000000..914ca2eb93750cc34f6383f12ad17387fc77465c Binary files /dev/null and b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/new-app.png differ diff --git a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/set-state-menu.png b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/set-state-menu.png new file mode 100644 index 0000000000000000000000000000000000000000..9c946930e54046a18ff8e7d514c2dc87facf0c4d Binary files /dev/null and b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/set-state-menu.png differ diff --git a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/smart-plugin.png b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/smart-plugin.png new file mode 100644 index 0000000000000000000000000000000000000000..7a268ed7802275d5d8907f1692ca20e5fab35717 Binary files /dev/null and b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/smart-plugin.png differ diff --git a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/state-menu.png b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/state-menu.png new file mode 100644 index 0000000000000000000000000000000000000000..707f38fac1b972a50ca1de7340ef3ac4ae452e0e Binary files /dev/null and b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/figures/state-menu.png differ diff --git a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/vsc-plug-in.md b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/vsc-plug-in.md index d47d76a39068c382f7f34bc68b910becb8326a2d..61fec6b1f84dae28a3066b03852741f7f422a877 100644 --- a/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/vsc-plug-in.md +++ b/rt-thread-version/rt-thread-smart/debug/vsc-plug-in/vsc-plug-in.md @@ -1,158 +1,104 @@ -# smart vscode 插件 +# RT-Thread Smart 插件 -RT-Thread 官方提供了 vscode 插件用来开发用户 app 代码。下面分享一下 Vscode 插件 ART-Pi Smart 的使用体验。 +为了使 RT-Thread Smart 开发者更方便的开发用户态应用,RT-Thread 开发了 VSCode 插件。包括下面的功能: -### 安装插件 +- SDK 管理界面(提供应用列表展示、下载工具链、创建应用工程等功能) -打开 vscode,在扩展中搜索 RT-Thread Smart +- 针对不用工程的快捷操作(如:编译工程、清理工程、安装并打包等) -![00.png](figures/4.png) +这些功能都以按钮的形式存在于 VSCode 的底部状态栏上,如下图所示: -### 创建工程 + ![image-20221019145632712](figures/home-0.png) -- 使用快捷键 `ctrl + shift + p`, 选择创建 RT-Thread Smart 工程 +其中 HOME 按钮对应的就是 SDK 管理界面,右侧的两个按钮(编译、清理)是针对 SDK 工程提供的快捷操作,对于不同的项目工程,右侧的快捷操作按钮可以自由定制。下面来详细介绍 Vscode 插件的各项功能。 - ![01.png](figures/5.png) +## 准备工作 -- 选择 RT-Thread Smart SDK 的根目录,回车 +- 下载 rt-thread: https://github.com/RT-Thread/rt-thread ,需要切换到 rt-smart 分支; - ![02.png](figures/6.png) +- 下载用户态应用程序: https://github.com/RT-Thread/userapps ; - gitee 下载下来的源码目录结构如下 +- 打开 VSCode,在扩展 (Ctrl+Shift+X) 中查找 RT-Thread Smart 插件并安装: - ![03.png](figures/7.png) + ![img](figures/smart-plugin.png) -- 新建一个 `hello`工程,回车 +## SDK 管理界面 - ![04.png](figures/8.png) +使用 VSCode 打开 userapps 目录(将打开该 userapps 目录的窗口称为主窗口),在底部的状态栏中有一些功能按钮,这里介绍常用的三个: -- 选择编译工具,目前 windows 下只有 scons。如果开发环境中没有安装 scons,需要使用命令 `pip install scons ` 安装 scons 工具。 +![image-20221019145632712](figures/home-0.png) - ![05.png](figures/9.png) +1. HOME:点击进入SDK 管理界面,该界面包含一些信息展示及常用功能,例如版本展示、创建工程等。 +2. 编译:点击编译,将执行 `scons` 命令,会编译 userapps/app 下所有的 app,并在 root/bin 中生成所有 app 的 `.elf` 可执行文件。 +3. 清理:点击清理,将执行 `scons -c` 命令,清除之前编译生成的文件。 -- 通过上面的步骤,一个用户 app 示例就创建完成了 +点击状态栏的 HOME 功能按钮后,将显示 SDK 管理界面,如下所示: - ![06.png](figures/10.png) +![](figures/home.png) -### 下载用户态代码 +**SDK 信息展示区**: -vscode 支持下载用户代码到 Smart 开发板。 +- 版本:RT-Smart 版本显示。 +- HOME:userapps 的路径,即用户态应用路径。 +- 内核:rt-thread 内核的路径,即可以编译 smart 的 bsp 路径,例如当前使用的 bsp 为:rt-thread\bsp\qemu-vexpress-a9,那么应当显示为该 bsp 的路径。 -- 在终端输入命令 `ifconfig` 获取开发板 IP 地址。这里的 MAC 在代码中是写死的,不知道为什么要使用这种方法。如果你的局域网中插入两块 Smart 开发板,可能会有问题,因为这两块开发板的 IP 地址是一样的。 +若内核路径不正确,请在 `userapps/.vscode/home.json` 中修改 kernel 项的文件路径,填入相对路径与绝对路径均可。 - ```shell - msh />ifconfig - network interface device: e1 (Default) - MTU: 1500 - MAC: a8 5e 45 91 92 93 - FLAGS: UP LINK_UP INTERNET_UP DHCP_ENABLE ETHARP BROADCAST IGMP - ip address: 192.168.110.34 - gw address: 192.168.110.1 - net mask : 255.255.255.0 - ipv6 link-local: FE80::AA5E:45FF:FE91:9293 VALID - ipv6[1] address: 0.0.0.0 INVALID - ipv6[2] address: 0.0.0.0 INVALID - dns server #0: 211.136.150.66 - dns server #1: 211.136.112.50 - - network interface device: w0 - MTU: 1500 - MAC: fc 58 4a 2c 50 01 - FLAGS: UP LINK_DOWN INTERNET_DOWN DHCP_ENABLE ETHARP BROADCAST IGMP - ip address: 0.0.0.0 - gw address: 0.0.0.0 - net mask : 0.0.0.0 - ipv6 link-local: FE80::FE58:4AFF:FE2C:5001 VALID - ipv6[1] address: 0.0.0.0 INVALID - ipv6[2] address: 0.0.0.0 INVALID - dns server #0: 211.136.150.66 - dns server #1: 211.136.112.50 - - network interface device: w1 - MTU: 1500 - MAC: fc 58 4a 2c 50 00 - FLAGS: UP LINK_DOWN INTERNET_DOWN DHCP_ENABLE ETHARP BROADCAST IGMP - ip address: 0.0.0.0 - gw address: 0.0.0.0 - net mask : 0.0.0.0 - ipv6 link-local: FE80::FE58:4AFF:FE2C:5000 VALID - ipv6[1] address: 0.0.0.0 INVALID - ipv6[2] address: 0.0.0.0 INVALID - dns server #0: 211.136.150.66 - dns server #1: 211.136.112.50 - ``` - -- 编译代码 - - ![08.png](figures/11.png) - -- 设置 IP 地址,使用快捷键 `ctrl + shift + p` 选择打开 RT-Thread Smart 设置 - - ![09.png](figures/124.png) - - 填入开发板 IP 地址,保存设置并退出 - - ![010.png](figures/132.png) - -- 下载代码 - - ![011.png](figures/14.png) - - 当终端显示以下界面时,表示代码下载成功 - - ![012.png](figures/15.png) +```json +"kernel": { + "folder": "/../rt-thread/bsp/qemu-vexpress-a9" +} +``` -- 运行可执行文件 +**功能区**: - ![013.png](figures/16.png) +- 创建工程:点击创建工程按钮创建新的工程,详见创建工程示例。 +- 打开终端:创建一个新的终端并打开。 +- 打开内核:打开内核代码。 -### 调试用户态代码 +**工具链**: -- 使用快捷键 `F5` 进入调试模式,可以在代码处设置断点 +- 点击下载按钮,自动下载安装 Windows 下所需的工具链。 - ![014.png](figures/17.png) +**应用列表区**: -- 可以使用快捷键 `F11` 进行单步调试 +- 模板应用:展示 userapps/app 目录下的模板应用。 +- 用户应用:展示使用 VSCode 新建在 userapps/workspse 目录下的用户应用。 +- 预编译:展示 userapps/prebuilt 目录下的已经预编译好的 bsp 文件,如 qemu-vexpress-a9 和 qemu-virt64-riscv。 -### UDB 工具 +应用列表区的应用都可以通过点击位置在 VSCode 新窗口中打开。 -在下载代码和调试代码时,在终端发现 vscode smart 插件使用的是一个叫 **udb** 的工具。udb 工具位于 **ART-Pi-smart\tools\udb-tools**。RT-Thread 提供了windows 和 linux 两个版本的 udb 工具。 +## 快捷操作按钮 -![015.png](figures/18.png) +在不同的工程下,VSCode 底部的快捷按钮是不同的,在主窗口,提供的是针对 userapps sdk 的一些快捷操作,编译所有应用,清理所有应用等。在每个具体的应用工程下,也提供类似的快捷操作。 -windows 下目录结构: +在应用列表区打开模板应用或者用户应用,会创建一个新的 VSCode 窗口(将该窗口称为应用窗口),可以把应用窗口底部的状态栏称为应用窗口状态栏。如点击模板应用中的 hello(或者其他均可): -- server.log :udb 的运行日志 -- udb.exe :可执行文件 -- udb.ini :tcp 配置文件,保存了 smart 开发板的 ip 地址 +![](figures/new-app.png) -#### udb 命令 +该应用窗口的状态栏有 HOME、编译、清理、安装并打包、下载功能按钮: +- 编译:仅编译当前 app,点击编译后,在当前 app 路径下生成对应的单个 `.elf` 文件。 +- 安装并打包:将上述编译的单个 `.elf` 文件复制一份到 root/bin 路径下。 +- 下载:针对拥有 udb 服务的内核提供下载功能,一般用户用不到。 -在该目录下打开 windows 终端,输入命令 `udb.exe --help ` 查看 udb 命令。 +用户也可以自定义当前工程的快捷操作按钮,通过修改当前工程目录下 `.vscode/smart.json` 文件。 -![016.png](figures/19.png) +## 创建工程 -#### udb devices +在 SDK 管理界面,点击创建工程。 -查看当前 udb 链路设备 +填入 SDK 根目录,即 userapps 用户态应用的上级目录(例如:实际路径为 `F:\2-daily-work\2022\06.smart\userapps`,则填入 `F:\2-daily-work\2022\06.smart`),回车;之后输入工程名如 test_app,回车;选择编译工具为 SCons;选择在新窗口或当前窗口打开应用。 -```bash -PS D:\repo\gitee\ART-Pi-smart\tools\udb-tools\windows> .\udb.exe devices -List of devices attached -serial mtu version state -192.168.110.34:5555 1024 2.0.0 active -``` +![creat-proj-1](figures/creat-proj-1.png) -#### udb push +这样就在 `userapps\workspace` 中创建了一个 test_app 工程,用户可以在该工程中开发应用。 -推送本地文件到远端设备 +## FAQ -![7.gif](figures/20.gif) +Q: VSCode 底部状态栏未显示。 -![018.png](figures/21.png) +A: 如果下方没有显示状态栏,可以通过左下角 “管理 - 设置”,在搜索栏输入 “状态栏” 并重新勾选, 这样状态栏将重新显示在底部。 -#### udb pull +![](figures/set-state-menu.png) -拉取远端文件到本地 -![8.gif](figures/22.gif) \ No newline at end of file