1
0
mirror of git://projects.qi-hardware.com/antorcha.git synced 2024-12-22 18:22:05 +02:00

RESET protocol to jump from application to boot loader without power cycling

This commit is contained in:
Werner Almesberger 2012-06-18 20:31:20 -03:00
parent 683056bca7
commit cc4b5607c7
8 changed files with 42 additions and 15 deletions

View File

@ -7,6 +7,8 @@ Protocol
1 0 0 Pong (maybe return version string in the future)
2 0 0 Reset (64 bytes reset secret)
4 0 N Unlock secret (64 bytes payload)
4 1..N-1 N Firmware binary (64 bytes payload)
4 N N First half of hash

View File

@ -30,7 +30,7 @@ OBJCOPY = $(AVR_PREFIX)objcopy
#OBJDUMP = $(AVR_PREFIX)objdump
SIZE = $(AVR_PREFIX)size
OBJS = $(NAME).o dispatch.o hash.o $(COMMON_OBJS)
OBJS = $(NAME).o dispatch.o hash.o reset.o $(COMMON_OBJS)
BOOT_OBJS = boot.o flash.o fw.o $(COMMON_OBJS)
COMMON_OBJS = rf.o spi.o
@ -87,7 +87,7 @@ clean:
rm -f version.c version.d version.o
nosecrets:
rm -f unlock-secret.inc image-secret.inc
rm -f unlock-secret.inc reset-secret.inc image-secret.inc
# ----- Build version ---------------------------------------------------------
@ -129,10 +129,14 @@ SECRET = { dd if=$(RANDOM) iflag=fullblock bs=$(1) count=1 status=noxfer | \
unlock-secret.inc:
$(BUILD) $(call SECRET,64) >$@ || { rm -f $@; exit 1; }
reset-secret.inc:
$(BUILD) $(call SECRET,64) >$@ || { rm -f $@; exit 1; }
image-secret.inc:
$(BUILD) $(call SECRET,128) >$@ || { rm -f $@; exit 1; }
fw.o: unlock-secret.inc
reset.o: unlock-secret.inc
# ----- Dependencies ----------------------------------------------------------

View File

@ -23,8 +23,8 @@
#include "dispatch.h"
static const struct handler *protos[] = {
&reset_handler,
NULL
};
@ -39,12 +39,6 @@ int main(void)
* It has also brought up RF and the underlying SPI.
*/
while (1) {
SET(LED_B8);
_delay_ms(100);
CLR(LED_B8);
_delay_ms(100);
}
while (1) {
got = rf_recv(buf, sizeof(buf));
if (got > 2)

View File

@ -57,9 +57,19 @@ int main(void)
PORTD = 0;
DDRD = 0xff;
/* disable pull-ups */
/* Disable pull-ups */
MCUCR |= 1 << PUD;
/*
* Disable the watchdog timer, in case the boot loader has been
* entered by a watchdog reset commanded by the application.
*/
MCUSR = 0; /* Remove override */
WDTCSR |= 1 << WDCE; /* Enable change */
WDTCSR = 1 << WDCE; /* Disable watchdog while still enabling
change */
rf_init();
/*

View File

@ -26,6 +26,8 @@ struct handler {
};
extern struct handler reset_handler;
bool dispatch(const uint8_t *buf, uint8_t len, const struct handler **protos);
#endif /* !PROTO_H */

View File

@ -15,6 +15,9 @@
#include <stdint.h>
#include <string.h>
#define F_CPU 8000000UL
#include <util/delay.h>
#include "io.h"
#include "flash.h"
#include "proto.h"
@ -54,8 +57,9 @@ bool fw_packet(const uint8_t *buf, uint8_t len)
static uint8_t limit;
uint8_t ack[] = { FIRMWARE+1, buf[1], buf[2] };
/* short (barely visible) flash to indicate reception */
/* short flash to indicate reception */
SET(LED_B7);
_delay_ms(1);
CLR(LED_B7);
/* Check packet for formal validity */

View File

@ -18,6 +18,7 @@
enum pck_type {
PING = 0, /* version query */
PONG = 1, /* version response */
RESET = 2, /* reset to boot loader */
FIRMWARE = 4, /* firmware upload */
FIRMWARE_ACK = 5, /* firmware upload acknowledgement */
IMAGE = 6, /* image upload */

View File

@ -49,6 +49,7 @@ static void rf_send(struct atrf_dsc *dsc, void *buf, int len)
/* Copy the message to append the CRC placeholders */
memcpy(tmp, buf, len);
atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_PLL_ON);
flush_interrupts(dsc);
atrf_buf_write(dsc, tmp, len+2);
atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_TX_START);
wait_for_interrupt(dsc, IRQ_TRX_END,
@ -98,17 +99,25 @@ static void ping(struct atrf_dsc *dsc)
}
static void packet(struct atrf_dsc *dsc,
static void packet_noack(struct atrf_dsc *dsc,
uint8_t type, uint8_t seq, uint8_t last, const void *payload, int len)
{
uint8_t tx_buf[PAYLOAD+3] = { type, seq, last };
uint8_t rx_buf[10];
int got;
assert(len == PAYLOAD);
memcpy(tx_buf+3, payload, len);
rf_send(dsc, tx_buf, sizeof(tx_buf));
}
static void packet(struct atrf_dsc *dsc,
uint8_t type, uint8_t seq, uint8_t last, const void *payload, int len)
{
uint8_t rx_buf[10];
int got;
while (1) {
rf_send(dsc, tx_buf, sizeof(tx_buf));
packet_noack(dsc, type, seq, last, payload, len);
if (verbose)
write(2, ">", 1);
got = rf_recv(dsc, rx_buf, sizeof(rx_buf));
@ -146,6 +155,7 @@ static void send_firmware(struct atrf_dsc *dsc, void *buf, int len)
write(2, "firmware ", 9);
last = (len+63)/64;
seq = 0;
packet_noack(dsc, RESET, 0, 0, unlock_secret, PAYLOAD);
packet(dsc, FIRMWARE, seq++, last, unlock_secret, PAYLOAD);
while (len >= PAYLOAD) {
packet(dsc, FIRMWARE, seq++, last, buf, PAYLOAD);