Skip to content

Commit fe93a37

Browse files
committed
update: 添加新标志字段-提供全自动软件OTA能力
1 parent 1a05d12 commit fe93a37

File tree

4 files changed

+85
-13
lines changed

4 files changed

+85
-13
lines changed

Bootloader/boot_flag.c

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -62,17 +62,17 @@ void BootFlag_Read(BootFlag_t *out)
6262
else
6363
{
6464
/* 未初始化,填充默认值 */
65-
out->valid_flag = APP_VALID_FLAG;
66-
out->boot_attempts = 0;
67-
out->need_copy = 0;
68-
out->ota_complete = 0;
69-
out->reserved1 = 0;
70-
out->app1_version = 0;
71-
out->app2_version = 0;
72-
out->app1_crc = 0;
73-
out->app2_crc = 0;
74-
out->boot_count = 0;
75-
out->reserved2 = 0;
65+
out->valid_flag = APP_VALID_FLAG;
66+
out->boot_attempts = 0;
67+
out->need_copy = 0;
68+
out->ota_complete = 0;
69+
out->enter_bootloader = 0;
70+
out->app1_version = 0;
71+
out->app2_version = 0;
72+
out->app1_crc = 0;
73+
out->app2_crc = 0;
74+
out->boot_count = 0;
75+
out->reserved2 = 0;
7676
}
7777
}
7878

@@ -106,3 +106,36 @@ void BootFlag_MarkBootSuccess(void)
106106
}
107107
}
108108

109+
/**
110+
* @brief 检查并清除进入Bootloader的请求标志
111+
* @retval 1:需要进入Bootloader, 0:不需要
112+
*/
113+
uint8_t BootFlag_CheckAndClearEnterBootloader(void)
114+
{
115+
BootFlag_t boot_flag;
116+
117+
BootFlag_Read(&boot_flag);
118+
if (boot_flag.enter_bootloader == 0)
119+
{
120+
return 0;
121+
}
122+
123+
boot_flag.enter_bootloader = 0;
124+
BootFlag_Save(&boot_flag);
125+
return 1;
126+
}
127+
128+
/**
129+
* @brief 请求进入Bootloader
130+
*/
131+
void BootFlag_RequestEnterBootloader(void)
132+
{
133+
BootFlag_t boot_flag;
134+
135+
BootFlag_Read(&boot_flag);
136+
boot_flag.enter_bootloader = 1;
137+
BootFlag_Save(&boot_flag);
138+
}
139+
140+
141+

Bootloader/boot_flag.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ typedef struct
1515
uint8_t boot_attempts;
1616
uint8_t need_copy;
1717
uint8_t ota_complete;
18-
uint8_t reserved1;
18+
uint8_t enter_bootloader;
1919
uint32_t app1_version;
2020
uint32_t app2_version;
2121
uint32_t app1_crc;
@@ -27,6 +27,8 @@ typedef struct
2727
void BootFlag_Read(BootFlag_t *out);
2828
int32_t BootFlag_Save(BootFlag_t *flag);
2929
void BootFlag_MarkBootSuccess(void);
30+
void BootFlag_RequestEnterBootloader(void);
31+
uint8_t BootFlag_CheckAndClearEnterBootloader(void);
3032

3133
#endif
3234

Bootloader/main.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,12 @@ int main(void)
8787
Serial_SendString("\r\n");
8888
}
8989

90+
if(BootFlag_CheckAndClearEnterBootloader())
91+
{
92+
Serial_SendString("\r\n>>> Enter Bootloader Requested <<<\r\n");
93+
Bootloader_CommandLoop();
94+
}
95+
9096
/* 等待3秒检测是否进入Bootloader模式 */
9197
Serial_SendString("Send 'B' within 3s to enter Bootloader mode...\r\n");
9298

Bootloader/tools/ota_send.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
PACKET_SIZE = 128
3131
PACKET_1K_SIZE = 1024
32+
OTA_TRIGGER = bytes([0x12, 0x34, 0x56, 0x78])
3233

3334

3435
class SerialConsole:
@@ -131,6 +132,18 @@ def build_header_payload(file_path: Path) -> bytes:
131132
return payload.ljust(PACKET_SIZE, b"\0")
132133

133134

135+
def wait_for_boot_menu_withinapp(cmd_port: serial.Serial, console: SerialConsole, seconds: float) -> None:
136+
print("Waiting for bootloader menu on USART1...")
137+
deadline = time.monotonic() + seconds
138+
139+
while time.monotonic() < deadline:
140+
time.sleep(0.05)
141+
console.poll()
142+
if console.contains("READY") or console.contains("Commands:"):
143+
return
144+
145+
raise TimeoutError("Bootloader menu was not detected on the command UART")
146+
134147
def wait_for_boot_menu(cmd_port: serial.Serial, console: SerialConsole, seconds: float) -> None:
135148
print("Reset the board now. Sending 'B' repeatedly on the command UART...")
136149
deadline = time.monotonic() + seconds
@@ -209,6 +222,12 @@ def transfer_file(
209222
print("Ymodem transfer finished.")
210223

211224

225+
def send_ota_trigger(data_port: serial.Serial) -> None:
226+
print("Sending OTA trigger to APP on USART2...")
227+
data_port.write(OTA_TRIGGER)
228+
data_port.flush()
229+
230+
212231
def parse_args() -> argparse.Namespace:
213232
parser = argparse.ArgumentParser(description="Send APP image to STM32 bootloader over two UARTs")
214233
parser.add_argument("--cmd-port", required=True, help="Command/debug UART, typically USART1 (for example COM5)")
@@ -238,11 +257,23 @@ def main() -> int:
238257

239258
console = SerialConsole(cmd_port, "cmd")
240259

241-
wait_for_boot_menu(cmd_port, console, args.boot_window)
260+
send_ota_trigger(data_port)
261+
262+
time.sleep(0.5)
263+
264+
cmd_port.reset_input_buffer()
265+
data_port.reset_input_buffer()
266+
267+
wait_for_boot_menu_withinapp(cmd_port, console, args.boot_window)
268+
269+
#wait_for_boot_menu(cmd_port, console, args.boot_window)
242270
print("Bootloader menu detected, sending command '2'...")
243271
send_command(cmd_port, b"2", console)
244272
transfer_file(data_port, file_path, console, args.retries)
245273

274+
print("Sending OTA trigger...")
275+
send_ota_trigger(data_port)
276+
246277
print("Waiting for final bootloader output...")
247278
time.sleep(1.0)
248279
console.poll()

0 commit comments

Comments
 (0)