Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit9d82ebe

Browse files
authored
Add example for using ESP.rebootIntoUartDownloadMode() (#7897)
1 parent47b8947 commit9d82ebe

File tree

1 file changed

+190
-0
lines changed

1 file changed

+190
-0
lines changed
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
/*
2+
3+
Example of Booting into UART Download using `ESP.rebootIntoUartDownloadMode()`
4+
5+
Two methods are presented for starting UART Boot Mode.
6+
1) From `loop()` call the function `proxyEspSync()`, which peeks for a SLIP
7+
frame marker. Then when present, look for an esptool ESP_SYNC packet on
8+
the Serial port.
9+
2) A simple hotkey of 'D'.
10+
11+
After either of these, `ESP.rebootIntoUartDownloadMode()` is called to place
12+
the ESP8266 into UART Flash program mode.
13+
14+
For a quick test to confirm the ESP8266 is responding to esptool.py,
15+
use this command:
16+
esptool.py --chip esp8266 --before no_reset --after soft_reset flash_id
17+
18+
19+
Note with these methods a hard reset is not done, and the esptool.py may not
20+
detect and report the correct Crystal frequency for the ESP Module. If you
21+
need that info, it needs to be gathered after a Power-On or Hard Reset.
22+
*/
23+
24+
#include<Arduino.h>
25+
#include<ESP8266WiFi.h>
26+
27+
////////////////////////////////////////////////////////////////////////////////
28+
//
29+
// Check Serial Receive for ESP_SYNC slip packet from esptool.py
30+
//
31+
// If you are already using Serial input for command input, the character '\xC0'
32+
// is not available. We must reserve its use for the SLIP Frame Marker. I am not
33+
// sure which languages if any, would pose a problem. For the non-English
34+
// languages check your character set values to be sure it is not an issue. If
35+
// it is an issue, you will not be able to use this method as presented. The
36+
// '\xC0' character is defined by the SLIP protocol and cannot be changed.
37+
38+
// If your needs require it, you can add logic to loop() for setting and
39+
// clearing uartDownloadEnable. For example, you could add a push button to a
40+
// GPIO pin and monitor for a 5-second press. Then, set uartDownloadEnable to
41+
// true. In addition to that, you could also define a time-to-live for that
42+
// state and clear it after it elapses.
43+
//
44+
// Change this to false if you do not want ESP_SYNC monitor always on.
45+
bool uartDownloadEnable =true;
46+
47+
// Buffer size to receive an ESP_SYNC packet into, larger than the expected
48+
// ESP_SYNC packet length.
49+
constexprsize_t pktBufSz =64;
50+
51+
// Enough time to receive 115 bytes at 115200bps.
52+
// More than enough to finish receiving an ESP_SYNC packet.
53+
constexprsize_tkSyncTimeoutMs =10;
54+
55+
// The SLIP Frame end character, which is also used to start a frame.
56+
constexprchar slipFrameMarker ='\xC0';
57+
58+
// General packet format:
59+
// <0xC0><cmd><payload length><32 bit cksum><payload data ...><0xC0>
60+
// Slip packet for ESP_SYNC, minus the frame markers ('\xC0') captured from
61+
// esptool using the `--trace` option.
62+
constchar syncPkt[] PROGMEM =
63+
"\x00\x08\x24\x00\x00\x00\x00\x00\x07\x07\x12\x20"
64+
"UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU";
65+
66+
constexprsize_t syncPktSz =sizeof(syncPkt) -1;// Don't compare zero terminator char
67+
68+
//
69+
// Use the discovery of an ESP_SYNC packet, to trigger calling UART Download
70+
// Mode. At entry we expect the Serial FIFO to start with the byte following
71+
// the slipFrameMarker.
72+
//
73+
voidproxyEspSync() {
74+
if (!uartDownloadEnable) {
75+
return;
76+
}
77+
78+
byte buf[pktBufSz];
79+
80+
// If it is an ESP_SYNC packet, it will not take long for readBytesUntil() to
81+
// complete.
82+
Serial.setTimeout(kSyncTimeoutMs);
83+
int len = Serial.readBytesUntil(slipFrameMarker, buf, pktBufSz);
84+
85+
// To avoid a false trigger, only start UART Download Mode when we get an
86+
// exact match to the captured esptool ESP_SYNC packet.
87+
if (syncPktSz == len &&0 ==memcmp_P(buf, syncPkt, len)) {
88+
ESP.rebootIntoUartDownloadMode();
89+
// Does not return
90+
}
91+
92+
// Assume RX FIFO data is garbled and flush all RX data.
93+
while (0 <= Serial.read()) {}// Clear FIFO
94+
95+
// If your Serial requirements need a specific timeout value, you would
96+
// restore those here.
97+
}
98+
//
99+
////////////////////////////////////////////////////////////////////////////////
100+
101+
voidpreinit() {
102+
// (no C++ in function)
103+
// disable wifi
104+
ESP8266WiFiClass::preinitWiFiOff();
105+
}
106+
107+
voidsetup() {
108+
// For `proxyEspSync()` to work, the Serial.begin() speed needs to be
109+
// 115200bps. This is the data rate used by esptool.py. It expects the Boot
110+
// ROM to use its "auto-baud" feature to match up. Since `proxyEspSync()` is
111+
// acting as a proxy we must use 115200.
112+
//
113+
// If on the Arduino IDE Tools menu you use "Upload Speeds" above 115200, it
114+
// will work. When esptool.py is run with the `--baud BAUD` option specified
115+
// above 115200, initial communication with the ESP8266 is done at 115200bps.
116+
// Once esptool.py has synchronize with the ESP8266 and downloaded a short
117+
// stub, then both devices shift their UART speeds to the command line value.
118+
Serial.begin(115200);
119+
120+
Serial.println(F(
121+
"\r\n\r\n"
122+
"Boot UART Download Demo - initialization started.\r\n"
123+
"\r\n"
124+
"For a quick test to see the UART Download work,\r\n"
125+
"stop your serial terminal APP and run:\r\n"
126+
" esptool.py --chip esp8266 --before no_reset --after soft_reset flash_id\r\n"));
127+
128+
// ...
129+
}
130+
131+
voidcmdLoop(Print& oStream,int key) {
132+
switch (key) {
133+
case'e':
134+
oStream.println(F("Enable monitor for detecting ESP_SYNC from esptool.py"));
135+
uartDownloadEnable =true;
136+
break;
137+
138+
case'D':
139+
// This option would be prone to false triggering. It is here for DEMO
140+
// purposes and debugging.
141+
oStream.println(F("Boot into UART download mode ..."));
142+
oStream.flush();
143+
ESP.rebootIntoUartDownloadMode();
144+
break;
145+
146+
case'R':
147+
oStream.println(F("Restart ..."));
148+
oStream.flush();
149+
ESP.restart();
150+
break;
151+
152+
// ...
153+
154+
case'?':
155+
oStream.println(F("\r\nHot key help:"));
156+
if (!uartDownloadEnable) {
157+
oStream.println(F(" e - Enable monitor for detecting ESP_SYNC from esptool.py"));
158+
}
159+
oStream.println(F(" D - Boot into UART download mode"));
160+
oStream.println(F(" R - Restart"));
161+
oStream.println(F(" ? - This help message\r\n"));
162+
break;
163+
164+
default:
165+
break;
166+
}
167+
168+
oStream.println();
169+
}
170+
171+
172+
voidloop() {
173+
174+
// In this example, we can have Serial data from a user keystroke for our
175+
// command loop or the esptool trying to SYNC up for flashing. If the
176+
// character matches the Slip Frame Marker (the 1st byte of the SYNC packet),
177+
// we intercept it and call our ESP_SYNC proxy to complete the verification
178+
// and reboot into the UART Downloader. Otherwise, process the keystroke as
179+
// normal.
180+
if (0 < Serial.available()) {
181+
int keyPress = Serial.read();
182+
if (slipFrameMarker == keyPress) {
183+
proxyEspSync();
184+
}else {
185+
cmdLoop(Serial, keyPress);
186+
}
187+
}
188+
189+
// ...
190+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp