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:
parent
a15f07b04b
commit
641a32bfeb
75
tests/riotboot_flashwrite/Makefile
Normal file
75
tests/riotboot_flashwrite/Makefile
Normal 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
|
28
tests/riotboot_flashwrite/README.md
Normal file
28
tests/riotboot_flashwrite/README.md
Normal 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.
|
81
tests/riotboot_flashwrite/coap_handler.c
Normal file
81
tests/riotboot_flashwrite/coap_handler.c
Normal 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]);
|
61
tests/riotboot_flashwrite/main.c
Normal file
61
tests/riotboot_flashwrite/main.c
Normal 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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user