1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-17 04:52:59 +01:00

tests/riotboot_flashwrite: initial commit

This commit is contained in:
Kaspar Schleiser 2019-03-14 12:02:49 +01:00
parent a15f07b04b
commit 641a32bfeb
4 changed files with 245 additions and 0 deletions

View File

@ -0,0 +1,75 @@
DEVELHELP ?= 0
BOARD ?= samr21-xpro
include ../Makefile.tests_common
BOARD_INSUFFICIENT_MEMORY := arduino-duemilanove arduino-mega2560 arduino-uno \
chronos msb-430 msb-430h nucleo-f031k6 \
nucleo-f042k6 nucleo-l031k6 nucleo-f030r8 \
nucleo-f303k8 nucleo-l053r8 stm32f0discovery \
telosb waspmote-pro wsn430-v1_3b wsn430-v1_4 z1
# Include packages that pull up and auto-init the link layer.
# NOTE: 6LoWPAN will be included if IEEE802.15.4 devices are present
USEMODULE += gnrc_netdev_default
USEMODULE += auto_init_gnrc_netif
# Specify the mandatory networking modules for IPv6 and UDP
USEMODULE += gnrc_ipv6_default
USEMODULE += gnrc_ipv6_router_default
USEMODULE += gnrc_udp
USEMODULE += gnrc_sock_udp
# Additional networking modules that can be dropped if not needed
USEMODULE += gnrc_icmpv6_echo
USEMODULE += nanocoap_sock
# include this for printing IP addresses
USEMODULE += shell_commands
# Comment this out to enable code in RIOT that does safety checking
# which is not needed in a production environment but helps in the
# development process:
#DEVELHELP = 1
# Use different settings when compiling for one of the following (low-memory)
# boards
LOW_MEMORY_BOARDS := nucleo-f334r8
GNRC_NETIF_NUMOF := 2
# uncomment these to use ethos
#USEMODULE += ethos gnrc_uhcpc
#
## ethos baudrate can be configured from make command
#ETHOS_BAUDRATE ?= 115200
#CFLAGS += -DETHOS_BAUDRATE=$(ETHOS_BAUDRATE) -DUSE_ETHOS_FOR_STDIO
ifneq (,$(filter $(BOARD),$(LOW_MEMORY_BOARDS)))
$(info Using low-memory configuration for microcoap_server.)
## low-memory tuning values
# lower pktbuf buffer size
CFLAGS += -DGNRC_PKTBUF_SIZE=1000
USEMODULE += prng_minstd
endif
# include riotboot modules
USEMODULE += riotboot_flashwrite
FEATURES_REQUIRED += riotboot
# Change this to 0 show compiler invocation lines by default:
QUIET ?= 1
include $(RIOTBASE)/Makefile.include
# Set a custom channel if needed
ifneq (,$(filter cc110x,$(USEMODULE))) # radio is cc110x sub-GHz
DEFAULT_CHANNEL ?= 0
CFLAGS += -DCC110X_DEFAULT_CHANNEL=$(DEFAULT_CHANNEL)
else
ifneq (,$(filter at86rf212b,$(USEMODULE))) # radio is IEEE 802.15.4 sub-GHz
DEFAULT_CHANNEL ?= 5
CFLAGS += -DIEEE802154_DEFAULT_SUBGHZ_CHANNEL=$(DEFAULT_CHANNEL)
else # radio is IEEE 802.15.4 2.4 GHz
DEFAULT_CHANNEL ?= 26
CFLAGS += -DIEEE802154_DEFAULT_CHANNEL=$(DEFAULT_CHANNEL)
endif
endif

View File

@ -0,0 +1,28 @@
# Introduction
This test application allows to test the riotboot_flashwrite module over coap.
WARNING: never use this code for anything else. It allows updating the device
over network without *any* kind of authentication or other security!
Please see the README of examples/nanocoap_server for instructions on how to
set up a network for testing.
# How to test
First, compile and flash with riotboot enabled:
$ BOARD=<board> make riotboot/flash
Confirm it booted from slot 0 (it should print "Current slot=0"), then
recompile in order to get an image for the second slot with a newer version
number:
$ BOARD=<board> make riotboot
Then send via CoAP, for example, with libcoap's coap_client:
$ coap-client -m post coap://[<ip address of node>]/flashwrite \
-f bin/<board>/tests_riotboot_flashwrite-slot1.riot.bin -b 64
Then reboot the node manually, confirming that it booted from slot 1.

View File

@ -0,0 +1,81 @@
/*
* Copyright (C) 2019 Kaspar Schleiser <kaspar@schleiser.de>
*
* 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.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "net/nanocoap.h"
#include "riotboot/flashwrite.h"
static riotboot_flashwrite_t _writer;
ssize_t _flashwrite_handler(coap_pkt_t* pkt, uint8_t *buf, size_t len, void *context)
{
riotboot_flashwrite_t *writer = context;
uint32_t result = COAP_CODE_204;
coap_block1_t block1;
int blockwise = coap_get_block1(pkt, &block1);
printf("_flashwrite_handler(): received data: offset=%u len=%u blockwise=%i more=%i\n", \
(unsigned)block1.offset, pkt->payload_len, blockwise, block1.more);
uint8_t *payload_start = pkt->payload;
size_t payload_len = pkt->payload_len;
size_t offset;
if (block1.offset == 0) {
printf("_flashwrite_handler(): init len=%u\n", pkt->payload_len);
riotboot_flashwrite_init(writer, riotboot_slot_other());
}
/* skip first RIOTBOOT_FLASHWRITE_SKIPLEN bytes, but handle the case where
* payload_len is smaller than RIOTBOOT_FLASHWRITE_SKIPLEN
*/
if (block1.offset <= RIOTBOOT_FLASHWRITE_SKIPLEN) {
size_t skip = RIOTBOOT_FLASHWRITE_SKIPLEN - block1.offset;
skip = (payload_len > skip) ? skip : payload_len;
payload_start += skip;
payload_len -= skip;
offset = block1.offset + skip;
}
else {
offset = block1.offset;
}
if (offset == writer->offset) {
riotboot_flashwrite_putbytes(writer, payload_start, payload_len, block1.more);
}
else {
printf("_flashwrite_handler(): skipping invalid offset (data=%u, writer=%u)\n", (unsigned)offset, (unsigned)writer->offset);
}
if (block1.more == 1) {
result = COAP_CODE_CONTINUE;
}
if (!blockwise || !block1.more) {
puts("_flashwrite_handler(): finish");
riotboot_flashwrite_finish(writer);
}
ssize_t reply_len = coap_build_reply(pkt, result, buf, len, 0);
uint8_t *pkt_pos = (uint8_t*)pkt->hdr + reply_len;
pkt_pos += coap_put_block1_ok(pkt_pos, &block1, 0);
return pkt_pos - (uint8_t*)pkt->hdr;
}
/* must be sorted by path (ASCII order) */
const coap_resource_t coap_resources[] = {
COAP_WELL_KNOWN_CORE_DEFAULT_HANDLER,
{ "/flashwrite", COAP_POST, _flashwrite_handler, &_writer },
};
const unsigned coap_resources_numof = sizeof(coap_resources) / sizeof(coap_resources[0]);

View File

@ -0,0 +1,61 @@
/*
* Copyright (C) 2016 Kaspar Schleiser <kaspar@schleiser.de>
*
* 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_flashwrite test application
*
* @author Kaspar Schleiser <kaspar@schleiser.de>
* @}
*/
#include <stdio.h>
#include "net/nanocoap_sock.h"
#include "xtimer.h"
#include "riotboot/slot.h"
#define COAP_INBUF_SIZE (256U)
#define MAIN_QUEUE_SIZE (8)
static msg_t _main_msg_queue[MAIN_QUEUE_SIZE];
/* import "ifconfig" shell command, used for printing addresses */
extern int _gnrc_netif_config(int argc, char **argv);
int main(void)
{
puts("riotboot_flashwrite test application");
int current_slot = riotboot_slot_current();
printf("Current slot=%d\n", current_slot);
riotboot_slot_print_hdr(current_slot);
/* nanocoap_server uses gnrc sock which uses gnrc which needs a msg queue */
msg_init_queue(_main_msg_queue, MAIN_QUEUE_SIZE);
puts("");
puts("Waiting for address autoconfiguration...");
xtimer_sleep(3);
/* print network addresses */
puts("Configured network interfaces:");
_gnrc_netif_config(0, NULL);
/* initialize nanocoap server instance */
uint8_t buf[COAP_INBUF_SIZE];
sock_udp_ep_t local = { .port=COAP_PORT, .family=AF_INET6 };
nanocoap_server(&local, buf, sizeof(buf));
/* should be never reached */
return 0;
}