make: Add feature to cmd 'make flash' - reset ota_data partition

Add a command `make erase_ota` - erases otadata if it there is in the
partition table otherwise error 'Partition table does not have ota_data partition'.

Closes https://github.com/espressif/esp-idf/issues/1821
This commit is contained in:
Konstantin Kondrashov 2018-06-25 11:53:10 +05:00 committed by bot
parent a1709a6682
commit de2b1cb02a
8 changed files with 126 additions and 6 deletions

View File

@ -0,0 +1,27 @@
#
# Generate partition binary
#
.PHONY: erase_ota blank_ota_data
GEN_EMPTY_PART := $(PYTHON) $(COMPONENT_PATH)/gen_empty_partition.py
BLANK_OTA_DATA_FILE = $(BUILD_DIR_BASE)/ota_data_initial.bin
# If there is no otadata partition, both OTA_DATA_OFFSET and BLANK_OTA_DATA_FILE
# expand to empty values.
ESPTOOL_ALL_FLASH_ARGS += $(OTA_DATA_OFFSET) $(BLANK_OTA_DATA_FILE)
$(BLANK_OTA_DATA_FILE): partition_table_get_info
$(GEN_EMPTY_PART) --size $(OTA_DATA_SIZE) $(BLANK_OTA_DATA_FILE)
$(eval BLANK_OTA_DATA_FILE = $(shell if [ $(OTA_DATA_SIZE) != 0 ]; then echo $(BLANK_OTA_DATA_FILE); else echo " "; fi) )
blank_ota_data: $(BLANK_OTA_DATA_FILE)
erase_ota: partition_table_get_info
@echo $(if $(OTA_DATA_OFFSET), "Erase ota_data [addr=$(OTA_DATA_OFFSET) size=$(OTA_DATA_SIZE)] ...", $(error "ERROR: Partition table does not have ota_data partition."))
$(ESPTOOLPY_SERIAL) erase_region $(OTA_DATA_OFFSET) $(OTA_DATA_SIZE)
all: blank_ota_data
flash: blank_ota_data
clean:
rm -f $(BLANK_OTA_DATA_FILE)

View File

@ -0,0 +1,83 @@
#!/usr/bin/env python
#
# generates an empty binary file
#
# This tool generates an empty binary file of the required size.
#
# Copyright 2018 Espressif Systems (Shanghai) PTE LTD
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http:#www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import print_function, division
import argparse
import os
import re
import struct
import sys
import hashlib
import binascii
__version__ = '1.0'
quiet = False
def status(msg):
""" Print status message to stderr """
if not quiet:
critical(msg)
def critical(msg):
""" Print critical message to stderr """
if not quiet:
sys.stderr.write(msg)
sys.stderr.write('\n')
def generate_blanked_file(size, output_path):
output = ""
for i in range(size):
output += b"\xFF"
try:
stdout_binary = sys.stdout.buffer # Python 3
except AttributeError:
stdout_binary = sys.stdout
with stdout_binary if output_path == '-' else open(output_path, 'wb') as f:
f.write(output)
def main():
global quiet
parser = argparse.ArgumentParser(description='Generates an empty binary file of the required size.')
parser.add_argument('--quiet', '-q', help="Don't print status messages to stderr", action='store_true')
parser.add_argument('--size', help='Size of generated the file', type=str, required=True)
parser.add_argument('output', help='Path for binary file.', nargs='?', default='-')
args = parser.parse_args()
quiet = args.quiet
size = int(args.size, 0)
if size > 0 :
generate_blanked_file(size, args.output)
return 0
class InputError(RuntimeError):
def __init__(self, e):
super(InputError, self).__init__(e)
if __name__ == '__main__':
try:
r = main()
sys.exit(r)
except InputError as e:
print(e, file=sys.stderr)
sys.exit(2)

View File

@ -65,9 +65,13 @@ all_binaries: $(PARTITION_TABLE_BIN) partition_table_get_info
partition_table_get_info: $(PARTITION_TABLE_BIN)
$(eval PHY_DATA_OFFSET:=$(shell $(GET_PART_INFO) --type data --subtype phy --offset $(PARTITION_TABLE_BIN)))
$(eval APP_OFFSET:=$(shell $(GET_PART_INFO) --default-boot-partition --offset $(PARTITION_TABLE_BIN)))
$(eval OTA_DATA_SIZE := $(shell $(GET_PART_INFO) --type data --subtype ota --size $(PARTITION_TABLE_BIN) || echo 0) )
$(eval OTA_DATA_OFFSET := $(shell $(GET_PART_INFO) --type data --subtype ota --offset $(PARTITION_TABLE_BIN)) )
export APP_OFFSET
export PHY_DATA_OFFSET
export OTA_DATA_OFFSET
export OTA_DATA_SIZE
PARTITION_TABLE_FLASH_CMD = $(ESPTOOLPY_SERIAL) write_flash $(PARTITION_TABLE_OFFSET) $(PARTITION_TABLE_BIN)
ESPTOOL_ALL_FLASH_ARGS += $(PARTITION_TABLE_OFFSET) $(PARTITION_TABLE_BIN)

View File

@ -36,7 +36,9 @@ When ``make all`` finishes, it will print a command line to use esptool.py to fl
make flash
This will flash the entire project (app, bootloader and partition table) to a new chip. The settings for serial port flashing can be configured with `make menuconfig`.
This will flash the entire project (app, bootloader and partition table) to a new chip. Also if partition table has ota_data then this command will flash a initial ota_data.
It allows to run the newly loaded app from a factory partition (or the first OTA partition, if factory partition is not present).
The settings for serial port flashing can be configured with `make menuconfig`.
You don't need to run ``make all`` before running ``make flash``, ``make flash`` will automatically rebuild anything which needs it.

View File

@ -63,13 +63,15 @@ Save your changes, and type `make` to build the example.
## Step 4: Flash OTA Example
When flashing, use the `erase_flash` target first to erase the entire flash (this deletes any leftover data in the ota_data partition). Then flash the factory image over serial:
When flashing, use the `make flash` to flash the factory image. This command will find if partition table has ota_data partition (as in our case) then ota_data will erase to initial.
It allows to run the newly loaded app from a factory partition.
```
make erase_flash flash
make flash
```
(The `make erase_flash flash` means "erase everything, then flash". `make flash` only erases the parts of flash which are being rewritten.)
After first update, if you want to return back to factory app (or the first OTA partition, if factory partition is not present) then use the command `make erase_ota`.
It erases ota_data partition to initial.
## Step 5: Run the OTA Example

View File

@ -34,6 +34,7 @@ help:
@echo "make size-components, size-files - Finer-grained memory footprints"
@echo "make size-symbols - Per symbol memory footprint. Requires COMPONENT=<component>"
@echo "make erase_flash - Erase entire flash contents"
@echo "make erase_ota - Erase ota_data partition. After that will boot first bootable partition (factory or OTAx)."
@echo "make monitor - Run idf_monitor tool to monitor serial output from app"
@echo "make simple_monitor - Monitor serial output on terminal console"
@echo "make list-components - List all components in the project"
@ -547,7 +548,7 @@ list-components:
$(foreach cp,$(COMPONENT_PATHS),$(info $(cp)))
# print flash command, so users can dump this to config files and download somewhere without idf
print_flash_cmd: partition_table_get_info
print_flash_cmd: partition_table_get_info blank_ota_data
echo $(ESPTOOL_WRITE_FLASH_OPTIONS) $(ESPTOOL_ALL_FLASH_ARGS) | sed -e 's:'$(PWD)/build/'::g'
# Check toolchain version using the output of xtensa-esp32-elf-gcc --version command.

View File

@ -5,6 +5,7 @@ components/heap/test_multi_heap_host/test_all_configs.sh
components/idf_test/unit_test/TestCaseScript/IDFUnitTest/__init__.py
components/partition_table/gen_esp32part.py
components/partition_table/parttool.py
components/app_update/gen_empty_partition.py
components/partition_table/test_gen_esp32part_host/gen_esp32part_tests.py
components/ulp/esp32ulp_mapgen.py
components/nvs_flash/nvs_partition_generator/nvs_partition_gen.py

View File

@ -92,7 +92,7 @@ $(BINARIES_DIR)/%/$(PROJECT_NAME).bin: configs/%
cp $(BUILDS_DIR)/$*/$(PROJECT_NAME).elf $(BINARIES_DIR)/$*/
cp $(BUILDS_DIR)/$*/$(PROJECT_NAME).bin $(BINARIES_DIR)/$*/
cp $(BUILDS_DIR)/$*/$(PROJECT_NAME).map $(BINARIES_DIR)/$*/
cp $(BUILDS_DIR)/$*/partition_table*.bin $(BINARIES_DIR)/$*/
cp $(BUILDS_DIR)/$*/*.bin $(BINARIES_DIR)/$*/
cp $(BUILDS_DIR)/$*/sdkconfig $(BINARIES_DIR)/$*/