diff --git a/.gitignore b/.gitignore index 8cc3925..36fb364 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,8 @@ managed_components/ *.obj *.o *.exe +# 发布用上位机单独入库;dist 里的构建产物仍然忽略 +!nand_xfer/NAND_Xfer.exe *.dll *.so *.a diff --git a/README.md b/README.md index efc2b7b..357c413 100644 --- a/README.md +++ b/README.md @@ -1,78 +1,52 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | +# P4 USB 传输 -# ESP-MQTT sample application -(See the README.md file in the upper level 'examples' directory for more information about examples.) +ESP32-P4 工程,仓库里有两套程序。 -This example connects to the broker URI selected using `idf.py menuconfig` (using mqtt tcp transport) and as a demonstration subscribes/unsubscribes and send a message on certain topic. -(Please note that the public broker is maintained by the community so may not be always available, for details please see this [disclaimer](https://iot.eclipse.org/getting-started/#sandboxes)) +- 根目录是设备主固件。界面、蓝牙、Wi-Fi、表情包和外置 SPI NAND 都在这里。外置盘挂载点是 `/extflash`,表情文件放在 `/extflash/eaf/`。 +- `nand_xfer/` 是单独的 NAND 传输固件。电脑通过板载 USB Serial/JTAG 把文件写到同一块外置 NAND,设备侧路径同样以 `/extflash` 开头。 -Note: If the URI equals `FROM_STDIN` then the broker address is read from stdin upon application startup (used for testing) +分区表在 `partitions.csv`,与 IntegratedV1 相同。传输固件只覆盖 `ota_0`(偏移 `0x70000`,大小 10MB),不改 bootloader、分区表和 NVS。烧录、恢复主程序和串口协议见 `nand_xfer/README.md`。 -It uses ESP-MQTT library which implements mqtt client to connect to mqtt broker with MQTT version 5. +## 上位机 -The more details about MQTT v5, please refer to [official website](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html) +Windows 程序:`nand_xfer/NAND_Xfer.exe`。双击打开,窗口标题是「NAND 传输」。它把本机一个目录批量写到设备的 FLASH 目录。 -## How to use example +使用前先让板子跑着 `nand_xfer` 固件,USB 接到 P4 的 USB Serial/JTAG,并关掉占用该 COM 口的其它程序,包括 `idf.py monitor`。 -### Hardware Required +1. **端口**:下拉选择串口。描述里带 `303A` 或 `Serial/JTAG` 的口排在前面。没有口时点「刷新」,并确认线已插上。 +2. **本地目录**:要上传的文件夹。默认是 `E:\PET\EAF`,点「浏览」可以换。上传的是这个目录里面的内容,子目录会保留。 +3. **FLASH目录**:设备上的目标路径。默认是 `/extflash/eaf`。 -This example can be executed on any ESP32 board, the only required interface is WiFi and connection to internet. +按钮: -### Configure the project +- **查询**:显示 NAND 容量、是否已挂载、FAT 总空间和剩余空间。日志里出现「未挂载」时,新盘要先格式化,再列目录或写入。 +- **列目录**:列出 FLASH 目录。目录显示为 `DIR`,文件显示为 `FILE` 加字节数。 +- **批量写入**:按本地目录逐个写入。每个文件在设备上关闭、同步、回读并做 CRC 校验后才算成功。进度按文件个数走。某个文件失败时,日志里会记下名字,其余文件继续。再传一次会覆盖未完成的文件。 +- **停止**:当前这个文件结束后不再继续。已经写完的文件保留。 +- **格式化**:清空整块外置 NAND 上的文件。新盘第一次使用时做这一步。确认框里输入 `FORMAT /extflash` 才会执行,大约一两分钟。盘上已有表情文件时不要格式化。格式化由设备按 16KB 簇完成;不要在 Windows 资源管理器里格式化这块盘。 -* Open the project configuration menu (`idf.py menuconfig`) -* Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../../README.md) for more details. -* MQTT v5 protocol (`CONFIG_MQTT_PROTOCOL_5`) under "ESP-MQTT Configurations" menu is enabled by `sdkconfig.defaults`. +写入结束后,窗口会再列一次目标目录。 -### Build and Flash +## 命令行 -Build the project and flash it to the board, then run monitor tool to view serial output: +同一套传输也可以用 Python 脚本,工作目录是 `nand_xfer`: -``` -idf.py -p PORT flash monitor +```powershell +py -3 -m pip install pyserial +py -3 nand_put.py COM3 "C:\files\demo.eaf" "/extflash/eaf/demo.eaf" +py -3 nand_put.py COM3 "C:\files\eaf" "/extflash/eaf" --recursive +py -3 nand_put.py COM3 --info +py -3 nand_put.py COM3 --list "/extflash/eaf" ``` -(To exit the serial monitor, type ``Ctrl-]``.) +`--format` 会清空 NAND,执行前要在提示里输入确认文字。完整命令、烧录脚本和协议见 `nand_xfer/README.md`。 -See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. +## 重新打包上位机 -## Example Output +在 `nand_xfer` 目录执行: +```powershell +.\build_gui.ps1 ``` -I (5119) esp_netif_handlers: example_connect: sta ip: 192.168.3.143, mask: 255.255.255.0, gw: 192.168.3.1 -I (5119) example_connect: Got IPv4 event: Interface "example_connect: sta" address: 192.168.3.143 -I (5619) example_connect: Got IPv6 event: Interface "example_connect: sta" address: fe80:0000:0000:0000:c64f:33ff:fe24:6645, type: ESP_IP6_ADDR_IS_LINK_LOCAL -I (5619) example_connect: Connected to example_connect: sta -I (5629) example_connect: - IPv4 address: 192.168.3.143 -I (5629) example_connect: - IPv6 address: fe80:0000:0000:0000:c64f:33ff:fe24:6645, type: ESP_IP6_ADDR_IS_LINK_LOCAL -I (5649) MQTT5_EXAMPLE: Other event id:7 -W (6299) wifi:idx:0 (ifx:0, 34:29:12:43:c5:40), tid:7, ssn:0, winSize:64 -I (7439) MQTT5_EXAMPLE: MQTT_EVENT_CONNECTED -I (7439) MQTT5_EXAMPLE: sent publish successful, msg_id=53118 -I (7439) MQTT5_EXAMPLE: sent subscribe successful, msg_id=41391 -I (7439) MQTT5_EXAMPLE: sent subscribe successful, msg_id=13695 -I (7449) MQTT5_EXAMPLE: sent unsubscribe successful, msg_id=55594 -I (7649) mqtt5_client: MQTT_MSG_TYPE_PUBACK return code is -1 -I (7649) MQTT5_EXAMPLE: MQTT_EVENT_PUBLISHED, msg_id=53118 -I (8039) mqtt5_client: MQTT_MSG_TYPE_SUBACK return code is 0 -I (8049) MQTT5_EXAMPLE: MQTT_EVENT_SUBSCRIBED, msg_id=41391 -I (8049) MQTT5_EXAMPLE: sent publish successful, msg_id=0 -I (8059) mqtt5_client: MQTT_MSG_TYPE_SUBACK return code is 2 -I (8059) MQTT5_EXAMPLE: MQTT_EVENT_SUBSCRIBED, msg_id=13695 -I (8069) MQTT5_EXAMPLE: sent publish successful, msg_id=0 -I (8079) MQTT5_EXAMPLE: MQTT_EVENT_DATA -I (8079) MQTT5_EXAMPLE: key is board, value is esp32 -I (8079) MQTT5_EXAMPLE: key is u, value is user -I (8089) MQTT5_EXAMPLE: key is p, value is password -I (8089) MQTT5_EXAMPLE: payload_format_indicator is 1 -I (8099) MQTT5_EXAMPLE: response_topic is /topic/test/response -I (8109) MQTT5_EXAMPLE: correlation_data is 123456 -I (8109) MQTT5_EXAMPLE: content_type is -I (8119) MQTT5_EXAMPLE: TOPIC=/topic/qos1 -I (8119) MQTT5_EXAMPLE: DATA=data_3 -I (8129) mqtt5_client: MQTT_MSG_TYPE_UNSUBACK return code is 0 -I (8129) MQTT5_EXAMPLE: MQTT_EVENT_UNSUBSCRIBED, msg_id=55594 -I (8139) mqtt_client: Client asked to disconnect -I (9159) MQTT5_EXAMPLE: MQTT_EVENT_DISCONNECTED -``` + +脚本用本目录的虚拟环境调用 PyInstaller,产物是 `nand_xfer\dist\NAND_Xfer.exe`。要更新仓库里的发布文件时,用这个新文件覆盖 `nand_xfer\NAND_Xfer.exe`。 diff --git a/nand_xfer/NAND_Xfer.exe b/nand_xfer/NAND_Xfer.exe new file mode 100644 index 0000000..5fc70e9 Binary files /dev/null and b/nand_xfer/NAND_Xfer.exe differ