From 3a248f649acd16448c7f27fe7f17f6f0bb6696f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Ku=C5=BAnia?= Date: Wed, 2 Oct 2019 19:53:42 +0200 Subject: [PATCH] [nrf52840] add UART and BLE bootloader support (#4212) This commit introduces serial and BLE DFU bootloader support * Added new linker script for serial and BLE DFU bootloaders * Added new nRF52840 switches (BOOTLOADER_USB/UART/BLE) * Deprecated BOOTLOADER=1 switch --- examples/Makefile-nrf52840 | 15 +- .../platforms/nrf528xx/nrf52811/README.md | 8 +- .../platforms/nrf528xx/nrf52840/README.md | 16 +- .../nrf52840/nrf52840_bootloader_ble.ld | 168 ++++++++++++++++++ .../nrf52840/nrf52840_bootloader_uart.ld | 168 ++++++++++++++++++ ...otloader.ld => nrf52840_bootloader_usb.ld} | 2 +- 6 files changed, 369 insertions(+), 8 deletions(-) create mode 100644 examples/platforms/nrf528xx/nrf52840/nrf52840_bootloader_ble.ld create mode 100644 examples/platforms/nrf528xx/nrf52840/nrf52840_bootloader_uart.ld rename examples/platforms/nrf528xx/nrf52840/{nrf52840_bootloader.ld => nrf52840_bootloader_usb.ld} (99%) diff --git a/examples/Makefile-nrf52840 b/examples/Makefile-nrf52840 index 7a4fd7364..76b6d02a6 100644 --- a/examples/Makefile-nrf52840 +++ b/examples/Makefile-nrf52840 @@ -85,10 +85,23 @@ COMMONCFLAGS := \ include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/common-switches.mk ifeq ($(BOOTLOADER),1) -configure_OPTIONS += --with-custom-linker-file=$(AbsTopSourceDir)/examples/platforms/nrf528xx/nrf52840/nrf52840_bootloader.ld +$(info Warning: BOOTLOADER=1 switch is deprecated. Defaulting to BOOTLOADER=USB.) +override BOOTLOADER = USB +endif + +ifeq ($(BOOTLOADER),USB) +configure_OPTIONS += --with-custom-linker-file=$(AbsTopSourceDir)/examples/platforms/nrf528xx/nrf52840/nrf52840_bootloader_usb.ld COMMONCFLAGS += -DAPP_USBD_NRF_DFU_TRIGGER_ENABLED=1 endif +ifeq ($(BOOTLOADER),UART) +configure_OPTIONS += --with-custom-linker-file=$(AbsTopSourceDir)/examples/platforms/nrf528xx/nrf52840/nrf52840_bootloader_uart.ld +endif + +ifeq ($(BOOTLOADER),BLE) +configure_OPTIONS += --with-custom-linker-file=$(AbsTopSourceDir)/examples/platforms/nrf528xx/nrf52840/nrf52840_bootloader_ble.ld +endif + # # Select transport which CLI, NCP and RCP examples will use to communicate. # To disable all transports use the DISABLE_TRANSPORTS switch. This will disable diff --git a/examples/platforms/nrf528xx/nrf52811/README.md b/examples/platforms/nrf528xx/nrf52811/README.md index 046b9875b..efae22b2f 100644 --- a/examples/platforms/nrf528xx/nrf52811/README.md +++ b/examples/platforms/nrf528xx/nrf52811/README.md @@ -72,7 +72,7 @@ $ make -f examples/Makefile-nrf52811 ``` After a successful build, the `elf` files can be found in -`/output/nrf52811/bin`. +`/output/nrf52811/bin`. You can convert them to hex using `arm-none-eabi-objcopy`: ```bash $ arm-none-eabi-objcopy -O ihex ot-cli-mtd ot-cli-mtd.hex @@ -173,7 +173,7 @@ To test the example: ``` After a couple of seconds the node will become a Leader of the network. - + ```bash > state leader @@ -197,7 +197,7 @@ To test the example: ```shell screen /dev/ttyACM1 115200 ``` - + You are now connected with the CLI on the second board 8. Use the following commands to attach to the network on the second board: @@ -350,7 +350,7 @@ nRF52811 supports [OpenThread Diagnostics Module][DIAG], with some additional fe For more information, see [nRF Diag command reference][nRFDIAG]. [DIAG]: ./../../../src/core/diags/README.md -[nRFDIAG]: DIAG.md +[nRFDIAG]: ./../DIAG.md ## Radio driver documentation diff --git a/examples/platforms/nrf528xx/nrf52840/README.md b/examples/platforms/nrf528xx/nrf52840/README.md index 8b71dc00e..aec7acd22 100644 --- a/examples/platforms/nrf528xx/nrf52840/README.md +++ b/examples/platforms/nrf528xx/nrf52840/README.md @@ -65,6 +65,18 @@ Note that the USB CDC ACM serial transport is not supported with Engineering sam If you are using Windows 7 or earlier, you must load an additional USB CDC driver. The driver can be found in `third_party/NordicSemiconductor/libraries/usb/nordic_cdc_acm_example.inf`. +### Bootloader support + +The examples support the following bootloaders for performing a Device Firmware Upgrade (DFU): +* USB bootloader +* UART bootloader +* BLE bootloader + +The support for a particular bootloader can be enabled with the following switches: +* USB: `BOOTLOADER=USB` +* UART: `BOOTLOADER=UART` +* BLE: `BOOTLOADER=BLE` + ### nRF52840 dongle support (PCA10059) You can build the libraries with support for the USB bootloader with USB DFU trigger support in PCA10059. As this dongle uses the native USB support, you must enable it as well. @@ -72,7 +84,7 @@ You can build the libraries with support for the USB bootloader with USB DFU tri To build the libraries, run make with the following parameters: ``` -$ make -f examples/Makefile-nrf52840 USB=1 BOOTLOADER=1 +$ make -f examples/Makefile-nrf52840 USB=1 BOOTLOADER=USB ``` See [nRF52840 Dongle Programming][nrf52840-dongle-programming] for more details about how to use the USB bootloader. @@ -380,7 +392,7 @@ nRF52840 port extends [OpenThread Diagnostics Module][DIAG]. You can read about all the features [here][nRFDIAG]. [DIAG]: ./../../../src/core/diags/README.md -[nRFDIAG]: DIAG.md +[nRFDIAG]: ./../DIAG.md ## Radio driver documentation diff --git a/examples/platforms/nrf528xx/nrf52840/nrf52840_bootloader_ble.ld b/examples/platforms/nrf528xx/nrf52840/nrf52840_bootloader_ble.ld new file mode 100644 index 000000000..9c9c324ec --- /dev/null +++ b/examples/platforms/nrf528xx/nrf52840/nrf52840_bootloader_ble.ld @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2019, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * GCC linker script for nRF52840 with BLE bootloader. + */ + +SEARCH_DIR(.) +GROUP(-lgcc -lc -lnosys) + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00026000, LENGTH = 0xd2000 + RAM (rwx) : ORIGIN = 0x20000008, LENGTH = 0x3fff8 +} + +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") + +ENTRY(Reset_Handler) + +FLASH_PAGE_SIZE = 4096; +FLASH_DATA_PAGES_USED = 4; + +SECTIONS +{ + .text : + { + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __HeapBase = .; + __end__ = .; + PROVIDE(end = .); + KEEP(*(.heap*)) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + KEEP(*(.stack*)) + } > RAM + + __stop_ot_flash_data = (ORIGIN(FLASH) + LENGTH(FLASH)); + __start_ot_flash_data = (__stop_ot_flash_data - (FLASH_PAGE_SIZE * FLASH_DATA_PAGES_USED)); + + /* Assure that code does not overlap flash data area.*/ + ASSERT((__start_ot_flash_data >= __etext + SIZEOF(.data)), "Error: Code overlaps flash data area.") + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/examples/platforms/nrf528xx/nrf52840/nrf52840_bootloader_uart.ld b/examples/platforms/nrf528xx/nrf52840/nrf52840_bootloader_uart.ld new file mode 100644 index 000000000..8532a83f1 --- /dev/null +++ b/examples/platforms/nrf528xx/nrf52840/nrf52840_bootloader_uart.ld @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2019, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * GCC linker script for nRF52840 with UART bootloader. + */ + +SEARCH_DIR(.) +GROUP(-lgcc -lc -lnosys) + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00001000, LENGTH = 0xf7000 + RAM (rwx) : ORIGIN = 0x20000008, LENGTH = 0x3fff8 +} + +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") + +ENTRY(Reset_Handler) + +FLASH_PAGE_SIZE = 4096; +FLASH_DATA_PAGES_USED = 4; + +SECTIONS +{ + .text : + { + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __HeapBase = .; + __end__ = .; + PROVIDE(end = .); + KEEP(*(.heap*)) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + KEEP(*(.stack*)) + } > RAM + + __stop_ot_flash_data = (ORIGIN(FLASH) + LENGTH(FLASH)); + __start_ot_flash_data = (__stop_ot_flash_data - (FLASH_PAGE_SIZE * FLASH_DATA_PAGES_USED)); + + /* Assure that code does not overlap flash data area.*/ + ASSERT((__start_ot_flash_data >= __etext + SIZEOF(.data)), "Error: Code overlaps flash data area.") + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/examples/platforms/nrf528xx/nrf52840/nrf52840_bootloader.ld b/examples/platforms/nrf528xx/nrf52840/nrf52840_bootloader_usb.ld similarity index 99% rename from examples/platforms/nrf528xx/nrf52840/nrf52840_bootloader.ld rename to examples/platforms/nrf528xx/nrf52840/nrf52840_bootloader_usb.ld index 380a1a9c4..3348a4fce 100644 --- a/examples/platforms/nrf528xx/nrf52840/nrf52840_bootloader.ld +++ b/examples/platforms/nrf528xx/nrf52840/nrf52840_bootloader_usb.ld @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, The OpenThread Authors. + * Copyright (c) 2019, The OpenThread Authors. * All rights reserved. * * Redistribution and use in source and binary forms, with or without