From f1c57b21ec9a5977d5c0d964b8d78a73d6054af3 Mon Sep 17 00:00:00 2001 From: Francisco Acosta Date: Thu, 27 Sep 2018 02:00:36 +0200 Subject: [PATCH] tests: add riotboot bootloader test The tests overrides the target all to be tested by the CI. All the instructions how to use it are in README.md The test is successful if the image boots and displays information about the image and running slot. Co-authored-by: Federico Pellegrin --- tests/riotboot/Makefile | 34 ++++++++++++++ tests/riotboot/README.md | 18 ++++++++ tests/riotboot/main.c | 99 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 151 insertions(+) create mode 100644 tests/riotboot/Makefile create mode 100644 tests/riotboot/README.md create mode 100644 tests/riotboot/main.c diff --git a/tests/riotboot/Makefile b/tests/riotboot/Makefile new file mode 100644 index 0000000000..c4b90fa4e3 --- /dev/null +++ b/tests/riotboot/Makefile @@ -0,0 +1,34 @@ +# If no BOARD is found in the environment, use this default: +BOARD ?= samr21-xpro + +TEST_ON_CI_WHITELIST += all + +# Select the boards with riotboot feature +FEATURES_REQUIRED += riotboot + +# Include modules to test the bootloader +USEMODULE += riotboot_slot +USEMODULE += shell + +# Comment this out to disable code in RIOT that does safety checking +# which is not needed in a production environment but helps in the +# development process: +DEVELHELP ?= 1 + +# Change this to 0 show compiler invocation lines by default: +QUIET ?= 1 + +all: riotboot + +include ../Makefile.tests_common +include $(RIOTBASE)/Makefile.include + +# Make 'flash' and 'flash-only' work without specific command. +# This is currently hacky as there is no way of specifiying a FLASHFILE +all: riotboot/combined-slot0 +# openocd +ELFFILE = $(BINDIR_APP)-slot0-combined.bin +# edbg +HEXFILE = $(BINDIR_APP)-slot0-combined.bin +# murdock uses ':=' to get the flashfile variable so should also be overwritten +FLASHFILE = $(BINDIR_APP)-slot0-combined.bin diff --git a/tests/riotboot/README.md b/tests/riotboot/README.md new file mode 100644 index 0000000000..09ae0e25f9 --- /dev/null +++ b/tests/riotboot/README.md @@ -0,0 +1,18 @@ +RIOT bootloader test +==================== + +This is a basic example how to use RIOT bootloader in your embedded +application. + +This test should foremost give you an overview how to use riotboot: + + - `make all` build the test using the target riotboot, which generates + a binary file of the application with a header on top of it, used by + the bootloader to recognise a bootable image. + + - `make riotboot/flash` creates the binary files and flashes both + riotboot and the RIOT image with headers included. This should boot + as a normal application. + +In this test two modules `riot_hdr` and `slot_util` are used to showcase +the access to riotboot shared functions. diff --git a/tests/riotboot/main.c b/tests/riotboot/main.c new file mode 100644 index 0000000000..8064b41d2b --- /dev/null +++ b/tests/riotboot/main.c @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2018 Inria + * Federico Pellegrin + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup tests + * @{ + * + * @file + * @brief riotboot bootloader test + * + * @author Francisco Acosta + * @author Federico Pellegrin + * + * @} + */ + +#include +#include +#include + +#include "riotboot/slot.h" +#include "shell.h" + +static int cmd_print_slot_nr(int argc, char **argv) +{ + (void)argc; + (void)argv; + + printf("Current slot=%d\n", riotboot_slot_current()); + return 0; +} + +static int cmd_print_slot_hdr(int argc, char **argv) +{ + (void)argc; + (void)argv; + + int current_slot = riotboot_slot_current(); + riotboot_slot_print_hdr(current_slot); + return 0; +} + +static int cmd_print_slot_addr(int argc, char **argv) +{ + (void)argc; + + int reqslot=atoi(argv[1]); + printf("Slot %d address=0x%08" PRIx32 "\n", + reqslot, riotboot_slot_get_image_startaddr(reqslot)); + return 0; +} + +static int cmd_dumpaddrs(int argc, char **argv) +{ + (void)argc; + (void)argv; + + riotboot_slot_dump_addrs(); + return 0; +} + +static const shell_command_t shell_commands[] = { + { "curslotnr", "Print current slot number", cmd_print_slot_nr }, + { "curslothdr", "Print current slot header", cmd_print_slot_hdr }, + { "getslotaddr", "Print address of requested slot", cmd_print_slot_addr }, + { "dumpaddrs", "Prints all slot data in header", cmd_dumpaddrs }, + { NULL, NULL, NULL } +}; + +int main(void) +{ + int current_slot; + + puts("Hello riotboot!"); + + printf("You are running RIOT on a(n) %s board.\n", RIOT_BOARD); + printf("This board features a(n) %s MCU.\n", RIOT_MCU); + + /* print some information about the running image */ + current_slot = riotboot_slot_current(); + if (current_slot != -1) { + printf("riotboot_test: running from slot %d\n", current_slot); + riotboot_slot_print_hdr(current_slot); + } + else { + printf("[FAILED] You're not running riotboot\n"); + } + + /* run the shell */ + char line_buf[SHELL_DEFAULT_BUFSIZE]; + shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE); + return 0; +}