Skip to content

Commit d46e8fd

Browse files
committed
STM32 test application: enable update-over-USART
1 parent 2193dcf commit d46e8fd

5 files changed

Lines changed: 294 additions & 61 deletions

File tree

test-app/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ OBJS:=startup.o main.o timer.o led.o system.o ../src/libwolfboot.o ../hal/$(TARG
55
TARGET?=none
66
LSCRIPT:=app.ld
77
OBJCOPY:=$(CROSS_COMPILE)objcopy
8-
CFLAGS:=-mcpu=cortex-m3 -mthumb -g -ggdb -Wall -Wno-main -Wstack-usage=200 -ffreestanding -Wno-unused -nostdlib -DPLATFORM_$(TARGET) -I../include
9-
LDFLAGS:=-T $(LSCRIPT) -Wl,-gc-sections -Wl,-Map=image.map -nostdlib
8+
CFLAGS:=-mcpu=cortex-m3 -mthumb -g -ggdb -Wall -Wno-main -Wstack-usage=200 -ffreestanding -Wno-unused -DPLATFORM_$(TARGET) -I../include -nostartfiles
9+
LDFLAGS:=$(CFLAGS) -T $(LSCRIPT) -Wl,-gc-sections -Wl,-Map=image.map
1010

1111
ifeq ($(EXT_FLASH),1)
1212
CFLAGS+=-DEXT_FLASH=1 -DPART_UPDATE_EXT=1

test-app/app.ld

Lines changed: 43 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,43 @@
1-
MEMORY
2-
{
3-
FLASH (rx) : ORIGIN = 0x00020100, LENGTH = 0x001FF00
4-
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00010000
5-
}
6-
7-
SECTIONS
8-
{
9-
.text :
10-
{
11-
_start_text = .;
12-
KEEP(*(.isr_vector))
13-
*(.text*)
14-
*(.rodata*)
15-
. = ALIGN(4);
16-
_end_text = .;
17-
} > FLASH
18-
19-
_stored_data = .;
20-
21-
.data : AT (_stored_data)
22-
{
23-
_start_data = .;
24-
KEEP(*(.data*))
25-
. = ALIGN(4);
26-
_end_data = .;
27-
} > RAM
28-
29-
.bss :
30-
{
31-
_start_bss = .;
32-
*(.bss*)
33-
*(COMMON)
34-
. = ALIGN(4);
35-
_end_bss = .;
36-
_end = .;
37-
} > RAM
38-
}
39-
40-
PROVIDE(_start_heap = _end);
41-
PROVIDE(_end_stack = ORIGIN(RAM) + LENGTH(RAM));
1+
MEMORY
2+
{
3+
FLASH (rx) : ORIGIN = 0x00020100, LENGTH = 0x001FF00
4+
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00010000
5+
}
6+
7+
SECTIONS
8+
{
9+
.text :
10+
{
11+
_start_text = .;
12+
KEEP(*(.isr_vector))
13+
*(.init)
14+
*(.fini)
15+
*(.text*)
16+
*(.rodata*)
17+
. = ALIGN(4);
18+
_end_text = .;
19+
} > FLASH
20+
21+
_stored_data = .;
22+
23+
.data : AT (_stored_data)
24+
{
25+
_start_data = .;
26+
KEEP(*(.data*))
27+
. = ALIGN(4);
28+
_end_data = .;
29+
} > RAM
30+
31+
.bss :
32+
{
33+
_start_bss = .;
34+
*(.bss*)
35+
*(COMMON)
36+
. = ALIGN(4);
37+
_end_bss = .;
38+
_end = .;
39+
} > RAM
40+
}
41+
42+
PROVIDE(_start_heap = _end);
43+
PROVIDE(_end_stack = ORIGIN(RAM) + LENGTH(RAM));

test-app/led.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
*/
2323

2424
#include <stdint.h>
25+
#include "wolfboot/wolfboot.h"
2526

2627
#define AHB1_CLOCK_ER (*(volatile uint32_t *)(0x40023830))
2728
#define GPIOD_AHB1_CLOCK_ER (1 << 3)
@@ -59,11 +60,12 @@ void led_pwm_setup(void)
5960
void boot_led_on(void)
6061
{
6162
uint32_t reg;
63+
uint32_t pin = LED_BOOT_PIN - 2 * (wolfBoot_current_firmware_version() & 0x01);
6264
AHB1_CLOCK_ER |= GPIOD_AHB1_CLOCK_ER;
63-
reg = GPIOD_MODE & ~(0x03 << (LED_BOOT_PIN * 2));
64-
GPIOD_MODE = reg | (1 << (LED_BOOT_PIN * 2));
65-
reg = GPIOD_PUPD & ~(0x03 << (LED_BOOT_PIN * 2));
66-
GPIOD_PUPD = reg | (1 << (LED_BOOT_PIN * 2));
67-
GPIOD_BSRR |= (1 << LED_BOOT_PIN);
65+
reg = GPIOD_MODE & ~(0x03 << (pin * 2));
66+
GPIOD_MODE = reg | (1 << (pin * 2));
67+
reg = GPIOD_PUPD & ~(0x03 << (pin * 2));
68+
GPIOD_PUPD = reg | (1 << (pin * 2));
69+
GPIOD_BSRR |= (1 << pin);
6870
}
6971

test-app/main.c

Lines changed: 234 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,40 +23,263 @@
2323

2424
#include <stdlib.h>
2525
#include <stdint.h>
26+
#include <string.h>
2627
#include "system.h"
2728
#include "timer.h"
2829
#include "led.h"
30+
#include "hal.h"
2931
#include "wolfboot/wolfboot.h"
3032

3133
#ifdef PLATFORM_stm32f4
3234

35+
extern int update_started;
36+
37+
#define UART3 (0x40004800)
38+
39+
#define UART3_SR (*(volatile uint32_t *)(UART3))
40+
#define UART3_DR (*(volatile uint32_t *)(UART3 + 0x04))
41+
#define UART3_BRR (*(volatile uint32_t *)(UART3 + 0x08))
42+
#define UART3_CR1 (*(volatile uint32_t *)(UART3 + 0x0c))
43+
#define UART3_CR2 (*(volatile uint32_t *)(UART3 + 0x10))
44+
45+
#define UART_CR1_UART_ENABLE (1 << 13)
46+
#define UART_CR1_SYMBOL_LEN (1 << 12)
47+
#define UART_CR1_PARITY_ENABLED (1 << 10)
48+
#define UART_CR1_PARITY_ODD (1 << 9)
49+
#define UART_CR1_TX_ENABLE (1 << 3)
50+
#define UART_CR1_RX_ENABLE (1 << 2)
51+
#define UART_CR2_STOPBITS (3 << 12)
52+
#define UART_SR_TX_EMPTY (1 << 7)
53+
#define UART_SR_RX_NOTEMPTY (1 << 5)
54+
55+
56+
#define CLOCK_SPEED (168000000)
57+
58+
#define APB1_CLOCK_ER (*(volatile uint32_t *)(0x40023840))
59+
#define UART3_APB1_CLOCK_ER_VAL (1 << 18)
60+
61+
#define AHB1_CLOCK_ER (*(volatile uint32_t *)(0x40023830))
62+
#define GPIOD_AHB1_CLOCK_ER (1 << 3)
63+
#define GPIOD_BASE 0x40020c00
64+
#define GPIOD_MODE (*(volatile uint32_t *)(GPIOD_BASE + 0x00))
65+
#define GPIOD_AFL (*(volatile uint32_t *)(GPIOD_BASE + 0x20))
66+
#define GPIOD_AFH (*(volatile uint32_t *)(GPIOD_BASE + 0x24))
67+
#define GPIO_MODE_AF (2)
68+
#define UART3_PIN_AF 7
69+
#define UART3_RX_PIN 9
70+
#define UART3_TX_PIN 8
71+
72+
#define MSGSIZE 16
73+
#define PAGESIZE (256)
74+
static uint8_t page[PAGESIZE];
75+
static const char ERR='!';
76+
static const char START='*';
77+
static const char UPDATE='U';
78+
static const char ACK='#';
79+
static uint8_t msg[MSGSIZE];
80+
81+
82+
void uart_write(const char c)
83+
{
84+
uint32_t reg;
85+
do {
86+
reg = UART3_SR;
87+
} while ((reg & UART_SR_TX_EMPTY) == 0);
88+
UART3_DR = c;
89+
}
90+
91+
static void uart_pins_setup(void)
92+
{
93+
uint32_t reg;
94+
AHB1_CLOCK_ER |= GPIOD_AHB1_CLOCK_ER;
95+
/* Set mode = AF */
96+
reg = GPIOD_MODE & ~ (0x03 << (UART3_RX_PIN * 2));
97+
GPIOD_MODE = reg | (2 << (UART3_RX_PIN * 2));
98+
reg = GPIOD_MODE & ~ (0x03 << (UART3_TX_PIN * 2));
99+
GPIOD_MODE = reg | (2 << (UART3_TX_PIN * 2));
100+
101+
/* Alternate function: use high pins (8 and 9) */
102+
reg = GPIOD_AFH & ~(0xf << ((UART3_TX_PIN - 8) * 4));
103+
GPIOD_AFH = reg | (UART3_PIN_AF << ((UART3_TX_PIN - 8) * 4));
104+
reg = GPIOD_AFH & ~(0xf << ((UART3_RX_PIN - 8) * 4));
105+
GPIOD_AFH = reg | (UART3_PIN_AF << ((UART3_RX_PIN - 8) * 4));
106+
}
107+
108+
int uart_setup(uint32_t bitrate, uint8_t data, char parity, uint8_t stop)
109+
{
110+
uint32_t reg;
111+
/* Enable pins and configure for AF7 */
112+
uart_pins_setup();
113+
/* Turn on the device */
114+
APB1_CLOCK_ER |= UART3_APB1_CLOCK_ER_VAL;
115+
116+
/* Configure for TX + RX */
117+
UART3_CR1 |= (UART_CR1_TX_ENABLE | UART_CR1_RX_ENABLE);
118+
119+
/* Configure clock */
120+
UART3_BRR = CLOCK_SPEED / bitrate;
121+
122+
/* Configure data bits */
123+
if (data == 8)
124+
UART3_CR1 &= ~UART_CR1_SYMBOL_LEN;
125+
else
126+
UART3_CR1 |= UART_CR1_SYMBOL_LEN;
127+
128+
/* Configure parity */
129+
switch (parity) {
130+
case 'O':
131+
UART3_CR1 |= UART_CR1_PARITY_ODD;
132+
/* fall through to enable parity */
133+
case 'E':
134+
UART3_CR1 |= UART_CR1_PARITY_ENABLED;
135+
break;
136+
default:
137+
UART3_CR1 &= ~(UART_CR1_PARITY_ENABLED | UART_CR1_PARITY_ODD);
138+
}
139+
/* Set stop bits */
140+
reg = UART3_CR2 & ~UART_CR2_STOPBITS;
141+
if (stop > 1)
142+
UART3_CR2 = reg & (2 << 12);
143+
else
144+
UART3_CR2 = reg;
145+
146+
/* Turn on uart */
147+
UART3_CR1 |= UART_CR1_UART_ENABLE;
148+
149+
return 0;
150+
}
151+
152+
char uart_read(void)
153+
{
154+
char c;
155+
volatile uint32_t reg;
156+
do {
157+
reg = UART3_SR;
158+
} while ((reg & UART_SR_RX_NOTEMPTY) == 0);
159+
c = (char)(UART3_DR & 0xff);
160+
return c;
161+
}
162+
163+
static void ack(uint32_t _off)
164+
{
165+
uint8_t *off = (uint8_t *)(&_off);
166+
int i;
167+
uart_write(ACK);
168+
for (i = 0; i < 4; i++) {
169+
uart_write(off[i]);
170+
}
171+
}
172+
173+
static int check(uint8_t *pkt, int size)
174+
{
175+
int i;
176+
uint16_t c = 0;
177+
uint16_t c_rx = *((uint16_t *)(pkt + 2));
178+
uint16_t *p = (uint16_t *)(pkt + 4);
179+
for (i = 0; i < ((size - 4) >> 1); i++)
180+
c += p[i];
181+
if (c == c_rx)
182+
return 0;
183+
return -1;
184+
}
185+
33186
void main(void) {
34-
uint32_t version;
187+
uint32_t tlen = 0;
188+
volatile uint32_t recv_seq;
189+
uint32_t r_total = 0;
190+
uint32_t tot_len = 0;
191+
uint32_t next_seq = 0;
192+
uint32_t version = 0;
193+
uint8_t *v_array = (uint8_t *)&version;
194+
int i;
195+
memset(page, 0xFF, PAGESIZE);
35196
boot_led_on();
36197
flash_set_waitstates();
37198
clock_config();
38199
led_pwm_setup();
39200
pwm_init(CPU_FREQ, 0);
40-
/* Dim the led by altering the PWM duty-cicle
201+
/* Dim the led by altering the PWM duty-cicle
41202
* in isr_tim2 (timer.c)
42203
*
43204
* Every 50ms, the duty cycle of the PWM connected
44205
* to the blue led increases/decreases making a pulse
45206
* effect.
46207
*/
47208
timer_init(CPU_FREQ, 1, 50);
48-
version = wolfBoot_current_firmware_version();
49-
if (version & 0x01) {
50-
/* Odd version: unstable, trigger update */
51-
if (wolfBoot_update_firmware_version() != 0)
209+
uart_setup(115200, 8, 'N', 1);
210+
memset(page, 0xFF, PAGESIZE);
211+
asm volatile ("cpsie i");
212+
/* Initiate update */
213+
214+
//wolfBoot_success();
215+
216+
hal_flash_unlock();
217+
uart_write(START);
218+
while (1) {
219+
r_total = 0;
220+
do {
221+
while(r_total < 2) {
222+
msg[r_total++] = uart_read();
223+
if ((r_total == 2) && ((msg[0] != 0xA5) || msg[1] != 0x5A)) {
224+
r_total = 0;
225+
continue;
226+
}
227+
}
228+
msg[r_total++] = uart_read();
229+
if ((tot_len == 0) && r_total == 2 + sizeof(uint32_t))
230+
break;
231+
if ((r_total > 8) && (tot_len <= ((r_total - 8) + next_seq)))
232+
break;
233+
} while (r_total < MSGSIZE);
234+
if (tot_len == 0) {
235+
tlen = msg[2] + (msg[3] << 8) + (msg[4] << 16) + (msg[5] << 24);
236+
if (tlen > WOLFBOOT_PARTITION_SIZE - 8) {
237+
uart_write(ERR);
238+
uart_write(ERR);
239+
uart_write(ERR);
240+
uart_write(ERR);
241+
uart_write(START);
242+
recv_seq = 0;
243+
tot_len = 0;
244+
update_started = 1;
245+
continue;
246+
}
247+
tot_len = tlen;
248+
ack(0);
249+
continue;
250+
}
251+
if (check(msg, r_total) < 0) {
252+
ack(next_seq);
253+
continue;
254+
}
255+
recv_seq = msg[4] + (msg[5] << 8) + (msg[6] << 16) + (msg[7] << 24);
256+
if (recv_seq == next_seq)
257+
{
258+
int psize = r_total - 8;
259+
int page_idx = recv_seq % PAGESIZE;
260+
memcpy(&page[recv_seq % PAGESIZE], msg + 8, psize);
261+
page_idx += psize;
262+
if ((page_idx == PAGESIZE) || (next_seq + psize >= tot_len)) {
263+
uint32_t dst = (WOLFBOOT_PARTITION_UPDATE_ADDRESS + recv_seq + psize) - page_idx;
264+
if ((dst % WOLFBOOT_SECTOR_SIZE) == 0) {
265+
hal_flash_erase(dst, WOLFBOOT_SECTOR_SIZE);
266+
}
267+
hal_flash_write(dst, page, PAGESIZE);
268+
memset(page, 0xFF, PAGESIZE);
269+
}
270+
next_seq += psize;
271+
}
272+
ack(next_seq);
273+
if (next_seq >= tot_len) {
274+
/* Update complete */
52275
wolfBoot_update_trigger();
53-
} else {
54-
/* Even version, stabilise */
55-
wolfBoot_success();
276+
hal_flash_lock();
277+
break;
278+
}
56279
}
57-
asm volatile ("cpsie i");
280+
/* Wait for reboot */
58281
while(1)
59-
WFI();
282+
;
60283
}
61284
#endif
62285

0 commit comments

Comments
 (0)