From 94fa6fbd7927756107ad4e22916b396264eb9137 Mon Sep 17 00:00:00 2001 From: Alexandre Abadie Date: Mon, 12 Feb 2024 11:38:23 +0100 Subject: [PATCH 1/7] drv/ota: add logic to perform secure firmware update --- dist/scripts/testbed/.gitignore | 2 + dist/scripts/testbed/dotbot-flash.py | 67 +++++++++++++++++++++++---- dist/scripts/testbed/generate_keys.py | 54 +++++++++++++++++++++ dist/scripts/testbed/requirements.txt | 1 + drv/drv.emProject | 2 +- drv/ota.h | 15 +++++- drv/ota/ota.c | 41 ++++++++++++++-- drv/ota/public_key.h | 16 +++++++ 8 files changed, 183 insertions(+), 15 deletions(-) create mode 100644 dist/scripts/testbed/.gitignore create mode 100755 dist/scripts/testbed/generate_keys.py create mode 100644 drv/ota/public_key.h diff --git a/dist/scripts/testbed/.gitignore b/dist/scripts/testbed/.gitignore new file mode 100644 index 000000000..ad4b63c2e --- /dev/null +++ b/dist/scripts/testbed/.gitignore @@ -0,0 +1,2 @@ +private_key +public_key.h diff --git a/dist/scripts/testbed/dotbot-flash.py b/dist/scripts/testbed/dotbot-flash.py index d9ccfb7da..cd990d37d 100755 --- a/dist/scripts/testbed/dotbot-flash.py +++ b/dist/scripts/testbed/dotbot-flash.py @@ -1,5 +1,6 @@ #!/usr/bin/env python +import os import logging import time @@ -8,10 +9,13 @@ from enum import Enum import click -from tqdm import tqdm - import serial import structlog + +from tqdm import tqdm +from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey + from dotbot.hdlc import hdlc_encode, HDLCHandler, HDLCState from dotbot.protocol import PROTOCOL_VERSION from dotbot.serial_interface import SerialInterface, SerialInterfaceException @@ -25,14 +29,16 @@ "nrf52840": 4096, "nrf5340-app": 4096, } - +PRIVATE_KEY_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), "private_key") class MessageType(Enum): """Types of bootloader message.""" - OTA_MESSAGE_TYPE_FW = 0 - OTA_MESSAGE_TYPE_FW_ACK = 1 - OTA_MESSAGE_TYPE_INFO = 2 + OTA_MESSAGE_TYPE_START = 0 + OTA_MESSAGE_TYPE_START_ACK = 1 + OTA_MESSAGE_TYPE_FW = 2 + OTA_MESSAGE_TYPE_FW_ACK = 3 + OTA_MESSAGE_TYPE_INFO = 4 class CpuType(Enum): @@ -109,6 +115,7 @@ def __init__(self, port, baudrate, image): self.hdlc_handler = HDLCHandler() self.device_info = None self.device_info_received = False + self.start_ack_received = False pad_length = CHUNK_SIZE - (len(image) % CHUNK_SIZE) self.image = image + bytearray(b"\xff") * (pad_length + 1) self.last_acked_chunk = -1 @@ -121,7 +128,9 @@ def on_byte_received(self, byte): payload = self.hdlc_handler.payload if not payload: return - if payload[0] == MessageType.OTA_MESSAGE_TYPE_FW_ACK.value: + if payload[0] == MessageType.OTA_MESSAGE_TYPE_START_ACK.value: + self.start_ack_received = True + elif payload[0] == MessageType.OTA_MESSAGE_TYPE_FW_ACK.value: self.last_acked_chunk = int.from_bytes(payload[1:5], byteorder="little") elif payload[0] == MessageType.OTA_MESSAGE_TYPE_INFO.value: self.device_info = DeviceInfo.from_bytes(payload[1:]) @@ -134,8 +143,38 @@ def fetch_device_info(self): length=1, byteorder="little" ) self.serial.write(hdlc_encode(buffer)) - time.sleep(0.2) print("Fetching device info...") + time.sleep(0.2) + + def send_start_update(self, secure): + if secure is True: + digest = hashes.Hash(hashes.SHA256()) + pos = 0 + while pos + CHUNK_SIZE <= len(self.image) + 1: + digest.update(self.image[pos : pos + CHUNK_SIZE]) + pos += CHUNK_SIZE + fw_hash = digest.finalize() + private_key_bytes = open(PRIVATE_KEY_PATH, "rb").read() + private_key = Ed25519PrivateKey.from_private_bytes(private_key_bytes) + attempts = 0 + while self.start_ack_received is False and attempts < 3: + buffer = bytearray() + buffer += int(MessageType.OTA_MESSAGE_TYPE_START.value).to_bytes( + length=1, byteorder="little" + ) + buffer += int((len(self.image) - 1) / CHUNK_SIZE).to_bytes( + length=4, byteorder="little" + ) + if secure is True: + buffer += fw_hash + signature = private_key.sign(bytes(buffer[1:])) + buffer += signature + self.serial.write(hdlc_encode(buffer)) + attempts += 1 + print("Sending start update notification...") + delay = 3 if secure and self.device_info.cpu != "nrf52840" else 0.2 + time.sleep(delay) + return attempts < 3 def flash(self): page_size = PAGE_SIZE_MAP[self.device_info.cpu] @@ -172,6 +211,12 @@ def flash(self): default="/dev/ttyACM0", help="Serial port to use to send the firmware.", ) +@click.option( + "-s", + "--secure", + is_flag=True, + help="Use cryptographic security (hash and signature).", +) @click.option( "-y", "--yes", @@ -179,7 +224,7 @@ def flash(self): help="Continue flashing without prompt.", ) @click.argument("image", type=click.File(mode="rb", lazy=True)) -def main(port, yes, image): +def main(port, secure, yes, image): # Disable logging configure in PyDotBot structlog.configure( wrapper_class=structlog.make_filtering_bound_logger(logging.CRITICAL), @@ -216,6 +261,10 @@ def main(port, yes, image): return if yes is False: click.confirm("Do you want to continue?", default=True, abort=True) + ret = flasher.send_start_update(secure) + if ret is False: + print("Error: No start acknowledment received. Aborting.") + return flasher.flash() print("Done") diff --git a/dist/scripts/testbed/generate_keys.py b/dist/scripts/testbed/generate_keys.py new file mode 100755 index 000000000..124e8c6e0 --- /dev/null +++ b/dist/scripts/testbed/generate_keys.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python + +import os + +from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey +from cryptography.hazmat.primitives.serialization import ( + Encoding, + PrivateFormat, + PublicFormat, + NoEncryption, +) + +PRIVATE_KEY_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), "private_key") +PUBLIC_KEY_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), "../../../drv/ota/public_key.h") + +HEADER_FORMAT = """/* + * PLEASE DON'T EDIT + * + * This file was automatically generated + */ + +#ifndef __{name_upper}_H +#define __{name_upper}_H + +#include + +const uint8_t {name}[] = {{ + {data} +}}; + +#endif /* __{name_upper}_H */ +""" + + +def save_as_c_array(path, name, data): + data_str = ", ".join([f"0x{data[i:i+2]}" for i in range(0, len(data), 2)]) + print(f"Saving '{name}' to {os.path.abspath(path)}") + with open(path, "w") as f: + f.write(HEADER_FORMAT.format(name=name, name_upper=name.upper(), data=data_str)) + + +def main(): + key_pair = Ed25519PrivateKey.generate() + private_key = key_pair.private_bytes(Encoding.Raw, PrivateFormat.Raw, NoEncryption()) + public_key = key_pair.public_key().public_bytes(Encoding.Raw, PublicFormat.Raw) + + print(f"Generated keys:\n - private key\t: {private_key.hex()}\n - public key\t: {public_key.hex()}") + print(f"Saving 'private key' to {os.path.abspath(PRIVATE_KEY_PATH)}") + with open(PRIVATE_KEY_PATH, "wb") as f: + f.write(private_key) + save_as_c_array(PUBLIC_KEY_PATH, "public_key", public_key.hex()) + +if __name__ == "__main__": + main() diff --git a/dist/scripts/testbed/requirements.txt b/dist/scripts/testbed/requirements.txt index f6c4839a3..df144dc15 100644 --- a/dist/scripts/testbed/requirements.txt +++ b/dist/scripts/testbed/requirements.txt @@ -1,3 +1,4 @@ click==8.1.7 +cryptography==41.0.5 tqdm==4.66.1 pydotbot diff --git a/drv/drv.emProject b/drv/drv.emProject index 7a9c3c483..885ee62a9 100644 --- a/drv/drv.emProject +++ b/drv/drv.emProject @@ -88,7 +88,7 @@ diff --git a/drv/ota.h b/drv/ota.h index 012ab4b2e..92ab7f4b4 100644 --- a/drv/ota.h +++ b/drv/ota.h @@ -18,7 +18,9 @@ //=========================== defines ========================================== -#define DB_OTA_CHUNK_SIZE (128U) ///< Size of a firmware chunk +#define DB_OTA_CHUNK_SIZE (128U) ///< Size of a firmware chunk +#define DB_OTA_SHA256_LENGTH (32U) +#define DB_OTA_SIGNATURE_LENGTH (64U) typedef void (*db_ota_reply_t)(const uint8_t *, size_t); ///< Transport agnostic function used to reply to the flasher script @@ -34,6 +36,15 @@ typedef struct { db_ota_mode_t mode; ///< Firmware update mode } db_ota_conf_t; +///< Firmware update start notification packet +typedef struct __attribute__((packed, aligned(4))) { + uint32_t chunk_count; ///< Number of chunks +#if defined(OTA_USE_CRYPTO) + uint8_t hash[DB_OTA_SHA256_LENGTH]; ///< SHA256 hash of the firmware + uint8_t signature[DB_OTA_SIGNATURE_LENGTH]; ///< Signature of the firmware hash +#endif +} db_ota_start_notification_t; + ///< Firmware update packet typedef struct __attribute__((packed, aligned(4))) { uint32_t index; ///< Index of the chunk @@ -51,6 +62,8 @@ typedef enum { ///< Message type typedef enum { + DB_OTA_MESSAGE_TYPE_START, + DB_OTA_MESSAGE_TYPE_START_ACK, DB_OTA_MESSAGE_TYPE_FW, DB_OTA_MESSAGE_TYPE_FW_ACK, DB_OTA_MESSAGE_TYPE_INFO, diff --git a/drv/ota/ota.c b/drv/ota/ota.c index 83ae55907..8e7913bc8 100644 --- a/drv/ota/ota.c +++ b/drv/ota/ota.c @@ -17,6 +17,12 @@ #include "ota.h" #include "partition.h" +#if defined(OTA_USE_CRYPTO) +#include "ed25519.h" +#include "sha256.h" +#include "public_key.h" +#endif + //=========================== defines ========================================== typedef struct { @@ -27,6 +33,7 @@ typedef struct { uint32_t target_partition; uint32_t addr; uint32_t last_index_acked; + uint8_t hash[DB_OTA_SHA256_LENGTH]; } db_ota_vars_t; //=========================== variables ======================================== @@ -62,7 +69,15 @@ void db_ota_start(void) { void db_ota_finish(void) { // Switch active image in partition table before resetting the device - // TODO: do more verifications (CRC, etc) before rebooting +#if defined(OTA_USE_CRYPTO) + uint8_t hash_result[DB_OTA_SHA256_LENGTH] = { 0 }; + crypto_sha256(hash_result); + + if (memcmp(hash_result, _ota_vars.hash, DB_OTA_SHA256_LENGTH) != 0) { + return; + } +#endif + if (_ota_vars.table.active_image != _ota_vars.target_partition) { _ota_vars.table.active_image = _ota_vars.target_partition; db_write_partitions_table(&_ota_vars.table); @@ -92,18 +107,36 @@ void db_ota_handle_message(const uint8_t *message) { memcpy(&_ota_vars.reply_buffer[1], &message_info, sizeof(db_ota_message_info_t)); _ota_vars.config->reply(_ota_vars.reply_buffer, sizeof(db_ota_message_type_t) + sizeof(db_ota_message_info_t)); } break; + case DB_OTA_MESSAGE_TYPE_START: + { + const db_ota_start_notification_t *ota_start = (const db_ota_start_notification_t *)&message[1]; +#if defined(OTA_USE_CRYPTO) + const uint8_t *hash = ota_start->hash; + if (!crypto_ed25519_verify(ota_start->signature, DB_OTA_SIGNATURE_LENGTH, (const uint8_t *)ota_start, sizeof(db_ota_start_notification_t) - DB_OTA_SIGNATURE_LENGTH, public_key)) { + break; + } + memcpy(_ota_vars.hash, hash, DB_OTA_SHA256_LENGTH); + crypto_sha256_init(); +#else + (void)ota_start; +#endif + db_ota_start(); + // Acknowledge the update start + _ota_vars.reply_buffer[0] = DB_OTA_MESSAGE_TYPE_START_ACK; + _ota_vars.config->reply(_ota_vars.reply_buffer, sizeof(db_ota_message_type_t)); + } break; case DB_OTA_MESSAGE_TYPE_FW: { const db_ota_pkt_t *ota_pkt = (const db_ota_pkt_t *)&message[1]; const uint32_t chunk_index = ota_pkt->index; const uint32_t chunk_count = ota_pkt->chunk_count; - if (chunk_index == 0) { - db_ota_start(); - } if (_ota_vars.last_index_acked != chunk_index) { // Skip writing the chunk if already acked db_ota_write_chunk(ota_pkt); +#if defined(OTA_USE_CRYPTO) + crypto_sha256_update((const uint8_t *)ota_pkt->fw_chunk, DB_OTA_CHUNK_SIZE); +#endif } // Acknowledge the received chunk diff --git a/drv/ota/public_key.h b/drv/ota/public_key.h new file mode 100644 index 000000000..572662b71 --- /dev/null +++ b/drv/ota/public_key.h @@ -0,0 +1,16 @@ +/* + * PLEASE DON'T EDIT + * + * This file was automatically generated + */ + +#ifndef __PUBLIC_KEY_H +#define __PUBLIC_KEY_H + +#include + +const uint8_t public_key[] = { + 0xe7, 0xb6, 0x65, 0xb0, 0x97, 0xad, 0xde, 0x27, 0xd8, 0x6b, 0xb1, 0x7b, 0x23, 0x00, 0x9f, 0x22, 0x96, 0x40, 0x7a, 0x25, 0x46, 0x69, 0x7d, 0x1b, 0x0c, 0x54, 0x3e, 0x27, 0xbb, 0xe9, 0x8e, 0xa0 +}; + +#endif /* __PUBLIC_KEY_H */ From 4460cd2bc1b504f80ed4b2f2fe7d51908f2b83a2 Mon Sep 17 00:00:00 2001 From: Alexandre Abadie Date: Mon, 12 Feb 2024 11:38:38 +0100 Subject: [PATCH 2/7] bsp/nvmc: fix assert --- bsp/nrf/nvmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bsp/nrf/nvmc.c b/bsp/nrf/nvmc.c index 0894c9eed..3da4349bf 100644 --- a/bsp/nrf/nvmc.c +++ b/bsp/nrf/nvmc.c @@ -53,7 +53,7 @@ void db_nvmc_write(const uint32_t *addr, const void *data, size_t len) { // Length must be a multiple of 4 bytes assert(len % 4 == 0); // writes must be 4 bytes aligned - assert(!((uint32_t)addr % 4) && !((uint32_t)data % 4)); + assert(((uint32_t)addr % 4) && ((uint32_t)data % 4)); uint32_t *dest_addr = (uint32_t *)addr; const uint32_t *data_addr = data; From 683a04fc7bf6ce047dd3eaf36f612e62adbb5f9b Mon Sep 17 00:00:00 2001 From: Alexandre Abadie Date: Mon, 12 Feb 2024 11:39:05 +0100 Subject: [PATCH 3/7] testbed: refactor segger studio project files --- testbed/bootloader.emProject | 44 ++++++++++++++++ testbed/bootloader/main.c | 14 ++++- testbed/dotbot-v1-bootloader.emProject | 61 ++++++++++++++++++++++ testbed/dotbot-v2-bootloader.emProject | 61 ++++++++++++++++++++++ testbed/nrf52833dk-bootloader.emProject | 61 ++++++++++++++++++++++ testbed/nrf52840dk-bootloader.emProject | 61 ++++++++++++++++++++++ testbed/nrf5340dk-app-bootloader.emProject | 61 ++++++++++++++++++++++ testbed/partition1/main.c | 14 +++++ testbed/sailbot-v1-bootloader.emProject | 61 ++++++++++++++++++++++ testbed/testbed.emProject | 47 ++--------------- 10 files changed, 440 insertions(+), 45 deletions(-) create mode 100644 testbed/bootloader.emProject create mode 100644 testbed/dotbot-v1-bootloader.emProject create mode 100644 testbed/dotbot-v2-bootloader.emProject create mode 100644 testbed/nrf52833dk-bootloader.emProject create mode 100644 testbed/nrf52840dk-bootloader.emProject create mode 100644 testbed/nrf5340dk-app-bootloader.emProject create mode 100644 testbed/sailbot-v1-bootloader.emProject diff --git a/testbed/bootloader.emProject b/testbed/bootloader.emProject new file mode 100644 index 000000000..a3e389150 --- /dev/null +++ b/testbed/bootloader.emProject @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testbed/bootloader/main.c b/testbed/bootloader/main.c index ef9955c55..13f3e774d 100644 --- a/testbed/bootloader/main.c +++ b/testbed/bootloader/main.c @@ -99,10 +99,13 @@ static void _write_partitions_table(const db_partitions_table_t *table) { //=========================== callbacks ======================================== +#ifdef DB_LED4_PIN static void _blink_led4(void) { db_gpio_toggle(&db_led4); } +#endif +#ifdef DB_BTN4_PIN static void _uart_callback(uint8_t byte) { _bootloader_vars.uart_byte = byte; _bootloader_vars.uart_byte_received = true; @@ -119,6 +122,7 @@ static const db_ota_conf_t _bootloader_ota_config = { .mode = DB_OTA_MODE_BOOTLOADER, .reply = _bootloader_reply, }; +#endif //================================= main ======================================= @@ -133,7 +137,9 @@ int main(void) { uint32_t active_image = (_bootloader_vars.table.active_image < DB_PARTITIONS_MAX_COUNT) ? _bootloader_vars.table.active_image : 0; +#ifdef DB_BTN4_PIN db_gpio_init(&db_btn4, DB_GPIO_IN_PU); + uint8_t keep_active = !db_gpio_read(&db_btn4); if (keep_active) { @@ -145,6 +151,9 @@ int main(void) { db_uart_init(0, &db_uart_rx, &db_uart_tx, DB_UART_BAUDRATE, &_uart_callback); db_ota_init(&_bootloader_ota_config); } +#else + uint8_t keep_active = 0; +#endif while (keep_active) { if (_bootloader_vars.uart_byte_received) { @@ -167,15 +176,18 @@ int main(void) { } } +#ifdef DB_BTN1_PIN if (!db_gpio_read(&db_btn1)) { _bootloader_vars.table.active_image = 0; _write_partitions_table(&_bootloader_vars.table); } - +#endif +#ifdef DB_BTN2_PIN if (!db_gpio_read(&db_btn2)) { _bootloader_vars.table.active_image = 1; _write_partitions_table(&_bootloader_vars.table); } +#endif } _jump_to_image((uint32_t *)_bootloader_vars.table.partitions[active_image].address); diff --git a/testbed/dotbot-v1-bootloader.emProject b/testbed/dotbot-v1-bootloader.emProject new file mode 100644 index 000000000..3bad2fe19 --- /dev/null +++ b/testbed/dotbot-v1-bootloader.emProject @@ -0,0 +1,61 @@ + + + + + + + + + + diff --git a/testbed/dotbot-v2-bootloader.emProject b/testbed/dotbot-v2-bootloader.emProject new file mode 100644 index 000000000..5dda0f4e0 --- /dev/null +++ b/testbed/dotbot-v2-bootloader.emProject @@ -0,0 +1,61 @@ + + + + + + + + + + diff --git a/testbed/nrf52833dk-bootloader.emProject b/testbed/nrf52833dk-bootloader.emProject new file mode 100644 index 000000000..0d168cda2 --- /dev/null +++ b/testbed/nrf52833dk-bootloader.emProject @@ -0,0 +1,61 @@ + + + + + + + + + + diff --git a/testbed/nrf52840dk-bootloader.emProject b/testbed/nrf52840dk-bootloader.emProject new file mode 100644 index 000000000..01f1868d4 --- /dev/null +++ b/testbed/nrf52840dk-bootloader.emProject @@ -0,0 +1,61 @@ + + + + + + + + + + diff --git a/testbed/nrf5340dk-app-bootloader.emProject b/testbed/nrf5340dk-app-bootloader.emProject new file mode 100644 index 000000000..950f8497a --- /dev/null +++ b/testbed/nrf5340dk-app-bootloader.emProject @@ -0,0 +1,61 @@ + + + + + + + + + + diff --git a/testbed/partition1/main.c b/testbed/partition1/main.c index 77d36b1c5..bf9a76115 100644 --- a/testbed/partition1/main.c +++ b/testbed/partition1/main.c @@ -41,14 +41,18 @@ static void _radio_callback(uint8_t *pkt, uint8_t len) { _app_vars.packet_received = true; } +#if defined(DB_LED1_PIN) && defined(DB_BTN1_PIN) static void _btn_toggle_callback(void *ctx) { (void)ctx; db_gpio_toggle(&db_led1); } +#endif +#ifdef DB_LED2_PIN static void _toggle_led(void) { db_gpio_toggle(&db_led2); } +#endif //=========================== private ========================================== @@ -73,14 +77,24 @@ int main(void) { db_radio_set_frequency(8); db_radio_rx(); +#ifdef DB_LED1_PIN db_gpio_init(&db_led1, DB_GPIO_OUT); db_gpio_set(&db_led1); +#endif + +#ifdef DB_LED2_PIN db_gpio_init(&db_led2, DB_GPIO_OUT); db_gpio_set(&db_led2); +#endif + +#if defined(DB_LED1_PIN) && defined(DB_BTN1_PIN) db_gpio_init_irq(&db_btn1, DB_GPIO_IN_PU, DB_GPIO_IRQ_EDGE_RISING, _btn_toggle_callback, NULL); +#endif +#ifdef DB_LED2_PIN db_timer_init(); db_timer_set_periodic_ms(0, 500, &_toggle_led); +#endif while (1) { __WFE(); diff --git a/testbed/sailbot-v1-bootloader.emProject b/testbed/sailbot-v1-bootloader.emProject new file mode 100644 index 000000000..e72ee8605 --- /dev/null +++ b/testbed/sailbot-v1-bootloader.emProject @@ -0,0 +1,61 @@ + + + + + + + + + + diff --git a/testbed/testbed.emProject b/testbed/testbed.emProject index 554f20b4f..24f651e3e 100644 --- a/testbed/testbed.emProject +++ b/testbed/testbed.emProject @@ -1,55 +1,13 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -88,6 +46,7 @@ Date: Mon, 12 Feb 2024 11:39:47 +0100 Subject: [PATCH 4/7] *.emProject: enable secure OTA for all platforms --- Makefile | 16 +++++++++++----- dotbot-v1.emProject | 3 ++- dotbot-v2.emProject | 3 ++- nrf52833dk.emProject | 2 +- nrf52840dk.emProject | 2 +- nrf5340dk-app.emProject | 2 +- sailbot-v1.emProject | 3 ++- 7 files changed, 20 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index 0a186a96c..db8e6e703 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,7 @@ SEGGER_DIR ?= /opt/segger BUILD_CONFIG ?= Debug BUILD_TARGET ?= dotbot-v1 PROJECT_FILE ?= $(BUILD_TARGET).emProject +BOOTLOADER ?= bootloader ifeq (nrf5340dk-app,$(BUILD_TARGET)) PROJECTS ?= \ @@ -56,30 +57,30 @@ else ifeq (nrf5340dk-net,$(BUILD_TARGET)) 03app_log_dump \ 03app_nrf5340_net \ # + # Bootloader not supported on nrf5340 network core + BOOTLOADER := else PROJECTS ?= $(shell find projects/ -maxdepth 1 -mindepth 1 -type d | tr -d "/" | sed -e s/projects// | sort) endif TESTBED_APPS ?= $(shell find testbed/ -maxdepth 1 -mindepth 1 -type d | tr -d "/" | sed -e s/testbed// | sort) +TESTBED_APPS := $(filter-out bootloader,$(TESTBED_APPS)) # remove incompatible apps (nrf5340, sailbot gateway) for dotbot (v1, v2) builds ifneq (,$(filter dotbot-v1,$(BUILD_TARGET))) PROJECTS := $(filter-out 01bsp_qdec 01drv_lis3mdl 01drv_move 03app_dotbot_gateway 03app_dotbot_gateway_lr 03app_sailbot 03app_nrf5340_%,$(PROJECTS)) ARTIFACT_PROJECTS := 03app_dotbot - TESTBED_APPS := $(filter-out bootloader partition0 partition1,$(TESTBED_APPS)) endif ifneq (,$(filter dotbot-v2,$(BUILD_TARGET))) PROJECTS := $(filter-out 03app_dotbot_gateway 03app_dotbot_gateway_lr 03app_sailbot 03app_nrf5340_net,$(PROJECTS)) ARTIFACT_PROJECTS := 03app_dotbot - TESTBED_APPS := $(filter-out bootloader partition0 partition1,$(TESTBED_APPS)) endif # remove incompatible apps (nrf5340, dotbot, gateway) for sailbot-v1 build ifeq (sailbot-v1,$(BUILD_TARGET)) PROJECTS := $(filter-out 01bsp_qdec 01drv_lis3mdl 01drv_move 03app_dotbot_gateway 03app_dotbot_gateway_lr 03app_dotbot 03app_nrf5340_%,$(PROJECTS)) ARTIFACT_PROJECTS := 03app_sailbot - TESTBED_APPS := $(filter-out bootloader partition0 partition1,$(TESTBED_APPS)) endif # remove incompatible apps (nrf5340) for nrf52833dk/nrf52840dk build @@ -107,7 +108,7 @@ ARTIFACTS = $(ARTIFACT_ELF) $(ARTIFACT_HEX) .PHONY: $(PROJECTS) $(ARTIFACT_PROJECTS) artifacts docker docker-release format check-format -all: $(PROJECTS) $(TESTBED_APPS) +all: $(PROJECTS) $(TESTBED_APPS) $(BOOTLOADER) $(PROJECTS): @echo "\e[1mBuilding project $@\e[0m" @@ -116,7 +117,12 @@ $(PROJECTS): $(TESTBED_APPS): @echo "\e[1mBuilding testbed application $@\e[0m" - "$(SEGGER_DIR)/bin/emBuild" $(PROJECT_FILE) -project $@ -config Release $(PACKAGES_DIR_OPT) -rebuild -verbose + "$(SEGGER_DIR)/bin/emBuild" $(PROJECT_FILE) -project $@ -config $(BUILD_CONFIG) $(PACKAGES_DIR_OPT) -rebuild -verbose + @echo "\e[1mDone\e[0m\n" + +$(BOOTLOADER): + @echo "\e[1mBuilding bootloader application $@\e[0m" + "$(SEGGER_DIR)/bin/emBuild" testbed/$(BUILD_TARGET)-bootloader.emProject -project $@ -config Release $(PACKAGES_DIR_OPT) -rebuild -verbose @echo "\e[1mDone\e[0m\n" list-projects: diff --git a/dotbot-v1.emProject b/dotbot-v1.emProject index f212614f1..772820f20 100644 --- a/dotbot-v1.emProject +++ b/dotbot-v1.emProject @@ -26,7 +26,7 @@ build_output_file_name="$(OutDir)/$(ProjectName)-$(BuildTarget)$(EXE)" build_treat_warnings_as_errors="Yes" c_additional_options="-Wno-missing-field-initializers" - c_preprocessor_definitions="ARM_MATH_CM4;NRF52833_XXAA;__nRF_FAMILY;CONFIG_NFCT_PINS_AS_GPIOS;FLASH_PLACEMENT=1;BOARD_DOTBOT_V1" + c_preprocessor_definitions="ARM_MATH_CM4;NRF52833_XXAA;__nRF_FAMILY;CONFIG_NFCT_PINS_AS_GPIOS;FLASH_PLACEMENT=1;BOARD_DOTBOT_V1;OTA_USE_CRYPTO" c_user_include_directories="$(SolutionDir)/../bsp;$(SolutionDir)/../crypto;$(SolutionDir)/../drv;$(PackagesDir)/nRF/Device/Include;$(PackagesDir)/CMSIS_5/CMSIS/Core/Include" debug_register_definition_file="$(PackagesDir)/nRF/XML/nrf52833_Registers.xml" debug_stack_pointer_start="__stack_end__" @@ -61,4 +61,5 @@ + diff --git a/dotbot-v2.emProject b/dotbot-v2.emProject index 0a1a7cad9..a514480a2 100644 --- a/dotbot-v2.emProject +++ b/dotbot-v2.emProject @@ -23,7 +23,7 @@ build_output_file_name="$(OutDir)/$(ProjectName)-$(BuildTarget)$(EXE)" build_treat_warnings_as_errors="Yes" c_additional_options="-Wno-strict-prototypes" - c_preprocessor_definitions="ARM_MATH_ARMV8MML;NRF5340_XXAA;NRF_APPLICATION;__NRF_FAMILY;CONFIG_NFCT_PINS_AS_GPIOS;FLASH_PLACEMENT=1;BOARD_DOTBOT_V2" + c_preprocessor_definitions="ARM_MATH_ARMV8MML;NRF5340_XXAA;NRF_APPLICATION;__NRF_FAMILY;CONFIG_NFCT_PINS_AS_GPIOS;FLASH_PLACEMENT=1;BOARD_DOTBOT_V2;OTA_USE_CRYPTO" c_user_include_directories="$(SolutionDir)/../bsp;$(SolutionDir)/../crypto;$(SolutionDir)/../drv;$(PackagesDir)/nRF/Device/Include;$(PackagesDir)/CMSIS_5/CMSIS/Core/Include" debug_register_definition_file="$(PackagesDir)/nRF/XML/nrf5340_application_Registers.xml" debug_stack_pointer_start="__stack_end__" @@ -62,4 +62,5 @@ + diff --git a/nrf52833dk.emProject b/nrf52833dk.emProject index 885268122..9b12f87aa 100644 --- a/nrf52833dk.emProject +++ b/nrf52833dk.emProject @@ -26,7 +26,7 @@ build_output_file_name="$(OutDir)/$(ProjectName)-$(BuildTarget)$(EXE)" build_treat_warnings_as_errors="Yes" c_additional_options="-Wno-missing-field-initializers" - c_preprocessor_definitions="ARM_MATH_CM4;NRF52833_XXAA;__nRF_FAMILY;CONFIG_NFCT_PINS_AS_GPIOS;FLASH_PLACEMENT=1;BOARD_NRF52833DK" + c_preprocessor_definitions="ARM_MATH_CM4;NRF52833_XXAA;__nRF_FAMILY;CONFIG_NFCT_PINS_AS_GPIOS;FLASH_PLACEMENT=1;BOARD_NRF52833DK;OTA_USE_CRYPTO" c_user_include_directories="$(SolutionDir)/../bsp;$(SolutionDir)/../crypto;$(SolutionDir)/../drv;$(PackagesDir)/nRF/Device/Include;$(PackagesDir)/CMSIS_5/CMSIS/Core/Include" debug_register_definition_file="$(PackagesDir)/nRF/XML/nrf52833_Registers.xml" debug_stack_pointer_start="__stack_end__" diff --git a/nrf52840dk.emProject b/nrf52840dk.emProject index b58a6ceb5..015c219dc 100644 --- a/nrf52840dk.emProject +++ b/nrf52840dk.emProject @@ -26,7 +26,7 @@ build_output_file_name="$(OutDir)/$(ProjectName)-$(BuildTarget)$(EXE)" build_treat_warnings_as_errors="Yes" c_additional_options="-Wno-missing-field-initializers" - c_preprocessor_definitions="ARM_MATH_CM4;NRF52840_XXAA;__nRF_FAMILY;CONFIG_NFCT_PINS_AS_GPIOS;FLASH_PLACEMENT=1;BOARD_NRF52840DK;USE_CRYPTOCELL" + c_preprocessor_definitions="ARM_MATH_CM4;NRF52840_XXAA;__nRF_FAMILY;CONFIG_NFCT_PINS_AS_GPIOS;FLASH_PLACEMENT=1;BOARD_NRF52840DK;OTA_USE_CRYPTO;USE_CRYPTOCELL" c_user_include_directories="$(SolutionDir)/../bsp;$(SolutionDir)/../crypto;$(SolutionDir)/../drv;$(PackagesDir)/nRF/Device/Include;$(PackagesDir)/CMSIS_5/CMSIS/Core/Include" debug_register_definition_file="$(PackagesDir)/nRF/XML/nrf52840_Registers.xml" debug_stack_pointer_start="__stack_end__" diff --git a/nrf5340dk-app.emProject b/nrf5340dk-app.emProject index d532b0040..1602fce28 100644 --- a/nrf5340dk-app.emProject +++ b/nrf5340dk-app.emProject @@ -23,7 +23,7 @@ build_output_file_name="$(OutDir)/$(ProjectName)-$(BuildTarget)$(EXE)" build_treat_warnings_as_errors="Yes" c_additional_options="-Wno-strict-prototypes" - c_preprocessor_definitions="ARM_MATH_ARMV8MML;NRF5340_XXAA;NRF_APPLICATION;__NRF_FAMILY;CONFIG_NFCT_PINS_AS_GPIOS;FLASH_PLACEMENT=1;BOARD_NRF5340DK" + c_preprocessor_definitions="ARM_MATH_ARMV8MML;NRF5340_XXAA;NRF_APPLICATION;__NRF_FAMILY;CONFIG_NFCT_PINS_AS_GPIOS;FLASH_PLACEMENT=1;BOARD_NRF5340DK;OTA_USE_CRYPTO" c_user_include_directories="$(SolutionDir)/../bsp;$(SolutionDir)/../crypto;$(SolutionDir)/../drv;$(PackagesDir)/nRF/Device/Include;$(PackagesDir)/CMSIS_5/CMSIS/Core/Include" debug_register_definition_file="$(PackagesDir)/nRF/XML/nrf5340_application_Registers.xml" debug_stack_pointer_start="__stack_end__" diff --git a/sailbot-v1.emProject b/sailbot-v1.emProject index eec2b7ed4..292971aa9 100644 --- a/sailbot-v1.emProject +++ b/sailbot-v1.emProject @@ -26,7 +26,7 @@ build_output_file_name="$(OutDir)/$(ProjectName)-$(BuildTarget)$(EXE)" build_treat_warnings_as_errors="Yes" c_additional_options="-Wno-missing-field-initializers" - c_preprocessor_definitions="ARM_MATH_CM4;NRF52833_XXAA;__nRF_FAMILY;CONFIG_NFCT_PINS_AS_GPIOS;FLASH_PLACEMENT=1;BOARD_SAILBOT_V1" + c_preprocessor_definitions="ARM_MATH_CM4;NRF52833_XXAA;__nRF_FAMILY;CONFIG_NFCT_PINS_AS_GPIOS;FLASH_PLACEMENT=1;BOARD_SAILBOT_V1;OTA_USE_CRYPTO" c_user_include_directories="$(SolutionDir)/../bsp;$(SolutionDir)/../crypto;$(SolutionDir)/../drv;$(PackagesDir)/nRF/Device/Include;$(PackagesDir)/CMSIS_5/CMSIS/Core/Include" debug_register_definition_file="$(PackagesDir)/nRF/XML/nrf52833_Registers.xml" debug_stack_pointer_start="__stack_end__" @@ -61,4 +61,5 @@ + From 60bfde3de02d4af2d33ea4a80dc40621d3ef8752 Mon Sep 17 00:00:00 2001 From: Alexandre Abadie Date: Mon, 12 Feb 2024 11:45:32 +0100 Subject: [PATCH 5/7] rename testbed in otap --- Makefile | 14 ++++++------- dist/scripts/{testbed => otap}/.gitignore | 0 .../scripts/{testbed => otap}/dotbot-flash.py | 0 .../{testbed => otap}/generate_keys.py | 0 .../{testbed => otap}/requirements.txt | 0 doc/doxygen/Doxyfile | 2 +- doc/sphinx/index.md | 2 +- doc/sphinx/{testbed.md => otap.md} | 2 +- dotbot-v1.emProject | 2 +- dotbot-v2.emProject | 2 +- nrf52833dk.emProject | 2 +- nrf52840dk.emProject | 2 +- nrf5340dk-app.emProject | 2 +- nrf5340dk-net.emProject | 2 +- {testbed => otap}/README.md | 21 ++++++++++--------- {testbed => otap}/bootloader.emProject | 0 {testbed => otap}/bootloader/main.c | 0 .../bootloader/nRF52833_xxAA_MemoryMap.xml | 0 .../bootloader/nRF52840_xxAA_MemoryMap.xml | 0 .../nRF5340_xxAA_Application_MemoryMap.xml | 0 .../nRF5340_xxAA_Network_MemoryMap.xml | 0 .../dotbot-v1-bootloader.emProject | 0 .../dotbot-v2-bootloader.emProject | 0 .../nrf52833dk-bootloader.emProject | 0 .../nrf52840dk-bootloader.emProject | 0 .../nrf5340dk-app-bootloader.emProject | 0 .../testbed.emProject => otap/otap.emProject | 2 +- {testbed => otap}/partition0/main.c | 0 .../partition0/nRF52833_xxAA_MemoryMap.xml | 0 .../partition0/nRF52840_xxAA_MemoryMap.xml | 0 .../nRF5340_xxAA_Application_MemoryMap.xml | 0 .../nRF5340_xxAA_Network_MemoryMap.xml | 0 {testbed => otap}/partition1/main.c | 0 .../partition1/nRF52833_xxAA_MemoryMap.xml | 0 .../partition1/nRF52840_xxAA_MemoryMap.xml | 0 .../nRF5340_xxAA_Application_MemoryMap.xml | 0 .../nRF5340_xxAA_Network_MemoryMap.xml | 0 .../sailbot-v1-bootloader.emProject | 0 sailbot-v1.emProject | 2 +- 39 files changed, 29 insertions(+), 28 deletions(-) rename dist/scripts/{testbed => otap}/.gitignore (100%) rename dist/scripts/{testbed => otap}/dotbot-flash.py (100%) rename dist/scripts/{testbed => otap}/generate_keys.py (100%) rename dist/scripts/{testbed => otap}/requirements.txt (100%) rename doc/sphinx/{testbed.md => otap.md} (53%) rename {testbed => otap}/README.md (88%) rename {testbed => otap}/bootloader.emProject (100%) rename {testbed => otap}/bootloader/main.c (100%) rename {testbed => otap}/bootloader/nRF52833_xxAA_MemoryMap.xml (100%) rename {testbed => otap}/bootloader/nRF52840_xxAA_MemoryMap.xml (100%) rename {testbed => otap}/bootloader/nRF5340_xxAA_Application_MemoryMap.xml (100%) rename {testbed => otap}/bootloader/nRF5340_xxAA_Network_MemoryMap.xml (100%) rename {testbed => otap}/dotbot-v1-bootloader.emProject (100%) rename {testbed => otap}/dotbot-v2-bootloader.emProject (100%) rename {testbed => otap}/nrf52833dk-bootloader.emProject (100%) rename {testbed => otap}/nrf52840dk-bootloader.emProject (100%) rename {testbed => otap}/nrf5340dk-app-bootloader.emProject (100%) rename testbed/testbed.emProject => otap/otap.emProject (98%) rename {testbed => otap}/partition0/main.c (100%) rename {testbed => otap}/partition0/nRF52833_xxAA_MemoryMap.xml (100%) rename {testbed => otap}/partition0/nRF52840_xxAA_MemoryMap.xml (100%) rename {testbed => otap}/partition0/nRF5340_xxAA_Application_MemoryMap.xml (100%) rename {testbed => otap}/partition0/nRF5340_xxAA_Network_MemoryMap.xml (100%) rename {testbed => otap}/partition1/main.c (100%) rename {testbed => otap}/partition1/nRF52833_xxAA_MemoryMap.xml (100%) rename {testbed => otap}/partition1/nRF52840_xxAA_MemoryMap.xml (100%) rename {testbed => otap}/partition1/nRF5340_xxAA_Application_MemoryMap.xml (100%) rename {testbed => otap}/partition1/nRF5340_xxAA_Network_MemoryMap.xml (100%) rename {testbed => otap}/sailbot-v1-bootloader.emProject (100%) diff --git a/Makefile b/Makefile index db8e6e703..d2f04889f 100644 --- a/Makefile +++ b/Makefile @@ -63,8 +63,8 @@ else PROJECTS ?= $(shell find projects/ -maxdepth 1 -mindepth 1 -type d | tr -d "/" | sed -e s/projects// | sort) endif -TESTBED_APPS ?= $(shell find testbed/ -maxdepth 1 -mindepth 1 -type d | tr -d "/" | sed -e s/testbed// | sort) -TESTBED_APPS := $(filter-out bootloader,$(TESTBED_APPS)) +OTAP_APPS ?= $(shell find otap/ -maxdepth 1 -mindepth 1 -type d | tr -d "/" | sed -e s/otap// | sort) +OTAP_APPS := $(filter-out bootloader,$(OTAP_APPS)) # remove incompatible apps (nrf5340, sailbot gateway) for dotbot (v1, v2) builds ifneq (,$(filter dotbot-v1,$(BUILD_TARGET))) @@ -97,7 +97,7 @@ ifneq (,$(filter nrf5340dk-net,$(BUILD_TARGET))) ARTIFACT_PROJECTS := 03app_nrf5340_net endif -SRCS ?= $(shell find bsp/ -name "*.[c|h]") $(shell find crypto/ -name "*.[c|h]") $(shell find drv/ -name "*.[c|h]") $(shell find projects/ -name "*.[c|h]") $(shell find testbed/ -name "*.[c|h]") +SRCS ?= $(shell find bsp/ -name "*.[c|h]") $(shell find crypto/ -name "*.[c|h]") $(shell find drv/ -name "*.[c|h]") $(shell find projects/ -name "*.[c|h]") $(shell find otap/ -name "*.[c|h]") CLANG_FORMAT ?= clang-format CLANG_FORMAT_TYPE ?= file @@ -108,21 +108,21 @@ ARTIFACTS = $(ARTIFACT_ELF) $(ARTIFACT_HEX) .PHONY: $(PROJECTS) $(ARTIFACT_PROJECTS) artifacts docker docker-release format check-format -all: $(PROJECTS) $(TESTBED_APPS) $(BOOTLOADER) +all: $(PROJECTS) $(OTAP_APPS) $(BOOTLOADER) $(PROJECTS): @echo "\e[1mBuilding project $@\e[0m" "$(SEGGER_DIR)/bin/emBuild" $(PROJECT_FILE) -project $@ -config $(BUILD_CONFIG) $(PACKAGES_DIR_OPT) -rebuild -verbose @echo "\e[1mDone\e[0m\n" -$(TESTBED_APPS): - @echo "\e[1mBuilding testbed application $@\e[0m" +$(OTAP_APPS): + @echo "\e[1mBuilding otap application $@\e[0m" "$(SEGGER_DIR)/bin/emBuild" $(PROJECT_FILE) -project $@ -config $(BUILD_CONFIG) $(PACKAGES_DIR_OPT) -rebuild -verbose @echo "\e[1mDone\e[0m\n" $(BOOTLOADER): @echo "\e[1mBuilding bootloader application $@\e[0m" - "$(SEGGER_DIR)/bin/emBuild" testbed/$(BUILD_TARGET)-bootloader.emProject -project $@ -config Release $(PACKAGES_DIR_OPT) -rebuild -verbose + "$(SEGGER_DIR)/bin/emBuild" otap/$(BUILD_TARGET)-bootloader.emProject -project $@ -config Release $(PACKAGES_DIR_OPT) -rebuild -verbose @echo "\e[1mDone\e[0m\n" list-projects: diff --git a/dist/scripts/testbed/.gitignore b/dist/scripts/otap/.gitignore similarity index 100% rename from dist/scripts/testbed/.gitignore rename to dist/scripts/otap/.gitignore diff --git a/dist/scripts/testbed/dotbot-flash.py b/dist/scripts/otap/dotbot-flash.py similarity index 100% rename from dist/scripts/testbed/dotbot-flash.py rename to dist/scripts/otap/dotbot-flash.py diff --git a/dist/scripts/testbed/generate_keys.py b/dist/scripts/otap/generate_keys.py similarity index 100% rename from dist/scripts/testbed/generate_keys.py rename to dist/scripts/otap/generate_keys.py diff --git a/dist/scripts/testbed/requirements.txt b/dist/scripts/otap/requirements.txt similarity index 100% rename from dist/scripts/testbed/requirements.txt rename to dist/scripts/otap/requirements.txt diff --git a/doc/doxygen/Doxyfile b/doc/doxygen/Doxyfile index a21d03e0d..fd1fbe883 100644 --- a/doc/doxygen/Doxyfile +++ b/doc/doxygen/Doxyfile @@ -126,8 +126,8 @@ INPUT = \ ../../bsp \ ../../crypto \ ../../drv \ + ../../otap \ ../../projects \ - ../../testbed \ # INPUT_ENCODING = UTF-8 FILE_PATTERNS = \ diff --git a/doc/sphinx/index.md b/doc/sphinx/index.md index 9c21018d2..2e5c51a48 100644 --- a/doc/sphinx/index.md +++ b/doc/sphinx/index.md @@ -4,7 +4,7 @@ getting_started applications examples -testbed +otap api ``` diff --git a/doc/sphinx/testbed.md b/doc/sphinx/otap.md similarity index 53% rename from doc/sphinx/testbed.md rename to doc/sphinx/otap.md index c94635ac5..f65979b73 100644 --- a/doc/sphinx/testbed.md +++ b/doc/sphinx/otap.md @@ -1,4 +1,4 @@ -```{include} ../../testbed/README.md +```{include} ../../otap/README.md :relative-images: :relative-docs: ../ ``` diff --git a/dotbot-v1.emProject b/dotbot-v1.emProject index 772820f20..94a3dd7e0 100644 --- a/dotbot-v1.emProject +++ b/dotbot-v1.emProject @@ -61,5 +61,5 @@ - + diff --git a/dotbot-v2.emProject b/dotbot-v2.emProject index a514480a2..2985fc63e 100644 --- a/dotbot-v2.emProject +++ b/dotbot-v2.emProject @@ -62,5 +62,5 @@ - + diff --git a/nrf52833dk.emProject b/nrf52833dk.emProject index 9b12f87aa..0a165f6fc 100644 --- a/nrf52833dk.emProject +++ b/nrf52833dk.emProject @@ -63,5 +63,5 @@ - + diff --git a/nrf52840dk.emProject b/nrf52840dk.emProject index 015c219dc..4f930c86a 100644 --- a/nrf52840dk.emProject +++ b/nrf52840dk.emProject @@ -63,5 +63,5 @@ - + diff --git a/nrf5340dk-app.emProject b/nrf5340dk-app.emProject index 1602fce28..a5ab636f6 100644 --- a/nrf5340dk-app.emProject +++ b/nrf5340dk-app.emProject @@ -64,5 +64,5 @@ - + diff --git a/nrf5340dk-net.emProject b/nrf5340dk-net.emProject index c2c4f3985..d02124546 100644 --- a/nrf5340dk-net.emProject +++ b/nrf5340dk-net.emProject @@ -59,5 +59,5 @@ - + diff --git a/testbed/README.md b/otap/README.md similarity index 88% rename from testbed/README.md rename to otap/README.md index 73a249f67..63a212457 100644 --- a/testbed/README.md +++ b/otap/README.md @@ -1,7 +1,8 @@ -# Testbed support +# OTAP support -This directory contains 3 applications that be used for the DotBot testbed support: -- **testbed/bootloader** contains a flexible bootloader application that +This directory contains 3 applications that be used for the DotBot over-the-air +programming support: +- **otap/bootloader** contains a flexible bootloader application that can be used to boot an image written at a given address on the flash memory. The bootloader application must be compiled in **Release** mode to make it as small as possible so that it stays under 4kiB. By default, the bootloader reads @@ -13,19 +14,19 @@ This directory contains 3 applications that be used for the DotBot testbed suppo tries to boot the image in partition 0 the next time, - pressing button 2 will set partition 1 as active and reset the device so it tries to boot the image in partition 1 the next time, - - using the [dotbot-flash.py](../dist/scripts/testbed/dotbot-flash.py) (see below) - provided in `dist/scripts/testbed`, a new firmware + - using the [dotbot-flash.py](../dist/scripts/otap/dotbot-flash.py) (see below) + provided in `dist/scripts/otap`, a new firmware image can be sent over UART to the active partition. Once completed the device has to be reset manually so it boots on the newly flashed image. -- **testbed/partition0** +- **otap/partition0** contains a sample application that is linked so that it can be written at address 0x2000, after the bootloader and partition tables pages. This application simply blinks an LED (LED1 on nRF DKs) and also contains the logic to download 128B chunks of an image and to write them on partition 1, -- **testbed/partition1** +- **otap/partition1** contains another sample application that is linked so that it can be written at address 0x41000 on nrf52833 or 0x81000 on nrf52840/nrf5340-app, after the image on partition 0. This application also @@ -60,7 +61,7 @@ The start address of partition 0 and partition 1 applications is defined in the match the start address of each partition defined in the bootloader `main.c`. -The [dotbot-flash.py](../dist/scripts/testbed/dotbot-flash.py) Python script is also provided: +The [dotbot-flash.py](../dist/scripts/otap/dotbot-flash.py) Python script is also provided: it reads a .bin firmware file and sends to a device over UART. The device can either be: - rebooted in bootloader mode (hold button 4 pressed during reset). @@ -71,7 +72,7 @@ be: application, which is just forwarding the bytes received from UART over radio. In this case, the firmware is split in 128B chunks and reconstructed on flash by an application running a code like in - **testbed/partition0**/**testbed/partition1** + **otap/partition0**/**otap/partition1** applications. Make sure that the firmware was built with the right offset on flash, following this rule: if the active image is on partition 0, the new firmware has to be built for partition 1 and vice versa. @@ -83,5 +84,5 @@ system. To install all the Python dependencies (pydotbot, click and tqdm), run: ``` -pip install -r dist/scripts/testbed/requirements.txt +pip install -r dist/scripts/otap/requirements.txt ``` diff --git a/testbed/bootloader.emProject b/otap/bootloader.emProject similarity index 100% rename from testbed/bootloader.emProject rename to otap/bootloader.emProject diff --git a/testbed/bootloader/main.c b/otap/bootloader/main.c similarity index 100% rename from testbed/bootloader/main.c rename to otap/bootloader/main.c diff --git a/testbed/bootloader/nRF52833_xxAA_MemoryMap.xml b/otap/bootloader/nRF52833_xxAA_MemoryMap.xml similarity index 100% rename from testbed/bootloader/nRF52833_xxAA_MemoryMap.xml rename to otap/bootloader/nRF52833_xxAA_MemoryMap.xml diff --git a/testbed/bootloader/nRF52840_xxAA_MemoryMap.xml b/otap/bootloader/nRF52840_xxAA_MemoryMap.xml similarity index 100% rename from testbed/bootloader/nRF52840_xxAA_MemoryMap.xml rename to otap/bootloader/nRF52840_xxAA_MemoryMap.xml diff --git a/testbed/bootloader/nRF5340_xxAA_Application_MemoryMap.xml b/otap/bootloader/nRF5340_xxAA_Application_MemoryMap.xml similarity index 100% rename from testbed/bootloader/nRF5340_xxAA_Application_MemoryMap.xml rename to otap/bootloader/nRF5340_xxAA_Application_MemoryMap.xml diff --git a/testbed/bootloader/nRF5340_xxAA_Network_MemoryMap.xml b/otap/bootloader/nRF5340_xxAA_Network_MemoryMap.xml similarity index 100% rename from testbed/bootloader/nRF5340_xxAA_Network_MemoryMap.xml rename to otap/bootloader/nRF5340_xxAA_Network_MemoryMap.xml diff --git a/testbed/dotbot-v1-bootloader.emProject b/otap/dotbot-v1-bootloader.emProject similarity index 100% rename from testbed/dotbot-v1-bootloader.emProject rename to otap/dotbot-v1-bootloader.emProject diff --git a/testbed/dotbot-v2-bootloader.emProject b/otap/dotbot-v2-bootloader.emProject similarity index 100% rename from testbed/dotbot-v2-bootloader.emProject rename to otap/dotbot-v2-bootloader.emProject diff --git a/testbed/nrf52833dk-bootloader.emProject b/otap/nrf52833dk-bootloader.emProject similarity index 100% rename from testbed/nrf52833dk-bootloader.emProject rename to otap/nrf52833dk-bootloader.emProject diff --git a/testbed/nrf52840dk-bootloader.emProject b/otap/nrf52840dk-bootloader.emProject similarity index 100% rename from testbed/nrf52840dk-bootloader.emProject rename to otap/nrf52840dk-bootloader.emProject diff --git a/testbed/nrf5340dk-app-bootloader.emProject b/otap/nrf5340dk-app-bootloader.emProject similarity index 100% rename from testbed/nrf5340dk-app-bootloader.emProject rename to otap/nrf5340dk-app-bootloader.emProject diff --git a/testbed/testbed.emProject b/otap/otap.emProject similarity index 98% rename from testbed/testbed.emProject rename to otap/otap.emProject index 24f651e3e..697acf10d 100644 --- a/testbed/testbed.emProject +++ b/otap/otap.emProject @@ -1,5 +1,5 @@ - + - + From e948b499d2b59b69d62b3e5dd0f15f764230bd32 Mon Sep 17 00:00:00 2001 From: Alexandre Abadie Date: Tue, 13 Feb 2024 14:08:40 +0100 Subject: [PATCH 6/7] otap: cleanup in script and bootloader segger studio project --- dist/scripts/otap/dotbot-flash.py | 31 +++++++++++++++---------- otap/nrf5340dk-app-bootloader.emProject | 2 +- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/dist/scripts/otap/dotbot-flash.py b/dist/scripts/otap/dotbot-flash.py index cd990d37d..300d9ffe0 100755 --- a/dist/scripts/otap/dotbot-flash.py +++ b/dist/scripts/otap/dotbot-flash.py @@ -137,14 +137,17 @@ def on_byte_received(self, byte): self.device_info_received = True def fetch_device_info(self): - while self.device_info_received is False: - buffer = bytearray() - buffer += int(MessageType.OTA_MESSAGE_TYPE_INFO.value).to_bytes( - length=1, byteorder="little" - ) - self.serial.write(hdlc_encode(buffer)) - print("Fetching device info...") - time.sleep(0.2) + # while self.device_info_received is False: + buffer = bytearray() + buffer += int(MessageType.OTA_MESSAGE_TYPE_INFO.value).to_bytes( + length=1, byteorder="little" + ) + print("Fetching device info...") + self.serial.write(hdlc_encode(buffer)) + timeout = 0 # ms + while self.device_info_received is False and timeout < 100: + timeout += 1 + time.sleep(0.01) def send_start_update(self, secure): if secure is True: @@ -157,7 +160,7 @@ def send_start_update(self, secure): private_key_bytes = open(PRIVATE_KEY_PATH, "rb").read() private_key = Ed25519PrivateKey.from_private_bytes(private_key_bytes) attempts = 0 - while self.start_ack_received is False and attempts < 3: + while attempts < 3: buffer = bytearray() buffer += int(MessageType.OTA_MESSAGE_TYPE_START.value).to_bytes( length=1, byteorder="little" @@ -169,11 +172,15 @@ def send_start_update(self, secure): buffer += fw_hash signature = private_key.sign(bytes(buffer[1:])) buffer += signature + print("Sending start update notification...") self.serial.write(hdlc_encode(buffer)) attempts += 1 - print("Sending start update notification...") - delay = 3 if secure and self.device_info.cpu != "nrf52840" else 0.2 - time.sleep(delay) + timeout = 0 # ms + while self.start_ack_received is False and timeout < 1000: + timeout += 1 + time.sleep(0.01) + if self.start_ack_received is True: + break return attempts < 3 def flash(self): diff --git a/otap/nrf5340dk-app-bootloader.emProject b/otap/nrf5340dk-app-bootloader.emProject index 950f8497a..3d3deac5d 100644 --- a/otap/nrf5340dk-app-bootloader.emProject +++ b/otap/nrf5340dk-app-bootloader.emProject @@ -1,5 +1,5 @@ - + Date: Tue, 13 Feb 2024 14:26:43 +0100 Subject: [PATCH 7/7] /bin/bash: line 1: q: command not found --- otap/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/otap/README.md b/otap/README.md index 63a212457..c69fc58e9 100644 --- a/otap/README.md +++ b/otap/README.md @@ -1,7 +1,7 @@ -# OTAP support +# OTAP -This directory contains 3 applications that be used for the DotBot over-the-air -programming support: +This directory contains 3 applications that be used for over-the-air +programming (OTAP) of DotBots: - **otap/bootloader** contains a flexible bootloader application that can be used to boot an image written at a given address on the flash memory. The bootloader application must be compiled in **Release** mode to make it as