docs: 优化目录,完成第二章文档
94
README.md
@@ -39,39 +39,40 @@
|
||||
|
||||
### 当前进度:
|
||||
|
||||
| 章节 | 教程 | 文字教程 | 视频教程 | 配套代码 |
|
||||
| -------------- | ---------------------- | :--: | :--: | :--: |
|
||||
| 一、认识ESP32 | 1.1 ESP32介绍 | ✔ | ✔ | 无 |
|
||||
| 一、认识ESP32 | 1.2 ESP32开发环境搭建 | ✔ | ✔✔✔ | 无 |
|
||||
| 一、认识ESP32 | 1.3 初试ESP32-HelloWorld | ✔ | | |
|
||||
| 二、IDF基础与工具使用 | 2.1 ESP32工程结构及构建 | ✔ | | |
|
||||
| 二、IDF基础与工具使用 | 2.2 ESP-IDF项目配置 | ✔ | | |
|
||||
| 二、IDF基础与工具使用 | 2.3 ESP-IDF自定义组件 | ✔ | | |
|
||||
| 二、IDF基础与工具使用 | 2.4 ESP-IDF组件管理器 | ✔ | | |
|
||||
| 三、FreeRTOS基础 | 3.1 FreeRTOS概述 | | | |
|
||||
| 三、FreeRTOS基础 | 3.2 FreeRTOS多任务与任务管理 | | | |
|
||||
| 四、外设学习 | 4.1.1 GPIO入门 | | | |
|
||||
| 四、外设学习 | 4.1.2 UART串口通信 | | | |
|
||||
| 四、外设学习 | 4.1.3 硬件定时器 | | | |
|
||||
| 四、外设学习 | 4.1.4 ADC模数转换 | | | |
|
||||
| 四、外设学习 | 4.1.5 DAC数模转换 | | | |
|
||||
| 四、外设学习 | 4.1.6 LED PWM控制 | | | |
|
||||
| 四、外设学习 | 4.1.7 I2C通信 | | | |
|
||||
| 四、外设学习 | 4.1.8 SPI通信 | | | |
|
||||
| 四、外设学习 | 4.2.1 分区表设计 | | | |
|
||||
| 四、外设学习 | 4.2.2 非易失性存储 | | | |
|
||||
| 四、外设学习 | 4.2.3 FAT文件系统 | | | |
|
||||
| 四、外设学习 | 4.2.4 SPIFFS文件系统 | | | |
|
||||
| 五、FreeRTOS进阶 | 5.1 FreeRTOS队列使用教程 | | | |
|
||||
| 五、FreeRTOS进阶 | 5.2 FreeRTOS信号量教程 | | | |
|
||||
| 五、FreeRTOS进阶 | 5.3 FreeRTOS互斥量教程 | | | |
|
||||
| 五、FreeRTOS进阶 | 5.4 FreeRTOS事件组教程 | | | |
|
||||
| 五、FreeRTOS进阶 | 5.5 FreeRTOS任务通知教程 | | | |
|
||||
| 五、FreeRTOS进阶 | 5.6 FreeRTOS软件定时器教程 | | | |
|
||||
| 六、Wi-Fi功能与相关协议 | 6.1.1 Wi-Fi模式与基础操作 | | | |
|
||||
| 六、Wi-Fi功能与相关协议 | 6.1.2 Wi-Fi STA与AP配置 | | | |
|
||||
| 六、Wi-Fi功能与相关协议 | 6.2.1 TCP协议应用 | | | |
|
||||
| 六、Wi-Fi功能与相关协议 | 6.2.2 UDP协议应用 | | | |
|
||||
| 章节 | 教程 | 文字教程 | 视频教程 | 配套代码 | 完成日期 |
|
||||
| -------------- | -------------------- | :--: | :--: | :--: | ---------- |
|
||||
| 一、认识ESP32 | 1.1 ESP32介绍 | ✔ | ✔ | 无 | 2025/1/3 |
|
||||
| 一、认识ESP32 | 1.2 ESP32开发环境搭建 | ✔ | ✔✔✔ | 无 | 2025/1/4-6 |
|
||||
| 一、认识ESP32 | 1.3 idf.py的基本使用 | ✔ | ✔ | 无 | 2025/1/7 |
|
||||
| 二、IDF基础与工具使用 | 2.1 ESP32工程结构及构建 | ✔ | | | |
|
||||
| 二、IDF基础与工具使用 | 2.2 ESP-IDF项目配置 | ✔ | | | |
|
||||
| 二、IDF基础与工具使用 | 2.3 ESP-IDF自定义组件 | ✔ | | | |
|
||||
| 二、IDF基础与工具使用 | 2.4 ESP-IDF组件管理器 | ✔ | | | |
|
||||
| 三、FreeRTOS基础 | 3.1 FreeRTOS概述 | | | | |
|
||||
| 三、FreeRTOS基础 | 3.2 FreeRTOS多任务与任务管理 | | | | |
|
||||
| 三、FreeRTOS基础 | 3.3 FreeRTOS任务看门狗 | | | | |
|
||||
| 四、外设学习 | 4.1.1 GPIO入门 | | | | |
|
||||
| 四、外设学习 | 4.1.2 UART串口通信 | | | | |
|
||||
| 四、外设学习 | 4.1.3 硬件定时器 | | | | |
|
||||
| 四、外设学习 | 4.1.4 ADC模数转换 | | | | |
|
||||
| 四、外设学习 | 4.1.5 DAC数模转换 | | | | |
|
||||
| 四、外设学习 | 4.1.6 LED PWM控制 | | | | |
|
||||
| 四、外设学习 | 4.1.7 I2C通信 | | | | |
|
||||
| 四、外设学习 | 4.1.8 SPI通信 | | | | |
|
||||
| 四、外设学习 | 4.2.1 分区表设计 | | | | |
|
||||
| 四、外设学习 | 4.2.2 非易失性存储 | | | | |
|
||||
| 四、外设学习 | 4.2.3 FAT文件系统 | | | | |
|
||||
| 四、外设学习 | 4.2.4 SPIFFS文件系统 | | | | |
|
||||
| 五、FreeRTOS进阶 | 5.1 FreeRTOS队列使用教程 | | | | |
|
||||
| 五、FreeRTOS进阶 | 5.2 FreeRTOS信号量教程 | | | | |
|
||||
| 五、FreeRTOS进阶 | 5.3 FreeRTOS互斥量教程 | | | | |
|
||||
| 五、FreeRTOS进阶 | 5.4 FreeRTOS事件组教程 | | | | |
|
||||
| 五、FreeRTOS进阶 | 5.5 FreeRTOS任务通知教程 | | | | |
|
||||
| 五、FreeRTOS进阶 | 5.6 FreeRTOS软件定时器教程 | | | | |
|
||||
| 六、Wi-Fi功能与相关协议 | 6.1.1 Wi-Fi模式与基础操作 | | | | |
|
||||
| 六、Wi-Fi功能与相关协议 | 6.1.2 Wi-Fi STA与AP配置 | | | | |
|
||||
| 六、Wi-Fi功能与相关协议 | 6.2.1 TCP协议应用 | | | | |
|
||||
| 六、Wi-Fi功能与相关协议 | 6.2.2 UDP协议应用 | | | | |
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
@@ -132,7 +133,7 @@
|
||||
|
||||
本节详细介绍ESP-IDF项目的基本目录结构,包括CMake工具的基础知识,帮助读者掌握ESP32工程的整体组织方式,为日后开发复杂项目奠定基础。
|
||||
|
||||
- 在线文字教程:[ESP32工程结构及构建.md](docs/02.IDF基础与工具使用/2.1-ESP32工程结构及构建/ESP32工程结构.md)
|
||||
- 在线文字教程:[ESP32工程结构及构建.md](docs/02.ESP-IDF基础/2.1-ESP32工程结构及构建/ESP32工程结构.md)
|
||||
- 在线视频教程:[ESP32工程结构及构建]
|
||||
- 教程配套代码:[基础工程模板](#)
|
||||
|
||||
@@ -140,7 +141,7 @@
|
||||
|
||||
本节将重点讲解如何使用`menuconfig`工具配置项目,包含常见的配置选项及其实际用途。通过本节学习,读者可以根据项目需求快速定制和优化ESP32项目配置。
|
||||
|
||||
- 在线文字教程:[ESP-IDF项目配置.md](./docs/02.IDF基础与工具使用/2.2-ESP-IDF项目配置/ESP-IDF项目配置.md)
|
||||
- 在线文字教程:[ESP-IDF项目配置.md](docs/02.ESP-IDF基础/2.2-ESP-IDF项目配置/ESP-IDF项目配置.md)
|
||||
- 在线视频教程:[ESP-IDF项目配置详解]
|
||||
- 教程配套代码:[项目配置示例代码](#)
|
||||
|
||||
@@ -148,15 +149,15 @@
|
||||
|
||||
本节讲解如何创建和管理ESP-IDF的自定义组件,包括组件的目录结构、声明与调用方法,以及组件的复用和共享技巧,帮助读者构建模块化项目。
|
||||
|
||||
- 在线文字教程:[ESP-IDF自定义组件.md](./docs/02.IDF基础与工具使用/2.3-ESP-IDF自定义组件/ESP-IDF自定义组件.md)
|
||||
- 在线文字教程:[ESP-IDF自定义组件.md](docs/02.ESP-IDF基础/2.3-ESP-IDF自定义组件/ESP-IDF自定义组件.md)
|
||||
- 在线视频教程:[ESP-IDF自定义组件开发详解]
|
||||
- 教程配套代码:[组件示例代码](#)
|
||||
|
||||
## 2.4 ESP-IDF组件管理器
|
||||
|
||||
本节重点介绍ESP-IDF组件管理器的功能与使用方法,涵盖如何通过组件管理器导入外部库、配置组件依赖,以及解决组件冲突的问题,帮助读者高效管理复杂项目的依赖关系。
|
||||
本节重点介绍ESP-IDF组件管理器的功能与使用方法,涵盖如何通过组件管理器导入外部库、配置组件依赖,使用官方提供的外部组件。
|
||||
|
||||
- 在线文字教程:[ESP-IDF组件管理器.md](./docs/02.IDF基础与工具使用/2.4-ESP-IDF组件管理器/ESP-IDF组件管理器.md)
|
||||
- 在线文字教程:[ESP-IDF组件管理器.md](docs/02.ESP-IDF基础/2.4-ESP-IDF组件管理器/ESP-IDF组件管理器.md)
|
||||
- 在线视频教程:[ESP-IDF组件管理器详解]
|
||||
- 教程配套代码:[组件管理器示例代码](#)
|
||||
|
||||
@@ -166,22 +167,31 @@
|
||||
|
||||
> 目标:学习FreeRTOS的核心概念与基本功能,掌握任务管理与调度机制,为实时系统开发打下基础。
|
||||
|
||||
## 3.1 FreeRTOS概述
|
||||
## 3.1 FreeRTOS介绍于引入
|
||||
|
||||
本节将介绍FreeRTOS的核心概念,包括实时操作系统的特点、FreeRTOS的基本架构和设计思想,以及其在嵌入式开发中的应用场景,帮助读者快速了解FreeRTOS的基础知识。
|
||||
|
||||
> 在线文字教程:[FreeRTOS概述](./docs/03.FreeRTOS基础/3.1-FreeRTOS概述/FreeRTOS概述.md)
|
||||
> 在线视频教程:[FreeRTOS概述讲解]
|
||||
> 在线文字教程:[FreeRTOS概述.md](./docs/03.FreeRTOS基础/3.1-FreeRTOS概述/FreeRTOS概述.md)
|
||||
> 在线视频教程:[FreeRTOS概述讲解]
|
||||
> 教程配套代码:[FreeRTOS初体验示例代码](#)
|
||||
|
||||
## 3.2 FreeRTOS多任务与任务管理
|
||||
|
||||
本节讲解FreeRTOS中的多任务机制及任务管理方法,包括任务创建、任务删除、任务优先级和任务状态的管理。通过本节学习,读者可以初步掌握在FreeRTOS中实现并发任务的基本技巧。
|
||||
|
||||
> 在线文字教程:[FreeRTOS多任务与任务管理](./docs/03.FreeRTOS基础/3.2-FreeRTOS多任务与任务管理/FreeRTOS多任务与任务管理.md)
|
||||
> 在线文字教程:[FreeRTOS多任务与任务管理.md](./docs/03.FreeRTOS基础/3.2-FreeRTOS多任务与任务管理/FreeRTOS多任务与任务管理.md)
|
||||
> 在线视频教程:[FreeRTOS任务管理详解]
|
||||
> 教程配套代码:[FreeRTOS多任务示例代码](#)
|
||||
|
||||
|
||||
## 3.3 FreeRTOS任务看门狗
|
||||
|
||||
本节讲解 FreeRTOS 中任务看门狗机制的原理包括如何监控任务执行状态、检测任务卡死以及触发系统恢复等功能。通过学习任务看门狗,读者可以掌握提高系统可靠性的重要技巧,确保任务能够在异常情况下得到及时处理。
|
||||
|
||||
> 在线文字教程:[FreeRTOS任务看门狗.md](./docs/03.FreeRTOS基础/3.3-FreeRTOS任务看门狗/FreeRTOS任务看门狗.md)
|
||||
> 在线视频教程:[FreeRTOS任务看门狗]
|
||||
> 教程配套代码:[FreeRTOS任务看门狗示例代码](#)
|
||||
|
||||
---
|
||||
|
||||
# 四、外设学习
|
||||
|
||||
|
Before Width: | Height: | Size: 7.0 KiB |
@@ -1,20 +1,38 @@
|
||||
|
||||
ESP-IDF 的项目工程与 Keil 的传统工程模式有显著不同。Keil 工程通常依赖于特定的项目文件格式(如 .uvprojx 或 .uvoptx),这些文件记录了项目的结构、配置和依赖,且需要通过 Keil 软件进行管理和编译。而 ESP-IDF 则采用更灵活的构建方式,ESP-IDF 的项目通过标准的文本文件(如 CMakeLists.txt )来定义构建规则。这些文件描述了项目的源码路径、依赖关系和编译选项,而不是依赖于 IDE 专属的配置格式。这样可以方便地在不同的开发环境中切换。
|
||||
ESP-IDF 的项目工程与 Keil 的传统工程模式有显著不同。Keil 工程通常依赖于特定的项目文件格式(如 .uvprojx 或 .uvoptx),这些文件记录了项目的结构、配置和依赖,且需要通过 Keil 软件进行管理和编译。而 ESP-IDF 则采用更灵活的构建方式,ESP-IDF 的项目只是一个特定的文件夹,其中包含了构建可执行应用程序所需的全部文件和配置,以及其他支持型文件,例如分区表、数据/文件系统分区和引导程序。这些文件描述了项目的源码路径、依赖关系和编译选项,而不是依赖于 IDE 专属的配置格式。这样可以方便地在不同的开发环境中切换。
|
||||
|
||||
关于ESP-IDF工程结构可以参考官方文档:
|
||||
关于ESP-IDF工程结构可以参考官方文档:[示例项目](https://docs.espressif.com/projects/esp-idf/zh_CN/v5.3.2/esp32/api-guides/build-system.html#example-project-structure)
|
||||
|
||||
这部分没有什么新的东西,只是需要明白ESP-IDF所规定的项目框架,下面的内容都提炼自官方文档,大家也可以直接前往官方文档查看。
|
||||
### 项目目录
|
||||
|
||||
esp-idf的标准目录如下所示:
|
||||
|
||||

|
||||
```c
|
||||
- myProject/
|
||||
- CMakeLists.txt
|
||||
- sdkconfig
|
||||
- components/ - component1/ - CMakeLists.txt
|
||||
- Kconfig
|
||||
- src1.c
|
||||
- component2/ - CMakeLists.txt
|
||||
- Kconfig
|
||||
- src1.c
|
||||
- include/ - component2.h
|
||||
- main/ - CMakeLists.txt
|
||||
- src1.c
|
||||
- src2.c
|
||||
- build/
|
||||
```
|
||||
|
||||
- `CMakeLists.txt` 文件,这是 CMake 用于学习如何构建项目的主要文件,可以在这个文件中设置项目全局的 CMake 变量。顶层项目 CMakeLists.txt 文件会导入 /tools/cmake/project.cmake 文件,由它负责实现构建系统的其余部分。该文件最后会设置项目的名称,并定义该项目。
|
||||
|
||||
- `CMakeLists.txt` 文件,这是 CMake 用于学习如何构建项目的主要文件,可以在这个文件中设置项目全局的 CMake 变量。顶层项目 CMakeLists.txt 文件会导入/tools/cmake/project.cmake 文件,由它负责实现构建系统的其余部分。该文件最后会设置项目的名称,并定义该项目。
|
||||
|
||||
- `sdkconfig` 项目配置文件,执行 idf.py menuconfig 时会创建或更新此文件,文件中保存了项目中所有组件(包括 ESP-IDF 本身)的配置信息。 sdkconfig 文件可能会也可能不会被添加到项目的源码管理系统中。
|
||||
|
||||
- 可选的 `components` 目录中包含了项目的部分自定义组件,并不是每个项目都需要这种自定义组件,但它有助于构建可复用的代码或者导入第三方(不属于 ESP-IDF)的组件。或者,您也可以在顶层 CMakeLists.txt 中设置 EXTRA_COMPONENT_DIRS 变量以查找其他指定位置处的组件。有关详细信息,请参阅 重命名 main 组件。如果项目中源文件较多,建议将其归于组件中,而不是全部放在 “main” 中
|
||||
|
||||
- - `main` 目录是一个特殊的组件,它包含项目本身的源代码。”main” 是默认名称,CMake 变量 COMPONENT_DIRS 默认包含此组件,但您可以修改此变量。
|
||||
- `main` 目录是一个特殊的组件,它包含项目本身的源代码。”main” 是默认名称,CMake 变量 COMPONENT_DIRS 默认包含此组件,但您可以修改此变量。
|
||||
|
||||
- `build` 目录是存放构建输出的地方,如果没有此目录,idf.py 会自动创建。CMake 会配置项目,并在此目录下生成临时的构建文件。随后,在主构建进程的运行期间,该目录还会保存临时目标文件、库文件以及最终输出的二进制文件。此目录通常不会添加到项目的源码管理系统中,也不会随项目源码一同发布。
|
||||
|
||||
@@ -69,6 +87,7 @@ idf_component_register(SRCS "my_component.c"
|
||||
|
||||
- `REQUIRES` 声明组件的public依赖,可供其他依赖者访问
|
||||
- `PRIV_REQUIRES`声明private依赖,只能被当前组件访问。
|
||||
|
||||
# 参考链接
|
||||
|
||||
1. https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/api-guides/build-system.html
|
||||
@@ -40,7 +40,6 @@
|
||||
3. 组件配置生成的宏定义,配合C语言的预处理语句,可以针对不同的配置改变代码解结构。
|
||||
4. 组件配置生成的宏定义在C语言中是全局的宏定义,可以在任意处访问配置项。只需要#include "sdkconfig.h"即可。
|
||||
|
||||
|
||||
## 三、组件配置相关文件
|
||||
|
||||
在 ESP-IDF 构建系统中,有这么几种文件和组件配置相关。它们分别是:
|
||||
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 201 KiB After Width: | Height: | Size: 201 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 9.5 KiB After Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
@@ -1,27 +1,31 @@
|
||||
|
||||
### 说明:
|
||||
|
||||
1. 本文档由DuRuofu撰写,由DuRuofu负责解释及执行。
|
||||
|
||||
### 修订历史:
|
||||
|
||||
| 文档名称 | 版本 | 作者 | 时间 | 备注 |
|
||||
| ---- | ---- | ---- | ---- | ---- |
|
||||
| ESP-IDF自定义组件 | v1.0.0 | DuRuofu | 2024-02-18 | 首次建立 |
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
# ESP-IDF自定义组件
|
||||
|
||||
## 一 、自定义组件介绍:
|
||||
|
||||
之前在[ESP32工程结构](../2.1-ESP32工程结构及构建/ESP32工程结构.md)里提到esp-idf项目的结构如下:
|
||||
|
||||

|
||||
```
|
||||
- myProject/
|
||||
- CMakeLists.txt
|
||||
- sdkconfig
|
||||
- bootloader_components/ - boot_component/ - CMakeLists.txt
|
||||
- Kconfig
|
||||
- src1.c
|
||||
- components/ - component1/ - CMakeLists.txt
|
||||
- Kconfig
|
||||
- src1.c
|
||||
- component2/ - CMakeLists.txt
|
||||
- Kconfig
|
||||
- src1.c
|
||||
- include/ - component2.h
|
||||
- main/ - CMakeLists.txt
|
||||
- src1.c
|
||||
- src2.c
|
||||
|
||||
- build/
|
||||
```
|
||||
|
||||
其中components文件夹就是我们自定义的组件。ESP-IDF组件机制就是代码模块化的一种体现,将特定功能的代码封装为一个个组件并对外暴露接口,增强代码的可复用性,提高代码维护效率。
|
||||
|
||||
|
||||
## 二 、自定义组件示例:
|
||||
|
||||
|
||||
@@ -50,7 +54,7 @@
|
||||
|
||||
``` c
|
||||
#include <stdio.h>
|
||||
#include "led_blink.h"
|
||||
#include "led_blink.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "driver/gpio.h"
|
||||
@@ -183,8 +187,6 @@ menu "点灯组件配置"
|
||||
endmenu
|
||||
|
||||
```
|
||||
|
||||
|
||||
这样就编写好了一个组件。
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
@@ -1,19 +1,4 @@
|
||||
|
||||
### 说明:
|
||||
|
||||
1. 本文档由DuRuofu撰写,由DuRuofu负责解释及执行。
|
||||
2. 本文介绍ESP-IDF组件管理器的使用
|
||||
|
||||
### 修订历史:
|
||||
|
||||
| 文档名称 | 版本 | 作者 | 时间 | 备注 |
|
||||
| ---- | ---- | ------------ | ------ |
|
||||
| ESP-IDF组件管理器 |v1.0.0| DuRuofu | 2024-02-18 | 首次建立 |
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
# ESP-IDF组件管理器
|
||||
|
||||
## 一、啥是组件管理器
|
||||
|
||||
ESP-IDF官方对组件管理器的描述是这样的:
|
||||
|
Before Width: | Height: | Size: 96 KiB After Width: | Height: | Size: 96 KiB |
|
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 128 KiB After Width: | Height: | Size: 128 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 118 KiB After Width: | Height: | Size: 118 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 120 KiB |
|
Before Width: | Height: | Size: 89 KiB |
|
Before Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 106 KiB |
|
Before Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 21 KiB |