# MicroPython 资源管理器
**Repository Path**: doublewww/micropython-resource-manager
## Basic Information
- **Project Name**: MicroPython 资源管理器
- **Description**: 将非 .py 文件打包进固件并调用
- **Primary Language**: Python
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 7
- **Created**: 2022-04-08
- **Last Updated**: 2022-05-24
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
MicroPython 资源管理器

### 项目介绍
将非`.py`文件打包进固件并调用(仅适用于`乐鑫 ESP`系列芯片)
> 相较于[前一个版本](https://gitee.com/walkline/micropython-resource-manager/tree/v1/),这个分支只能算作是一个使用教程了
### 关于文件打包
`MicroPython`编译固件过程中可以自动编译打包用户添加的`.py`文件,对于其它类型的用户文件就无能为力了
这里使用一个工具 [mklittlefs](https://github.com/earlephilhower/mklittlefs),它可以将文件写入`littlefs v2`分区并生成一个分区文件,再把这个分区文件写入已有固件中实现文件打包
使用此方法打包的文件使用上与用户分区里的文件无异
### 分区表
先观察一下编译固件所使用的分区表文件的内容
| Name | Type | SubType | Offset | Size | Flags |
| :-: | :-: | :-: | :-: | :-: | :-: |
| nvs | data | nvs | 0x9000 | 0x6000 | |
| phy_init | data | phy | 0xf000 | 0x1000 | |
| factory | app | factory | **0x10000** | **0x180000** | |
| vfs | data | fat | **0x200000** | 0x200000 | |
> 上表为`ESP32`系列标准`4MiB`闪存分区表
其中:
* `factory`分区:为`MicroPython`固件(app)分区
* `vfs`分区:为用户可用分区
这两个分区之间还留有一定的`可用空间`,可供我们追加用户文件,这个空间大小的计算公式为:
```python
>>> free_sapce = vfs_offset - (factory_offset + factory_size)
```
代入数值后计算得到`可用空间`大小为`458752B (448KiB)`(使用其它分区表文件的需自行计算)
#### 修改分区表文件
假设我们要追加的用户文件总大小小于`可用空间`,在分区表文件中新增一个资源分区`resource`
| Name | Type | SubType | Offset | Size | Flags |
| :-: | :-: | :-: | :-: | :-: | :-: |
| nvs | data | nvs | 0x9000 | 0x6000 | |
| phy_init | data | phy | 0xf000 | 0x1000 | |
| factory | app | factory | 0x10000 | 0x180000 | |
| **resource** | **data** | **fat** | **0x190000** | **0x70000** | |
| vfs | data | fat | 0x200000 | 0x200000 | |
`resource`分区起始地址设为`0x190000`,大小设为`0x70000`,其中:
```python
# 起始地址
resource_offset = factory_offset + factory_size
# 分区大小
resource_size = vfs_offset - resource_offset
```
#### 资源分区管理
资源分区分区表增加`SubType=fat`后可以使用`esp32 模块`读取到分区信息
```python
>>> import esp32
>>> esp32.Partition.find(type=esp32.Partition.TYPE_DATA, label='resource')
[<
Partition type=1,
subtype=129,
address=1638400,
size=458752,
label=resource,
encrypted=0
>]
```
### 如何打包文件
这里以`ESP32 4MiB`开发板举例,向固件中写入 3 个文件,分别是:
* chushibiao.bin:出师表所用字库文件
* chushibiao.txt:出师表原文
* mua.pbm:单色位图文件
> 3 个文件位于`example/files/`
按照步骤进行操作:
1. 按照上述说明[修改分区表文件](https://gitee.com/walkline/micropython-resource-manager#%E4%BF%AE%E6%94%B9%E5%88%86%E5%8C%BA%E8%A1%A8%E6%96%87%E4%BB%B6),参考文件位于[example/partitions.csv](https://gitee.com/walkline/micropython-resource-manager/blob/master/example/partitions.csv)
2. 使用修改后的分区表编译固件,参考文件位于[example/esp32_firmware.bin](https://gitee.com/walkline/micropython-resource-manager/blob/master/example/esp32_firmware.bin)
3. 根据修改后的分区表中的偏移地址,修改`config.py`文件中的对应内容
4. 使用合并工具向固件中增加用户资源文件
```bash
# python combine_files.py
$ python combine_files.py ./example/esp32_firmware.bin ./example/files/
```
4. 将生成的`esp32_firmware_output.bin`固件文件烧录到开发板
### 如何读取文件
要读取资源文件,只需要将资源分区加载到系统中即可
```python
import esp32, os
res = esp32.Partition.find(esp32.Partition.TYPE_DATA, label='resource')
if res:
os.mount(res[0], '/res')
```
### 查看演示内容
开发板使用`repl`模式运行`main.py`文件
```bash
$ ab --repl
# 使用快捷键 ctrl + r,选择 main.py 并运行
```
> ab 工具使用方法见 [AMPY Batch Tool](https://gitee.com/walkline/a-batch-tool) 项目
演示过程中将逐一显示以下内容:
* `mua.pbm`图片
* `chushibiao.txt`文本内容
* `chushibiao.bin`字库信息
* 汉字及数据内容
* 汉字预览
> 所有内容在`repl`中显示
完整输出内容如下:
```
>>> Run local file
[1] main.py
[2] drivers\ssd1306.py
[3] config.py
[4] combine_files.py
Choose a file: 1
bitmap preview
.....................................................................................
................@@@..................................................................
..........@@@@@@@@@@@@@..............................................................
.......@@@@@@@@@@@@@@@@@@............................................................
......@@@@@@@@@@@@@@@@@@@@...........................................................
.....@@@@@@@@@@@@@@@@@@@@@@..........................................................
....@@@@@@@@@@@@@@..@@@@@@@@.........................................................
...@@@@@@....@@.......@@@@@@@........................................................
..@@@@@@...............@@@@@@........................................................
..@@@@@................@@@@@@........................................................
..@@@@@................@@@@@@@.......................................................
..@@@@@.................@@@@@@.......................................................
.@@@@@@................@@@@@@@.......................................................
.@@@@@@................@@@@@@@.......................................................
.@@@@@@@...............@@@@@@..............@@@@@.....................................
.@@@@@@@@.............@@@@@@@............@@@@@@@.....................................
..@@@@@@@@...........@@@@@@@@...........@@@@@@@@@....................................
..@@@@@@@@@.........@@@@@@@@@..........@@@@@@@@@@@....................@@.............
..@@@@@@@@@@@.....@@@@@@@@@@..........@@@@@@.......................@@@@@@@...........
...@@@@@@@@@@@...@@@@@@@@@@@..........@@.........................@@@@@@@@@...........
....@@@@@@@@@@@@@@@@@@@@@@@................@@@@@@@@@@@@@@.......@@@@@@@@@@@..........
.....@@@@@@@@@@@@@@@@@@@@@..............@@@@@@@@@@@@@@@@@@@@@...@@@@@@@@@@@..........
.......@@@@@@@@@@@@@@@@..............@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@..........
..........@@@@@@@@@@...............@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@..........
................@@@@..............@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.........
.................@@@............@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.........
...................@...........@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.........
...............................@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.........
..............................@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.........
.............................@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.........
............................@@@@...@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.....@@.
............................@@@.....@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.....@@.
...........................@@@......@@@@@@@@@@@@@@@@@@@@@@@@@@....@@@@@@@@@@@.....@@.
...........................@@........@@@@@@@@@@@@@@@@@@@@@@@@......@@@@@@@@@@@@@@@@@.
...........................@@........@@@@@@@@@@@@@@@@@@@@@@@@......@@@@@@@@@@@@@@@@@.
..........................@@@.......@@@@@@.@@..@@@@@@@@@@@@@.......@@@@@@@@@@@@@@@@@.
..........................@@@.......@@@@@@.......@@..@@@@@@@........@@@@@@@@@@@@@@@..
..........................@@@.......@@@@@@...........@@@@@@@.......@@@@@@@@@@@@@@@@..
..........................@@@@.....@@@@@@@..........@@@@@@@@.......@@@@@@@@@@@@@@@@..
..........................@@@@@@@@@@@@@@@@@.........@@@@@@@@.......@@@@@@@@@@@@@@@@..
..........................@@.@@@.@@.@@@@@@@.........@@@@@@@@@......@@@@@@@@@@@@@@@@..
..........................@@.@@..@@.@@@@@@@.........@@@@@@@@@@@@.@@@@@@@@@@@@@@@@@@..
..........................@@.@@.@@..@@@@@@@@.......@@@@@@@@.@@.@@@@@@@@@@@@@@@@@@@@..
..........................@@@@@.@@.@@@@@@@@@@......@@@@@@@..@@.@@..@@@@@@@@@@@@@@@@..
...........................@@@@@@@.@@@@@@@@@@@@..@@@@@@@@@.@@..@@..@@@@@@@@@@@@@@@...
...........................@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.@@.@@@..@@@@@@@@@@@@@@@...
............................@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.@@@@@@@@@@@@@@@@@@@@...
............................@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@...
.............................@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@....
.............................@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@....
..............................@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@....
...............................@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@....
................................@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.....
.................................@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.....
..................................@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.....
...................................@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@......
....................................@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@......
.......................................@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.@@@......
...........................................@@@@@@@@@@@@@@@@@@@@@@@@@..@@@....@@......
.......................................@.........@@@@@@@@@@@.@@@......@@.............
.......................................@@....................@@.......@@.............
.............................................................@@.......@@.............
.....................................................................................
.....................................................................................
press any key to continue...
text preview
出师表
先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。然侍卫之臣不懈于内,忠志之士忘身于外者,盖追先帝之殊遇,欲报之于陛下也。诚宜开张圣听,以光先帝遗德,恢弘志士之气,不宜妄自菲薄
,引喻失义,以塞忠谏之路也。
宫中府中,俱为一体,陟罚臧否,不宜异同。若有作奸犯科及为忠善者,宜付有司论其刑赏,以昭陛下平明之理,不宜偏私,使内外异法也。
侍中、侍郎郭攸之、费祎、董允等,此皆良实,志虑忠纯,是以先帝简拔以遗陛下。愚以为宫中之事,事无大小,悉以咨之,然后施行,必得裨补阙漏,有所广益。
将军向宠,性行淑均,晓畅军事,试用之于昔日,先帝称之曰能,是以众议举宠为督。愚以为营中之事,悉以咨之,必能使行阵和睦,优劣得所。
亲贤臣,远小人,此先汉所以兴隆也;亲小人,远贤臣,此后汉所以倾颓也。先帝在时,每与臣论此事,未尝不叹息痛恨于桓、灵也。侍中、尚书、长史、参军,此悉贞良死节之臣,愿陛下亲之信之,则汉室之隆,可计
日而待也。
臣本布衣,躬耕于南阳,苟全性命于乱世,不求闻达于诸侯。先帝不以臣卑鄙,猥自枉屈,三顾臣于草庐之中,咨臣以当世之事,由是感激,遂许先帝以驱驰。后值倾覆,受任于败军之际,奉命于危难之间,尔来二十有
一年矣。
先帝知臣谨慎,故临崩寄臣以大事也。受命以来,夙夜忧叹,恐托付不效,以伤先帝之明,故五月渡泸,深入不毛。今南方已定,兵甲已足,当奖率三军,北定中原,庶竭驽钝,攘除奸凶,兴复汉室,还于旧都。此臣所
以报先帝而忠陛下之职分也。至于斟酌损益,进尽忠言,则攸之、祎、允之任也。
愿陛下托臣以讨贼兴复之效,不效,则治臣之罪,以告先帝之灵。若无兴德之言,则责攸之、祎、允等之慢,以彰其咎;陛下亦宜自谋,以咨诹善道,察纳雅言,深追先帝遗诏,臣不胜受恩感激。
今当远离,临表涕零,不知所言。
press any key to continue...
fontlib preview
HZK Info: /res/chushibiao.bin
file size : 14350
font height : 16
data size : 32
scan mode : 1 (Vertical)
byte order : 0 (LSB)
format : 0 (MONO_VLSB)
characters : 427
press any key to continue...
chars data preview
半: b'\x00DHP@\xfe@PHD\x00\x00\x00\x00\x00\x00\x02\x02\x02\x02\x02\x1f\x02\x02\x02\x02\x02\x00\x00\x00\x00\x00'
中: b'\x00\xf8\x88\x88\x88\xfe\x88\x88\x88\x88\xf8\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x1f\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00'
而: b'\x02\xf2\x12\x12\xf2\x1a\x16\xf2\x12\x12\xf2\x02\x00\x00\x00\x00\x00\x1f\x00\x00\x0f\x00\x00\x0f\x00\x10\x1f\x00\x00\x00\x00\x00'
表: b'@DTT\xd4~\xd4TTTD@\x00\x00\x00\x00\x04\x04\x02\x1f\x10\x08\x01\x06\x04\x19\x08\x00\x00\x00\x00\x00'
业: b' @\x80\x00\xfe\x00\x00\xfe\x00\xc00\x00\x00\x00\x00\x00\x10\x10\x11\x10\x1f\x10\x10\x1f\x11\x10\x10\x10\x00\x00\x00\x00'
未: b'@HHHH\xfeHHHH@\x00\x00\x00\x00\x00\x08\x08\x04\x02\x01\x1f\x01\x02\x04\x08\x08\x00\x00\x00\x00\x00'
道: b'@B\xcc\x00\x04\xf4V\\TV\xf4\x04\x00\x00\x00\x00\x10\x08\x07\x08\x10\x17\x15\x15\x15\x15\x17\x10\x00\x00\x00\x00'
出: b'\x00\x00< \xfe <\x00\x00\x00\x00\x00\x00\x00\x1f\x08\x08\x08\x0f\x08\x08\x08\x08\x1f\x00\x00\x00\x00\x00'
天: b' """\xa2~\xa2"""" \x00\x00\x00\x00\x10\x10\x08\x06\x01\x00\x01\x02\x04\x08\x10\x10\x00\x00\x00\x00'
帝: b'\xe4$\xa4\xac\xb4\xe6\xb4\xac\xa4$\xe4\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x1f\x00\x08\x0f\x00\x00\x00\x00\x00\x00\x00'
: b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
师: b'\x00\xf8\x00\xfe\x00\xf4\x14\x14\xfc\x14\x14\xf4\x00\x00\x00\x00\x10\x13\x08\x07\x00\x07\x00\x00\x1f\x00\x04\x07\x00\x00\x00\x00'
下: b'\x02\x02\x02\x02\x02\xfe\x12"B\xc2\x02\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
先: b'\x00PHN\xc8H~\xc8HH@@\x00\x00\x00\x00\x10\x10\x08\x06\x01\x00\x00\x0f\x10\x10\x10\x1c\x00\x00\x00\x00'
殂: b'\x84t\x9c\x14\xf6\x04\xfe"""\xfe\x00\x00\x00\x00\x00\x10\x08\x04\x03\x10\x10\x1f\x11\x11\x11\x1f\x10\x00\x00\x00\x00'
,: b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x16\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
创: b'@ \xf0(&$\xe8\x10\x00\xf8\x00\xfe\x00\x00\x00\x00\x00\x00\x0f\x10\x11\x12\x11\x1c\x00\x03\x10\x1f\x00\x00\x00\x00'
崩: b'\x00\x00\xee\xa8\xa8\xe8\x08\xee\xa8\xa8\xa8\xee\x00\x00\x00\x00\x10\x08\x07\x02\x12\x1f\x10\x0f\x02\x02\x12\x1f\x00\x00\x00\x00'
今: b'@@ \x10(F\x08\x10 @@\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x11\r\x03\x01\x00\x00\x00\x00\x00\x00\x00'
press any key to continue...
chars preview
................ ................ ................ ................ ................ ................ ................
.....@.......... ...@............ .....@.......... ................ ................ ...@..@......... .....@..........
..@..@...@...... ...@.@@@@@@@.... .@@@@@@@@@@..... ................ ................ ...@..@......... @@@@@@@@@@@.....
..@..@...@...... .@.@....@....... .....@.......... ................ ................ ..@@@@@@@@...... ...@...@........
..@..@...@...... .@.@.@@@@@@@.... ..@@@@@@@@...... ................ ................ .@....@......... ....@.@.........
..@@@@@@@@...... .@.@.@..@..@.... .....@.......... ................ ................ ......@......... @@@@@@@@@@@.....
.....@.......... .@.@.@..@..@.... @@@@@@@@@@@@.... ................ ................ .@@@@@@@@@@@.... @....@....@.....
.....@.......... .@.@.@..@..@.... ....@.@......... ................ ................ ....@..@........ @.@@@@@@@.@.....
.@...@....@..... .@.@.@..@..@.... ...@..@..@...... ................ ................ ....@..@........ ..@..@..@.......
.@...@....@..... .@.@.@..@..@.... ..@@...@........ ................ ................ ...@...@........ ..@..@..@.......
.@...@....@..... ...@.@..@.@@.... @@.@...@@....... ................ ................ ...@...@...@.... ..@..@..@.......
.@@@@@@@@@@..... ..@.....@....... ...@.@...@@..... ................ ................ ..@....@...@.... ..@..@.@@.......
.@........@..... @@......@....... ...@@....@...... ................ ................ @@......@@@@.... .....@..........
................ ................ ................ ................ ................ ................ ................
................ ................ ................ ................ ................ ................ ................
................ ................ ................ ................ ................ ................ ................
................ ................ ................ ................ ................ ................ ................
....@......@.... ....@..@........ .....@.......... .....@.......... @@@@@@@@@@@@.... .....@.......... .@....@..@......
....@@.....@.... ....@..@........ .....@.......... .@...@...@...... ......@......... .....@.......... ..@.@@@@@@@@....
...@..@..@.@.... ....@..@........ .@@@@@@@@@...... ..@..@..@....... .....@.......... .@@@@@@@@@@..... ..@....@........
..@....@.@.@.... ....@..@..@..... .....@.......... ...@.@.@........ .@@@@@@@@@@..... .@...@....@..... .....@@@@@@.....
.@@@@@@..@.@.... @...@..@..@..... .....@.......... .....@.......... .@..@..@..@..... .@...@....@..... .....@....@.....
@.@...@..@.@.... .@..@..@.@...... @@@@@@@@@@@..... .@@@@@@@@@...... .@..@..@..@..... .@...@....@..... @@@..@@@@@@.....
..@...@..@.@.... ..@.@..@.@...... .....@.......... .....@.......... .@..@..@..@..... .@@@@@@@@@@..... ..@..@....@.....
..@.@.@..@.@.... ..@.@..@@....... ....@@@......... .....@.......... .@..@..@..@..... .@...@....@..... ..@..@@@@@@.....
..@..@...@.@.... ....@..@........ ...@.@.@........ @@@@@@@@@@@..... .@..@..@..@..... .....@.......... ..@..@....@.....
..@....@...@.... ....@..@........ ..@..@..@....... .....@.......... .@..@..@..@..... .....@.......... ..@..@@@@@@.....
..@....@...@.... ....@..@........ @@...@...@@..... .....@.......... .@..@..@..@..... .....@.......... .@.@............
...@@@@@..@@.... @@@@@@@@@@@@.... .....@.......... .....@.......... .@.......@@..... .....@.......... @...@@@@@@@@....
................ ................ ................ ................ ................ ................ ................
................ ................ ................ ................ ................ ................ ................
................ ................ ................ ................ ................ ................ ................
................ ................ ................ ................ ................ ................
..@....@...@.... ....@.@@@@@..... ................ .....@.......... .@@@@@@@@@@..... @@@@@@@@@@@@....
..@....@...@.... @@@@@@@...@..... ................ .....@.......... .....@.......... .....@..........
..@@@@@@@@@@.... ..@...@...@..... ................ ....@.@......... .....@.......... .....@..........
................ .@@@@.@...@..... ................ ...@...@........ .....@.......... .....@@.........
..@@@@.@@@@@.... .@..@.@@@@@..... ................ ..@.@...@....... @@@@@@@@@@@@.... .....@.@........
..@..@.@...@.... .@..@.@...@..... ................ @@...@...@@..... .....@.......... .....@..@@......
..@@@@.@@@@@.... @.@.@.@...@..... ................ ................ ....@.@......... .....@...@......
..@..@.@...@.... ...@..@@@@@..... ................ ..@@@@@@@....... ....@.@......... .....@..........
..@@@@.@@@@@.... ...@..@...@..... ...@@........... .......@........ ...@...@........ .....@..........
..@..@.@...@.... ..@...@...@..... ...@@........... ......@......... ...@....@....... .....@..........
.@...@.@...@.... .@....@...@..... ....@........... ......@......... ..@......@...... .....@..........
@...@@@...@@.... @...@@@@@@@@.... ...@............ .....@.......... @@........@@.... .....@..........
................ ................ ................ ................ ................ ................
................ ................ ................ ................ ................ ................
................ ................ ................ ................ ................ ................
>>>
```
### 参考资料
* [分区表 - ESP32](https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/api-guides/partition-tables.html)
* [ESP32-C3 MicroPython 固件编译环境搭建教程](https://gitee.com/walkline/esp32-c3_micropython_firmware)
* [WSL 下加速 Github 克隆速度](https://walkline.wang/blog/archives/263)
* [mklittlefs 工具下载](https://github.com/earlephilhower/mklittlefs/releases)
### 合作交流
* 联系邮箱:
* QQ 交流群:
* 走线物联:[163271910](https://jq.qq.com/?_wv=1027&k=xtPoHgwL)
* 扇贝物联:[31324057](https://jq.qq.com/?_wv=1027&k=yp4FrpWh)

