Skip to content

Commit 166d91f

Browse files
committed
Merge branch 'feature/remove_raw_ota_exmaple_v3.1' into 'release/v3.1'
Update verify and document for OTA of ESP8285(ESP8266 + 1MB flash) (bakcport v3.1) See merge request sdk/ESP8266_RTOS_SDK!745
2 parents d911333 + 83ef300 commit 166d91f

15 files changed

+351
-771
lines changed

components/app_update/esp_ota_ops.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,28 @@ static ota_select s_ota_select[2];
6969

7070
const static char *TAG = "esp_ota_ops";
7171

72+
#ifndef CONFIG_ESP8266_BOOT_COPY_APP
73+
static inline int esp_ota_verify_binary(const esp_partition_pos_t *pos, esp_image_header_t *image)
74+
{
75+
const int32_t entry = image->entry_addr - 0x40200010;
76+
77+
ESP_LOGD(TAG, "OTA binary start entry 0x%x, partition start from 0x%x to 0x%x\n", entry, pos->offset,
78+
pos->offset + pos->size);
79+
80+
if (pos->offset + pos->size <= 0x100000) {
81+
if (entry <= 0 || entry <= pos->offset || entry >= pos->offset + pos->size) {
82+
const char *doc_str = "<<ESP8266_RTOS_SDK/examples/system/ota/README.md>>";
83+
84+
ESP_LOGE(TAG, "**Important**: The OTA binary link data is error, "
85+
"please refer to document %s for how to generate OTA binaries", doc_str);
86+
return ESP_ERR_INVALID_ARG;
87+
}
88+
}
89+
90+
return ESP_OK;
91+
}
92+
#endif
93+
7294
/* Return true if this is an OTA app partition */
7395
static bool is_ota_partition(const esp_partition_t *p)
7496
{
@@ -244,6 +266,13 @@ esp_err_t esp_ota_end(esp_ota_handle_t handle)
244266
goto cleanup;
245267
}
246268

269+
#ifndef CONFIG_ESP8266_BOOT_COPY_APP
270+
if (esp_ota_verify_binary(&part_pos, &data.image) != ESP_OK) {
271+
ret = ESP_ERR_OTA_VALIDATE_FAILED;
272+
goto cleanup;
273+
}
274+
#endif
275+
247276
#ifdef CONFIG_SECURE_BOOT_ENABLED
248277
ret = esp_secure_boot_verify_signature(it->part->address, data.image_len);
249278
if (ret != ESP_OK) {

components/esp8266/Makefile.projbuild

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,32 +94,32 @@ OTA_V2_TO_V3_BIN := ./build/$(PROJECT_NAME).v2_to_v3.ota.bin
9494
CONFIG_APP2_OFFSET ?= $(CONFIG_APP1_OFFSET)
9595
CONFIG_APP2_SIZE ?= $(CONFIG_APP1_SIZE)
9696

97-
OTA1_OFFSET := CONFIG_APP1_OFFSET
97+
OTA1_OFFSET := $(CONFIG_APP1_OFFSET)
9898
ifdef CONFIG_ESP8266_BOOT_COPY_APP
9999
OTA2_LINK_OFFSET := $(CONFIG_APP1_OFFSET)
100100
else
101101
OTA2_LINK_OFFSET := $(CONFIG_APP2_OFFSET)
102102
endif
103103

104104
$(OTA2_BIN): all_binaries
105-
ifeq ($(CONFIG_ESPTOOLPY_FLASHSIZE), "1MB")
105+
ifneq ($(OTA1_OFFSET), $(OTA2_LINK_OFFSET))
106106
@rm -f ./build/esp8266/esp8266_out.ld
107107
@make APP_OFFSET=$(OTA2_LINK_OFFSET) APP_SIZE=$(CONFIG_APP2_SIZE) CFLAGS= CXXFLAGS=
108108
endif
109109
@cp $(RAW_BIN) $(OTA2_BIN)
110110
@echo [GEN] $(OTA2_BIN)
111111

112112
$(OTA1_BIN): all_binaries
113-
ifeq ($(CONFIG_ESPTOOLPY_FLASHSIZE), "1MB")
113+
ifneq ($(OTA1_OFFSET), $(OTA2_LINK_OFFSET))
114114
@rm -f ./build/esp8266/esp8266_out.ld
115115
endif
116-
@make APP_OFFSET=$(CONFIG_APP1_OFFSET) APP_SIZE=$(CONFIG_APP1_SIZE) CFLAGS= CXXFLAGS=
116+
@make APP_OFFSET=$(OTA1_OFFSET) APP_SIZE=$(CONFIG_APP1_SIZE) CFLAGS= CXXFLAGS=
117117
@cp $(RAW_BIN) $(OTA1_BIN)
118118
@echo [GEN] $(OTA1_BIN)
119119

120120
$(OTA_BIN): $(OTA1_BIN) $(OTA2_BIN)
121121
@cp $(OTA1_BIN) $(OTA_BIN)
122-
ifeq ($(CONFIG_ESPTOOLPY_FLASHSIZE), "1MB")
122+
ifneq ($(OTA1_OFFSET), $(OTA2_LINK_OFFSET))
123123
@cat $(OTA2_BIN) >> $(OTA_BIN)
124124
endif
125125
@cp $(OTA1_BIN) $(RAW_BIN)

examples/system/ota/README.md

Lines changed: 114 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11

2+
# Important
3+
4+
If your development board is based on **ESP8285** or **ESP8266 + 1MB flash**, you should read this document carefully, especially the Chapter **"Principle"**.
5+
6+
---
7+
28
# Simple OTA Demo
39

410
This example demonstrates a working OTA (over the air) firmware update workflow.
@@ -11,10 +17,68 @@ This example is a *simplified demonstration*, for production firmware updates yo
1117

1218
An app running on ESP8266 can upgrade itself by downloading a new app "image" binary file, and storing it in flash.
1319

14-
In this example, the ESP8266 has 3 images in flash: factory, OTA_0, OTA_1. Each of these is a self-contained partition. The number of OTA image partition is determined by the partition table layout.
20+
In this example, the ESP8266 has 2 images in flash: OTA_0, OTA_1. Each of these is a self-contained partition. The number of OTA image partition is determined by the partition table layout.
21+
22+
Flash the example through serial port with command "make flash" to update the OTA_0 app image. In first boot, the bootloader loads this OTA_0 app image which then will execute an OTA update (triggered in the example code). The OTA update will download a new image from an http server and save it into the OTA_1 partition. After that, the example code will update the ota_data partition to indicate the new app partition, and then reboot, which leads to the second boot. During the second boot, the bootloader will read the ota_data, and select to run the new OTA image.
23+
24+
# Custom partition configuration
25+
26+
If customers want to use their own partition tables with specific partition location. Please see following steps:
27+
28+
## Step 1: Create partition file
29+
30+
Create a partition managment file with "cvs" formate, please refer to "doc/en/api-guides/partition-tables.rst"
31+
32+
## Step 2: Select custom partition mode
33+
34+
1. Select custom partition tables at "menuconfig":
35+
36+
```
37+
Partition Table --->
38+
Partition Table (XXXXXX) --->
39+
(X) Custom partition table CSV
40+
```
41+
42+
2. Configurate custom partition location at:
43+
44+
```
45+
(XXXXXX)Custom partition CSV file
46+
```
47+
48+
Note: System will add the absolute path of the project to the head of the "Custom partition CSV file" automatically when compling.
49+
50+
3. Configurate patition table location if necessary:
51+
52+
```
53+
(XXXXXX)Partition table offset address at flash
54+
```
55+
56+
## Step 3: Configurate application location:
57+
58+
Configurate application location at "mennuconfig" like following base on partition table file.
59+
60+
If you select 1MB flash, application location configuration menu is like following:
61+
62+
```
63+
Partition Table --->
64+
65+
[*] Support to setup partition parameter of APP2
66+
(0x5000) App1 offset address
67+
(0x7B000) App1 size by bytes
68+
(0x85000) App2 offset address
69+
(0x7b000) App2 size by bytes
70+
```
71+
72+
If you select 2MB flash and above size, application location configuration menu is like following:
73+
74+
```
75+
Partition Table --->
1576
16-
Flashing the example over serial with "make flash" updates the factory app image. On first boot, the bootloader loads this factory app image which then performs an OTA update (triggered in the example code). The update downloads a new image from an http server and saves it into the OTA_0 partition. At this point the example code updates the ota_data partition to indicate the new app partition, and resets. The bootloader reads ota_data, determines the new OTA image has been selected, and runs it.
77+
(0x10000) APP1 partition offset
78+
(0xF0000) APP1 partition size(by bytes)
79+
```
1780

81+
Note: The firmware location information must be same as partition table file. **make ota flash** will only download the app1 at **APP1 partition offset**.
1882

1983
# Workflow
2084

@@ -32,11 +96,26 @@ Python has a built-in HTTP server that can be used for example purposes.
3296

3397
For our upgrade example OTA file, we're going to use the `get-started/project_template` example.
3498

35-
Open a new terminal to run the HTTP server, then run these commands to build the example and start the server:
99+
Open a new terminal to run the HTTP server, then run these commands to build the example and start the server, if your board's flash size is "1 MB", you should firstly configure flash size to be "1 MB"(default is "2 MB") at "menuconfig" and then build project:
100+
101+
Configure 1MB flash if it is needed:
102+
103+
```
104+
Serial flasher config --->
105+
Flash size (2 MB) --->
106+
(X) 1 MB
107+
```
108+
109+
Build project:
36110

37111
```
38112
cd $IDF_PATH/examples/get-started/project_template
39-
make
113+
make ota
114+
```
115+
116+
Start http server at the directory of "build":
117+
118+
```
40119
cd build
41120
python -m SimpleHTTPServer 8070
42121
```
@@ -45,8 +124,6 @@ While the server is running, the contents of the build directory can be browsed
45124

46125
NB: On some systems, the command may be `python2 -m SimpleHTTPServer`.
47126

48-
NB: You've probably noticed there is nothing special about the "project_template" example when used for OTA updates. This is because any .bin app file which is built by esp-idf can be used as an app image for OTA. The only difference is whether it is written to a factory partition or an OTA partition.
49-
50127
If you have any firewall software running that will block incoming access to port 8070, configure it to allow access while running the example.
51128

52129
## Step 3: Build OTA Example
@@ -59,6 +136,16 @@ Change back to the OTA example directory, and type `make menuconfig` to configur
59136

60137
If serving the "project_template" example, you can leave the default filename as-is.
61138

139+
Configure 1MB flash if need:
140+
141+
```
142+
Serial flasher config --->
143+
Flash size (2 MB) --->
144+
(X) 1 MB
145+
```
146+
147+
Configurate the application location information and it must be the same as the OTA example's information, you can refer to the **Step 3: Configurate application location** of **Custom partition configuration**.
148+
62149
Save your changes, and type `make` to build the example.
63150

64151
## Step 4: Flash OTA Example
@@ -80,11 +167,29 @@ When the example starts up, it will print "ota: Starting OTA example..." then:
80167
3. Write the image to flash, and configure the next boot from this image.
81168
4. Reboot
82169

170+
# Principle
171+
172+
Command "make ota" will generate 3 binaries: "xxx(project name).app1.bin", "xxx(project name).app2.bin" and "xxx(project name).ota.bin". You should only upload the "xxx(project name).ota.bin" to your OTA server and let the app download it as the example.
173+
174+
"xxx.app1.bin" is for downloading to OTA_0 partition, and "xxx.app2.bin" is for downloading to OTA_1 partition. If your board's flash size is larger than "1 MB" or you select "Copy OTA" function, then "xxx.app1.bin" = "xxx.app2.bin" = "xxx.ota.bin". Otherwise If your board's flash size is "1 MB" and you don't select "Copy OTA" function, "xxx.app1.bin" != "xxx.app2.bin" != "xxx.ota.bin", "xxx.ota.bin" = "xxx.app1.bin" + "xxx.app2.bin". So the flash size configuration is very important. Otherwise if and at the last The example will select the binary it needs and download it into flash.
175+
176+
Based on the above theory, we can see that for ESP8266 + 2MB flash(or larger size), app1 and app2 are the same, you can download it directly without any distinction. But for ESP8285 (ESP8266 + 1MB flash), the ota0 (app1) and ota1 (app2) are different, you need to distinguish which one should be downloaded, and to what location, during FOTA. Now, the way in the example code is to synthesize app1 and app2 into an "xxxx (project name).ota.bin". And only write the target app (app1 or app2) into the flash, according to the location of download, when FOTA; the other part will be discarded.
177+
178+
On the other hand, if you want to use ESP8285(ESP8266 + 1MB flash) and don't want to upload 2 binaries for OTA, you can enable the "Copy OTA" function in menuconfig.
179+
180+
```
181+
Component config --->
182+
ESP8266-specific --->
183+
[*] (**Expected**)Boot copy app
184+
```
185+
186+
After enabling "Copy OTA" mode, the system will always download the app bin into ota_1 partition and then re-boot. After reboot, the bootloader will unpack the app bin and copy it to the ota_0 partition, then run the application in ota_0 partition.
187+
83188
# Troubleshooting
84189

85-
* Check your PC can ping the ESP8266 at its IP, and that the IP, AP and other configuration settings are correct in menuconfig.
86-
* Check if any firewall software is preventing incoming connections on the PC.
87-
* Check you can see the configured file (default project_template.bin) if you browse the file listing at http://127.0.0.1/
190+
* Check whether your PC can ping the ESP8266 at its IP, and make sure that the IP, AP and other configuration settings are correct in menuconfig.
191+
* Check if there is any firewall software on the PC that prevents incoming connections.
192+
* Check whether you can see the configured file (default project_template.ota.bin) when browsing the file listing at http://127.0.0.1/
88193
* If you have another PC or a phone, try viewing the file listing from the separate host.
89194

90195
## Error "ota_begin error err=0x104"

examples/system/ota/main/Kconfig.projbuild

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ config SERVER_PORT
3232

3333
config EXAMPLE_FILENAME
3434
string "HTTP GET Filename"
35-
default "/hello-world.bin"
35+
default "/project_template.ota.bin"
3636
help
3737
Filename of the app image file to download for
3838
the OTA update.

0 commit comments

Comments
 (0)