First stab at OTA-update
Introduce new testing-app example. Add a new coap error code for blockwise transfer. Add include-file for bootloader callbacks (jumptable). Note that only the bootloader for osd-merkur-256 will support OTA-update, the -128 simply has not enough flash memory, so only in the -256 we have the bootloader functions in the jump-table of the bootloader and in the bootloader-if.h include-file.
This commit is contained in:
parent
1a57b55d8f
commit
c35be7c066
13 changed files with 455 additions and 4 deletions
|
@ -94,6 +94,7 @@ typedef enum {
|
|||
NOT_FOUND_4_04 = 132, /* NOT_FOUND */
|
||||
METHOD_NOT_ALLOWED_4_05 = 133, /* METHOD_NOT_ALLOWED */
|
||||
NOT_ACCEPTABLE_4_06 = 134, /* NOT_ACCEPTABLE */
|
||||
REQUEST_ENTITY_INCOMPLETE_4_08 = 136, /* REQUEST_ENTITY_INCOMPLETE */
|
||||
PRECONDITION_FAILED_4_12 = 140, /* BAD_REQUEST */
|
||||
REQUEST_ENTITY_TOO_LARGE_4_13 = 141, /* REQUEST_ENTITY_TOO_LARGE */
|
||||
UNSUPPORTED_MEDIA_TYPE_4_15 = 143, /* UNSUPPORTED_MEDIA_TYPE */
|
||||
|
|
|
@ -482,6 +482,7 @@ const struct rest_implementation coap_rest_implementation = {
|
|||
NOT_FOUND_4_04,
|
||||
METHOD_NOT_ALLOWED_4_05,
|
||||
NOT_ACCEPTABLE_4_06,
|
||||
REQUEST_ENTITY_INCOMPLETE_4_08,
|
||||
REQUEST_ENTITY_TOO_LARGE_4_13,
|
||||
UNSUPPORTED_MEDIA_TYPE_4_15,
|
||||
INTERNAL_SERVER_ERROR_5_00,
|
||||
|
|
|
@ -56,6 +56,7 @@ struct rest_implementation_status {
|
|||
const unsigned int NOT_FOUND; /* NOT_FOUND_4_04, NOT_FOUND_404 */
|
||||
const unsigned int METHOD_NOT_ALLOWED; /* METHOD_NOT_ALLOWED_4_05, METHOD_NOT_ALLOWED_405 */
|
||||
const unsigned int NOT_ACCEPTABLE; /* NOT_ACCEPTABLE_4_06, NOT_ACCEPTABLE_406 */
|
||||
const unsigned int REQUEST_ENTITY_INCOMPLETE; /* REQUEST_ENTITY_INCOMPLETE_4_08, REQUEST_ENTITY_INCOMPLETE_408 */
|
||||
const unsigned int REQUEST_ENTITY_TOO_LARGE; /* REQUEST_ENTITY_TOO_LARGE_4_13, REQUEST_ENTITY_TOO_LARGE_413 */
|
||||
const unsigned int UNSUPPORTED_MEDIA_TYPE; /* UNSUPPORTED_MEDIA_TYPE_4_15, UNSUPPORTED_MEDIA_TYPE_415 */
|
||||
|
||||
|
|
49
examples/osd/ota-update/Makefile
Normal file
49
examples/osd/ota-update/Makefile
Normal file
|
@ -0,0 +1,49 @@
|
|||
# Set this to the name of your sketch (without extension .pde)
|
||||
SKETCH=sketch
|
||||
EXE=ota
|
||||
|
||||
|
||||
all: $(EXE)
|
||||
|
||||
CONTIKI=../../..
|
||||
|
||||
# Contiki IPv6 configuration
|
||||
CONTIKI_WITH_IPV6 = 1
|
||||
|
||||
CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\"
|
||||
|
||||
PROJECT_SOURCEFILES += res_upload_image.c ${SKETCH}.cpp
|
||||
|
||||
# variable for Makefile.include
|
||||
ifneq ($(TARGET), minimal-net)
|
||||
CFLAGS += -DUIP_CONF_IPV6_RPL=1
|
||||
else
|
||||
# minimal-net does not support RPL under Linux and is mostly used to test CoAP only
|
||||
${info INFO: compiling without RPL}
|
||||
CFLAGS += -DUIP_CONF_IPV6_RPL=0
|
||||
CFLAGS += -DHARD_CODED_ADDRESS=\"fdfd::10\"
|
||||
${info INFO: compiling with large buffers}
|
||||
CFLAGS += -DUIP_CONF_BUFFER_SIZE=2048
|
||||
CFLAGS += -DREST_MAX_CHUNK_SIZE=1024
|
||||
CFLAGS += -DCOAP_MAX_HEADER_SIZE=640
|
||||
endif
|
||||
|
||||
# linker optimizations
|
||||
SMALL=1
|
||||
|
||||
# REST Engine shall use Erbium CoAP implementation
|
||||
APPS += er-coap
|
||||
APPS += rest-engine
|
||||
APPS += arduino #json-resource #time json arduino
|
||||
|
||||
include $(CONTIKI)/Makefile.include
|
||||
include $(CONTIKI)/apps/arduino/Makefile.include
|
||||
|
||||
avr-size: $(EXE).$(TARGET).sz
|
||||
|
||||
flash: $(EXE).$(TARGET).u # $(EXE).$(TARGET).eu
|
||||
|
||||
.PHONY: flash avr-size
|
||||
.PRECIOUS: $(EXE).$(TARGET).hex $(EXE).$(TARGET).eep
|
||||
|
||||
AVRDUDE_PORT=/dev/ttyUSB1
|
81
examples/osd/ota-update/README.rst
Normal file
81
examples/osd/ota-update/README.rst
Normal file
|
@ -0,0 +1,81 @@
|
|||
==========
|
||||
OTA Update
|
||||
==========
|
||||
|
||||
OTA stands for "Over the Air". OTA update is used to flash a new
|
||||
firmware to a device over the air. This document (some of) the
|
||||
requirements for OTA.
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
Position Independent Code
|
||||
=========================
|
||||
|
||||
The new contiki-osd-merkur-256 target should have enough memory for two
|
||||
independent application images. An application image should include the
|
||||
code for over-the-air update to ensure it can be upgraded in the field.
|
||||
|
||||
Upgrading an image means writing a new image into the other half of the
|
||||
flash memory (the part which does not run the current image). Since an
|
||||
image has internal addresses and is usually linked to fixed addresses we
|
||||
have two options:
|
||||
|
||||
- Find a way to generate position independent code for the Atmel
|
||||
microcontrollers so that an image can be used in the lower- or upper
|
||||
half of flash memory
|
||||
- Generate two images, one linked for the lower, one linked for the
|
||||
upper half of flash memory.
|
||||
|
||||
It seems the GCC Atmel compiler cannot generate position independent
|
||||
code. So we have to modify the first option to make it work: We can use
|
||||
some magic during loading of an image to link it to the correct half of
|
||||
flash-memory during loading. This can either mean full relocation of the
|
||||
image (the same job that is normally done before runtime by the linker)
|
||||
or offline-generation of a jump-table for all objects (functions) that
|
||||
are accessed and the bootloader then only relocates the addresses in the
|
||||
jump-table.
|
||||
|
||||
The first implementation will use two images (one for upper-, one for
|
||||
lower half).
|
||||
|
||||
Memory Layout
|
||||
=============
|
||||
|
||||
+--------------------------------------+
|
||||
| 3E000-3FFFF Bootloader |
|
||||
+--------------------------------------+
|
||||
| 3DE00-3DFFF Flash image directory |
|
||||
+--------------------------------------+
|
||||
| 3DC00-3DDFF IRQVec copy upper image |
|
||||
+--------------------------------------+
|
||||
| 1F100-3DBFF |
|
||||
| Upper Image (w/o first two pages) |
|
||||
| |
|
||||
| |
|
||||
+--------------------------------------+
|
||||
| 1EF00-1F0FF IRQVec upper image |
|
||||
+--------------------------------------+
|
||||
| 1ED00-1EEFF IRQVec copy lower image |
|
||||
+--------------------------------------+
|
||||
| 00200-1ECFF |
|
||||
| Lower Image (w/o first two pages) |
|
||||
| |
|
||||
| |
|
||||
+--------------------------------------+
|
||||
| 00000-001FF IRQVec running image |
|
||||
+--------------------------------------+
|
||||
|
||||
We have two identical images. Each image contains the IRQ vectors (and
|
||||
some code after the vector table) in the lower two pages. A copy of
|
||||
these two pages is kept in two pages after the image. The reason is that
|
||||
the IRQ vectors are fixed at address 00000 in this processor
|
||||
architecture. So for running an image we need to copy the irq-vectors to
|
||||
the fixed location (and therefore we keep a backup to be able to restore
|
||||
the original image at that location).
|
||||
Note that in the table above an image as generated by the compiler
|
||||
consists of the IRQ vectors in the first two pages (00000-001FF for the
|
||||
first and 1EF00-1F0FF for the second image) plus the rest of the code
|
||||
for that image.
|
||||
|
||||
|
2
examples/osd/ota-update/ota.c
Normal file
2
examples/osd/ota-update/ota.c
Normal file
|
@ -0,0 +1,2 @@
|
|||
#include <arduino-process.h>
|
||||
AUTOSTART_PROCESSES(&arduino_sketch);
|
101
examples/osd/ota-update/project-conf.h
Normal file
101
examples/osd/ota-update/project-conf.h
Normal file
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* Copyright (c) 2010, Swedish Institute of Computer Science.
|
||||
* 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 Institute 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 INSTITUTE 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 INSTITUTE 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.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PROJECT_RPL_WEB_CONF_H_
|
||||
#define PROJECT_RPL_WEB_CONF_H_
|
||||
|
||||
#define PLATFORM_HAS_LEDS 1
|
||||
//#define PLATFORM_HAS_BUTTON 1
|
||||
#define PLATFORM_HAS_BATTERY 1
|
||||
|
||||
#define SICSLOWPAN_CONF_FRAG 1
|
||||
|
||||
/* For Debug: Dont allow MCU sleeping between channel checks */
|
||||
#undef RDC_CONF_MCU_SLEEP
|
||||
#define RDC_CONF_MCU_SLEEP 0
|
||||
|
||||
/* Disabling RDC for demo purposes. Core updates often require more memory. */
|
||||
/* For projects, optimize memory and enable RDC again. */
|
||||
// #undef NETSTACK_CONF_RDC
|
||||
//#define NETSTACK_CONF_RDC nullrdc_driver
|
||||
|
||||
/* Increase rpl-border-router IP-buffer when using more than 64. */
|
||||
#undef REST_MAX_CHUNK_SIZE
|
||||
#define REST_MAX_CHUNK_SIZE 64
|
||||
|
||||
/* Estimate your header size, especially when using Proxy-Uri. */
|
||||
/*
|
||||
#undef COAP_MAX_HEADER_SIZE
|
||||
#define COAP_MAX_HEADER_SIZE 70
|
||||
*/
|
||||
|
||||
/* The IP buffer size must fit all other hops, in particular the border router. */
|
||||
|
||||
#undef UIP_CONF_BUFFER_SIZE
|
||||
#define UIP_CONF_BUFFER_SIZE 256
|
||||
|
||||
|
||||
/* Multiplies with chunk size, be aware of memory constraints. */
|
||||
#undef COAP_MAX_OPEN_TRANSACTIONS
|
||||
#define COAP_MAX_OPEN_TRANSACTIONS 4
|
||||
|
||||
/* Must be <= open transaction number, default is COAP_MAX_OPEN_TRANSACTIONS-1. */
|
||||
/*
|
||||
#undef COAP_MAX_OBSERVERS
|
||||
#define COAP_MAX_OBSERVERS 2
|
||||
*/
|
||||
|
||||
/* Filtering .well-known/core per query can be disabled to save space. */
|
||||
/*
|
||||
#undef COAP_LINK_FORMAT_FILTERING
|
||||
#define COAP_LINK_FORMAT_FILTERING 0
|
||||
*/
|
||||
|
||||
/* Save some memory for the sky platform. */
|
||||
/*
|
||||
#undef NBR_TABLE_CONF_MAX_NEIGHBORS
|
||||
#define NBR_TABLE_CONF_MAX_NEIGHBORS 10
|
||||
#undef UIP_CONF_MAX_ROUTES
|
||||
#define UIP_CONF_MAX_ROUTES 10
|
||||
*/
|
||||
|
||||
/* Reduce 802.15.4 frame queue to save RAM. */
|
||||
/*
|
||||
#undef QUEUEBUF_CONF_NUM
|
||||
#define QUEUEBUF_CONF_NUM 4
|
||||
*/
|
||||
|
||||
/*
|
||||
#undef SICSLOWPAN_CONF_FRAG
|
||||
#define SICSLOWPAN_CONF_FRAG 1
|
||||
*/
|
||||
|
||||
#endif /* PROJECT_RPL_WEB_CONF_H_ */
|
175
examples/osd/ota-update/res_upload_image.c
Normal file
175
examples/osd/ota-update/res_upload_image.c
Normal file
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
* Copyright (c) 2017, Marcus Priesch, Ralf Schlatterbeck
|
||||
* with code from the res-plugtest-large-update.c by
|
||||
* Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich
|
||||
* 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 Institute 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 INSTITUTE 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 INSTITUTE 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.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Over-the-air update using blockwise transfer
|
||||
* \author
|
||||
* Marcus Priesch <marcus@priesch.co.at>
|
||||
* Ralf Schlatterbeck <rsc@runtux.com>
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "sys/cc.h"
|
||||
#include "rest-engine.h"
|
||||
#include "er-coap.h"
|
||||
#include "contiki.h"
|
||||
#include "contiki-net.h"
|
||||
#include "er-coap.h"
|
||||
#include "Arduino.h"
|
||||
#include <avr/interrupt.h>
|
||||
#include "bootloader_if.h"
|
||||
|
||||
#if 1
|
||||
#include <stdio.h>
|
||||
#define PRINTF(x) printf x
|
||||
#else
|
||||
#define PRINTF(x)
|
||||
#endif
|
||||
|
||||
static const uint32_t partition_start = 0x1ef00; //bootloader_get_part_start ();
|
||||
static const uint32_t partition_size = 5000; //bootloader_get_part_size ();
|
||||
|
||||
// We allocate this statically, otherwise we cannot flash a new image
|
||||
// when ram is exhausted!
|
||||
static uint8_t current_page [256];
|
||||
static size_t current_offset = 0;
|
||||
#define PAGESIZE (sizeof (current_page))
|
||||
|
||||
static void
|
||||
res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
coap_packet_t *const packet = (coap_packet_t *)request;
|
||||
uint8_t *in_data = NULL;
|
||||
size_t len = 0;
|
||||
uint8_t sreg = SREG;
|
||||
|
||||
unsigned int ct = -1;
|
||||
|
||||
REST.get_header_content_type(request, &ct);
|
||||
|
||||
/* Require content_type APPLICATION_OCTET_STREAM */
|
||||
if (ct != REST.type.APPLICATION_OCTET_STREAM) {
|
||||
REST.set_response_status(response, REST.status.BAD_REQUEST);
|
||||
const char *error_msg = "ContentType";
|
||||
REST.set_response_payload(response, error_msg, strlen(error_msg));
|
||||
return;
|
||||
}
|
||||
|
||||
len = REST.get_request_payload (request, (const uint8_t **)&in_data);
|
||||
PRINTF (("cur: %lu len: %lu, offset: %lu\n",
|
||||
(uint32_t)current_offset, (uint32_t)len, (uint32_t)*offset));
|
||||
PRINTF (("b1-offs: %lu, b1-size: %u, b1-num: %lu b1-more: %d b1-size1: %lu\n",
|
||||
packet->block1_offset, packet->block1_size, packet->block1_num,
|
||||
packet->block1_more, packet->size1));
|
||||
if (len == 0 || NULL == in_data) {
|
||||
REST.set_response_status(response, REST.status.BAD_REQUEST);
|
||||
const char *error_msg = "NoPayload";
|
||||
REST.set_response_payload(response, error_msg, strlen(error_msg));
|
||||
return;
|
||||
}
|
||||
|
||||
if (packet->block1_offset > current_offset) {
|
||||
REST.set_response_status(response, REST.status.REQUEST_ENTITY_INCOMPLETE);
|
||||
const char *error_msg = "OutOfSequence";
|
||||
REST.set_response_payload(response, error_msg, strlen(error_msg));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Old packet or retransmission, immediately confirm */
|
||||
if (packet->block1_offset + len <= current_offset) {
|
||||
REST.set_response_status(response, REST.status.CHANGED);
|
||||
coap_set_header_block1
|
||||
(response, packet->block1_num, 0, packet->block1_size);
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME: blocksize may be larger than our flash page size
|
||||
if (len > PAGESIZE) {
|
||||
REST.set_response_status(response, REST.status.INTERNAL_SERVER_ERROR);
|
||||
const char *error_msg = "GRMPF: PageSize";
|
||||
REST.set_response_payload(response, error_msg, strlen(error_msg));
|
||||
return;
|
||||
}
|
||||
// FIXME: blocksize may be larger than our flash page size
|
||||
// So we should handle this case and repeatedly flash a block until the
|
||||
// received data is written.
|
||||
if (current_offset % PAGESIZE + len > PAGESIZE) {
|
||||
REST.set_response_status(response, REST.status.INTERNAL_SERVER_ERROR);
|
||||
const char *error_msg = "GRMPF: blocksize";
|
||||
REST.set_response_payload(response, error_msg, strlen(error_msg));
|
||||
return;
|
||||
}
|
||||
// Should never happen, we test for < and > earlier.
|
||||
if (packet->block1_offset != current_offset) {
|
||||
REST.set_response_status(response, REST.status.INTERNAL_SERVER_ERROR);
|
||||
const char *error_msg = "GRMPF: Offset";
|
||||
REST.set_response_payload(response, error_msg, strlen(error_msg));
|
||||
return;
|
||||
}
|
||||
|
||||
if(packet->block1_offset + len > partition_size) {
|
||||
REST.set_response_status(response,
|
||||
REST.status.REQUEST_ENTITY_TOO_LARGE);
|
||||
REST.set_response_payload(
|
||||
response,
|
||||
buffer,
|
||||
sprintf((char *)buffer, "%luB max.", partition_size));
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy (current_page + current_offset % PAGESIZE, in_data, len);
|
||||
if (current_offset % PAGESIZE == 0 || !packet->block1_more) {
|
||||
// WRITE Flash here
|
||||
PRINTF (("Flashing: %lu\n", (uint32_t)len));
|
||||
sreg = SREG;
|
||||
cli ();
|
||||
bootloader_write_page_to_flash
|
||||
(partition_start + current_offset, len, current_page);
|
||||
SREG = sreg;
|
||||
}
|
||||
current_offset += len;
|
||||
|
||||
REST.set_response_status(response, REST.status.CHANGED);
|
||||
coap_set_header_block1(response, packet->block1_num, 0, packet->block1_size);
|
||||
}
|
||||
|
||||
RESOURCE(
|
||||
res_upload_image
|
||||
, "title=\"Flash memory upgrade\";rt=\"block\""
|
||||
, NULL
|
||||
, NULL
|
||||
, res_put_handler
|
||||
, NULL
|
||||
);
|
||||
|
28
examples/osd/ota-update/sketch.pde
Normal file
28
examples/osd/ota-update/sketch.pde
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Gardena 9V Magnet-Valve
|
||||
* We have a CoAP Resource for the Valve, it can be in state 1 (on) and
|
||||
* 0 (off).
|
||||
* Transition on-off outputs a negative pulse
|
||||
* Transition off-on outputs a positive pulse
|
||||
*/
|
||||
|
||||
extern "C" {
|
||||
#include <stdio.h>
|
||||
#include "contiki.h"
|
||||
#include "contiki-net.h"
|
||||
#include "er-coap.h"
|
||||
extern resource_t res_upload_image;
|
||||
char resname[] = "update";
|
||||
}
|
||||
|
||||
|
||||
void setup (void)
|
||||
{
|
||||
rest_init_engine ();
|
||||
rest_activate_resource (&res_upload_image, resname);
|
||||
}
|
||||
|
||||
void loop (void)
|
||||
{
|
||||
//printf ("Huhu\n");
|
||||
}
|
6
platform/osd-merkur-128/bootloader_if.h
Normal file
6
platform/osd-merkur-128/bootloader_if.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef BOOTLOADER_IF_H_
|
||||
#define BOOTLOADER_IF_H_
|
||||
|
||||
extern uint8_t bootloader_get_mac(uint8_t);
|
||||
|
||||
#endif /* BOOTLOADER_IF_H_ */
|
|
@ -39,6 +39,7 @@
|
|||
#endif
|
||||
|
||||
#include "contiki.h"
|
||||
#include "bootloader_if.h"
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/eeprom.h>
|
||||
#include <stdio.h>
|
||||
|
@ -85,8 +86,6 @@ const uint8_t default_domain_name[] PROGMEM = PARAMS_DOMAINNAME;
|
|||
#if PARAMETER_STORAGE==0
|
||||
/* 0 Hard coded, minmal program and eeprom usage. */
|
||||
|
||||
extern uint8_t bootloader_get_mac(uint8_t);
|
||||
|
||||
uint8_t
|
||||
params_get_eui64(uint8_t *eui64) {
|
||||
#if CONTIKI_CONF_RANDOM_MAC
|
||||
|
|
8
platform/osd-merkur-256/bootloader_if.h
Normal file
8
platform/osd-merkur-256/bootloader_if.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef BOOTLOADER_IF_H_
|
||||
#define BOOTLOADER_IF_H_
|
||||
|
||||
extern uint8_t bootloader_get_mac(uint8_t);
|
||||
extern int bootloader_write_page_to_flash
|
||||
(uint32_t address, unsigned int size, unsigned char *p);
|
||||
|
||||
#endif /* BOOTLOADER_IF_H_ */
|
|
@ -39,6 +39,7 @@
|
|||
#endif
|
||||
|
||||
#include "contiki.h"
|
||||
#include "bootloader_if.h"
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/eeprom.h>
|
||||
#include <stdio.h>
|
||||
|
@ -85,8 +86,6 @@ const uint8_t default_domain_name[] PROGMEM = PARAMS_DOMAINNAME;
|
|||
#if PARAMETER_STORAGE==0
|
||||
/* 0 Hard coded, minmal program and eeprom usage. */
|
||||
|
||||
extern uint8_t bootloader_get_mac(uint8_t);
|
||||
|
||||
uint8_t
|
||||
params_get_eui64(uint8_t *eui64) {
|
||||
#if CONTIKI_CONF_RANDOM_MAC
|
||||
|
|
Loading…
Reference in a new issue