Skip to content

Commit 2ce2949

Browse files
authored
Merge pull request #43 from wolfSSL/uart-flash
External, emulated non-volatile memory over UART
2 parents ab629ba + fbf4f72 commit 2ce2949

13 files changed

Lines changed: 1030 additions & 2 deletions

File tree

Makefile

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,13 +118,24 @@ ifeq ($(SPI_FLASH),1)
118118
WOLFCRYPT_OBJS+=hal/spi/spi_drv_$(SPI_TARGET).o
119119
endif
120120

121+
ifeq ($(UART_FLASH),1)
122+
EXT_FLASH=1
123+
endif
124+
121125
ifeq ($(EXT_FLASH),1)
122126
CFLAGS+= -DEXT_FLASH=1 -DPART_UPDATE_EXT=1 -DPART_SWAP_EXT=1
123127
ifeq ($(NO_XIP),1)
124128
CFLAGS+=-DPART_BOOT_EXT=1
125129
endif
130+
ifeq ($(UART_FLASH),1)
131+
CFLAGS+=-DUART_FLASH=1
132+
OBJS+=src/uart_flash.o
133+
WOLFCRYPT_OBJS+=hal/uart/uart_drv_$(UART_TARGET).o
134+
endif
126135
endif
127136

137+
138+
128139
ifeq ($(ALLOW_DOWNGRADE),1)
129140
CFLAGS+= -DALLOW_DOWNGRADE
130141
endif
@@ -264,7 +275,7 @@ keys: $(PRIVATE_KEY)
264275

265276
clean:
266277
@find . -type f -name "*.o" | xargs rm -f
267-
@rm -f *.bin *.elf wolfboot.map *.bin *.hex config/target.ld
278+
@rm -f *.bin *.elf wolfboot.map *.bin *.hex config/target.ld .bootloader-partition-size
268279
@make -C test-app clean
269280

270281
distclean: clean

arch.mk

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ ARCH_FLASH_OFFSET=0x0
1515
# Default SPI driver name
1616
SPI_TARGET=$(TARGET)
1717

18+
# Default UART driver name
19+
UART_TARGET=$(TARGET)
1820

1921
## Hash settings
2022
ifeq ($(HASH),SHA256)
@@ -129,6 +131,7 @@ ifeq ($(TARGET),lpc)
129131
CFLAGS+=-I$(MCUXPRESSO_DRIVERS)/drivers -I$(MCUXPRESSO_DRIVERS) -DCPU_$(MCUXPRESSO_CPU) -I$(MCUXPRESSO_CMSIS)/Include -DDEBUG_CONSOLE_ASSERT_DISABLE=1
130132
OBJS+=$(MCUXPRESSO_DRIVERS)/drivers/fsl_clock.o $(MCUXPRESSO_DRIVERS)/drivers/fsl_flashiap.o $(MCUXPRESSO_DRIVERS)/drivers/fsl_power.o $(MCUXPRESSO_DRIVERS)/drivers/fsl_reset.o
131133
OBJS+=$(MCUXPRESSO_DRIVERS)/mcuxpresso/libpower_softabi.a $(MCUXPRESSO_DRIVERS)/drivers/fsl_common.o
134+
OBJS+=$(MCUXPRESSO_DRIVERS)/drivers/fsl_usart.o $(MCUXPRESSO_DRIVERS)/drivers/fsl_flexcomm.o
132135
endif
133136

134137

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
ARCH?=ARM
2+
TARGET?=stm32f4
3+
SIGN?=ECC256
4+
HASH?=SHA256
5+
MCUXPRESSO?=/home/dan/src/FRDM-K64F
6+
MCUXPRESSO_CPU?=MK64FN1M0VLL12
7+
MCUXPRESSO_DRIVERS?=/home/dan/src/FRDM-K64F/devices/MK64F12
8+
MCUXPRESSO_CMSIS?=/home/dan/src/FRDM-K64F/CMSIS
9+
FREEDOM_E_SDK?=/home/dan/src/freedom-e-sdk
10+
STM32CUBE?=/home/dan/STM32Cube/Repository/STM32Cube_FW_WB_V1.3.0
11+
DEBUG?=1
12+
VTOR?=1
13+
CORTEX_M0?=0
14+
NO_ASM?=0
15+
EXT_FLASH?=0
16+
SPI_FLASH?=0
17+
NO_XIP?=0
18+
UART_FLASH?=1
19+
ALLOW_DOWNGRADE?=0
20+
NVM_FLASH_WRITEONCE?=0
21+
WOLFBOOT_VERSION?=0
22+
V?=0
23+
SPMATH?=1
24+
RAM_CODE?=0
25+
DUALBANK_SWAP?=0
26+
IMAGE_HEADER_SIZE?=256
27+
PKA?=1
28+
WOLFTPM?=0
29+
WOLFBOOT_PARTITION_SIZE?=0x4000
30+
WOLFBOOT_SECTOR_SIZE?=0x4000
31+
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x8000
32+
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x00000
33+
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x4000
34+
WOLFBOOT_LOAD_ADDRESS?=0x200000
35+
WOLFBOOT_LOAD_DTS_ADDRESS?=0x400000

hal/uart/uart_drv_lpc.c

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/* uart_drv_lpc.c
2+
*
3+
* Driver for the back-end of the UART_FLASH module.
4+
*
5+
* Example implementation for LPC54xxx, using UART0.
6+
*
7+
* Copyright (C) 2020 wolfSSL Inc.
8+
*
9+
* This file is part of wolfBoot.
10+
*
11+
* wolfBoot is free software; you can redistribute it and/or modify
12+
* it under the terms of the GNU General Public License as published by
13+
* the Free Software Foundation; either version 2 of the License, or
14+
* (at your option) any later version.
15+
*
16+
* wolfBoot is distributed in the hope that it will be useful,
17+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19+
* GNU General Public License for more details.
20+
*
21+
* You should have received a copy of the GNU General Public License
22+
* along with this program; if not, write to the Free Software
23+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
24+
*/
25+
26+
#include "fsl_common.h"
27+
#include "fsl_iocon.h"
28+
#include "fsl_usart.h"
29+
#include "target.h"
30+
#include "wolfboot/wolfboot.h"
31+
#include "hal.h"
32+
33+
#define IOCON_PIO_DIGITAL_EN 0x0100u /*!<@brief Enables digital function */
34+
#define IOCON_PIO_FUNC1 0x01u /*!<@brief Selects pin function 1 */
35+
#define IOCON_PIO_INPFILT_OFF 0x0200u /*!<@brief Input filter disabled */
36+
#define IOCON_PIO_INV_DI 0x00u /*!<@brief Input function is not inverted */
37+
#define IOCON_PIO_MODE_INACT 0x00u /*!<@brief No addition pin function */
38+
#define IOCON_PIO_OPENDRAIN_DI 0x00u /*!<@brief Open drain is disabled */
39+
#define IOCON_PIO_SLEW_STANDARD 0x00u /*!<@brief Standard mode, output slew rate control is enabled */
40+
41+
static void uart_pin_init(void)
42+
{
43+
/* Enables the clock for the IOCON block. 0 = Disable; 1 = Enable.: 0x01u */
44+
CLOCK_EnableClock(kCLOCK_Iocon);
45+
46+
const uint32_t port0_pin29_config = (/* Pin is configured as FC0_RXD_SDA_MOSI */
47+
IOCON_PIO_FUNC1 |
48+
/* No addition pin function */
49+
IOCON_PIO_MODE_INACT |
50+
/* Input function is not inverted */
51+
IOCON_PIO_INV_DI |
52+
/* Enables digital function */
53+
IOCON_PIO_DIGITAL_EN |
54+
/* Input filter disabled */
55+
IOCON_PIO_INPFILT_OFF |
56+
/* Standard mode, output slew rate control is enabled */
57+
IOCON_PIO_SLEW_STANDARD |
58+
/* Open drain is disabled */
59+
IOCON_PIO_OPENDRAIN_DI);
60+
/* PORT0 PIN29 (coords: B13) is configured as FC0_RXD_SDA_MOSI */
61+
IOCON_PinMuxSet(IOCON, 0U, 29U, port0_pin29_config);
62+
63+
const uint32_t port0_pin30_config = (/* Pin is configured as FC0_TXD_SCL_MISO */
64+
IOCON_PIO_FUNC1 |
65+
/* No addition pin function */
66+
IOCON_PIO_MODE_INACT |
67+
/* Input function is not inverted */
68+
IOCON_PIO_INV_DI |
69+
/* Enables digital function */
70+
IOCON_PIO_DIGITAL_EN |
71+
/* Input filter disabled */
72+
IOCON_PIO_INPFILT_OFF |
73+
/* Standard mode, output slew rate control is enabled */
74+
IOCON_PIO_SLEW_STANDARD |
75+
/* Open drain is disabled */
76+
IOCON_PIO_OPENDRAIN_DI);
77+
/* PORT0 PIN30 (coords: A2) is configured as FC0_TXD_SCL_MISO */
78+
IOCON_PinMuxSet(IOCON, 0U, 30U, port0_pin30_config);
79+
}
80+
81+
int uart_tx(const uint8_t c)
82+
{
83+
while((USART_GetStatusFlags(USART0) & kUSART_TxFifoEmptyFlag) == 0)
84+
;
85+
USART_WriteByte(USART0, c);
86+
return 1;
87+
}
88+
89+
int uart_rx(uint8_t *c)
90+
{
91+
if ((USART_GetStatusFlags(USART0) & kUSART_RxFifoNotEmptyFlag) != 0) {
92+
*c = USART_ReadByte(USART0);
93+
return 1;
94+
}
95+
return 0;
96+
}
97+
98+
int uart_init(uint32_t bitrate, uint8_t data, char parity, uint8_t stop)
99+
{
100+
uint8_t ch;
101+
usart_config_t config;
102+
uart_pin_init();
103+
USART_GetDefaultConfig(&config);
104+
config.baudRate_Bps = bitrate;
105+
config.enableTx = true;
106+
config.enableRx = true;
107+
CLOCK_AttachClk(kFRO12M_to_FLEXCOMM0);
108+
USART_Init(USART0, &config, CLOCK_GetFlexCommClkFreq(0));
109+
110+
uart_send_current_version();
111+
return 0;
112+
}
113+

hal/uart/uart_drv_stm32f4.c

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
/* uart_drv_stm32.c
2+
*
3+
* Driver for the back-end of the UART_FLASH module.
4+
*
5+
* Example implementation for stm32F4, using UART3.
6+
*
7+
* Pinout: RX=PD9, TX=PD8
8+
*
9+
* Copyright (C) 2020 wolfSSL Inc.
10+
*
11+
* This file is part of wolfBoot.
12+
*
13+
* wolfBoot is free software; you can redistribute it and/or modify
14+
* it under the terms of the GNU General Public License as published by
15+
* the Free Software Foundation; either version 2 of the License, or
16+
* (at your option) any later version.
17+
*
18+
* wolfBoot is distributed in the hope that it will be useful,
19+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
20+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21+
* GNU General Public License for more details.
22+
*
23+
* You should have received a copy of the GNU General Public License
24+
* along with this program; if not, write to the Free Software
25+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
26+
*/
27+
28+
#include <stdint.h>
29+
30+
/* Driver hardcoded to work on UART3 (PD8/PD9) */
31+
#define UART3 (0x40004800)
32+
#define UART3_PIN_AF 7
33+
#define UART3_RX_PIN 9
34+
#define UART3_TX_PIN 8
35+
36+
#define UART3_SR (*(volatile uint32_t *)(UART3))
37+
#define UART3_DR (*(volatile uint32_t *)(UART3 + 0x04))
38+
#define UART3_BRR (*(volatile uint32_t *)(UART3 + 0x08))
39+
#define UART3_CR1 (*(volatile uint32_t *)(UART3 + 0x0c))
40+
#define UART3_CR2 (*(volatile uint32_t *)(UART3 + 0x10))
41+
42+
#define UART_CR1_UART_ENABLE (1 << 13)
43+
#define UART_CR1_SYMBOL_LEN (1 << 12)
44+
#define UART_CR1_PARITY_ENABLED (1 << 10)
45+
#define UART_CR1_PARITY_ODD (1 << 9)
46+
#define UART_CR1_TX_ENABLE (1 << 3)
47+
#define UART_CR1_RX_ENABLE (1 << 2)
48+
#define UART_CR2_STOPBITS (3 << 12)
49+
#define UART_SR_TX_EMPTY (1 << 7)
50+
#define UART_SR_RX_NOTEMPTY (1 << 5)
51+
52+
53+
#define CLOCK_SPEED (168000000)
54+
55+
#define APB1_CLOCK_ER (*(volatile uint32_t *)(0x40023840))
56+
#define UART3_APB1_CLOCK_ER_VAL (1 << 18)
57+
58+
#define AHB1_CLOCK_ER (*(volatile uint32_t *)(0x40023830))
59+
#define GPIOD_AHB1_CLOCK_ER (1 << 3)
60+
#define GPIOD_BASE 0x40020c00
61+
#define GPIOD_MODE (*(volatile uint32_t *)(GPIOD_BASE + 0x00))
62+
#define GPIOD_AFL (*(volatile uint32_t *)(GPIOD_BASE + 0x20))
63+
#define GPIOD_AFH (*(volatile uint32_t *)(GPIOD_BASE + 0x24))
64+
#define GPIO_MODE_AF (2)
65+
66+
static void uart_pins_setup(void)
67+
{
68+
uint32_t reg;
69+
AHB1_CLOCK_ER |= GPIOD_AHB1_CLOCK_ER;
70+
/* Set mode = AF */
71+
reg = GPIOD_MODE & ~ (0x03 << (UART3_RX_PIN * 2));
72+
GPIOD_MODE = reg | (2 << (UART3_RX_PIN * 2));
73+
reg = GPIOD_MODE & ~ (0x03 << (UART3_TX_PIN * 2));
74+
GPIOD_MODE = reg | (2 << (UART3_TX_PIN * 2));
75+
76+
/* Alternate function: use high pins (8 and 9) */
77+
reg = GPIOD_AFH & ~(0xf << ((UART3_TX_PIN - 8) * 4));
78+
GPIOD_AFH = reg | (UART3_PIN_AF << ((UART3_TX_PIN - 8) * 4));
79+
reg = GPIOD_AFH & ~(0xf << ((UART3_RX_PIN - 8) * 4));
80+
GPIOD_AFH = reg | (UART3_PIN_AF << ((UART3_RX_PIN - 8) * 4));
81+
}
82+
83+
int uart_tx(const uint8_t c)
84+
{
85+
uint32_t reg;
86+
do {
87+
reg = UART3_SR;
88+
} while ((reg & UART_SR_TX_EMPTY) == 0);
89+
UART3_DR = c;
90+
return 1;
91+
}
92+
93+
int uart_rx(uint8_t *c)
94+
{
95+
volatile uint32_t reg = UART3_SR;
96+
if ((reg & UART_SR_RX_NOTEMPTY) != 0) {
97+
reg = UART3_DR;
98+
*c = (uint8_t)(reg & 0xff);
99+
return 1;
100+
}
101+
return 0;
102+
}
103+
104+
int uart_init(uint32_t bitrate, uint8_t data, char parity, uint8_t stop)
105+
{
106+
uint32_t reg;
107+
/* Enable pins and configure for AF7 */
108+
uart_pins_setup();
109+
/* Turn on the device */
110+
APB1_CLOCK_ER |= UART3_APB1_CLOCK_ER_VAL;
111+
UART3_CR1 &= ~(UART_CR1_UART_ENABLE);
112+
113+
/* Configure for TX + RX */
114+
UART3_CR1 |= (UART_CR1_TX_ENABLE | UART_CR1_RX_ENABLE);
115+
116+
/* Configure clock */
117+
UART3_BRR = CLOCK_SPEED / bitrate;
118+
119+
/* Configure data bits */
120+
if (data == 8)
121+
UART3_CR1 &= ~UART_CR1_SYMBOL_LEN;
122+
else
123+
UART3_CR1 |= UART_CR1_SYMBOL_LEN;
124+
125+
/* Configure parity */
126+
switch (parity) {
127+
case 'O':
128+
UART3_CR1 |= UART_CR1_PARITY_ODD;
129+
/* fall through to enable parity */
130+
/* FALL THROUGH */
131+
case 'E':
132+
UART3_CR1 |= UART_CR1_PARITY_ENABLED;
133+
break;
134+
default:
135+
UART3_CR1 &= ~(UART_CR1_PARITY_ENABLED | UART_CR1_PARITY_ODD);
136+
}
137+
/* Set stop bits */
138+
reg = UART3_CR2 & ~UART_CR2_STOPBITS;
139+
if (stop > 1)
140+
UART3_CR2 = reg & (2 << 12);
141+
else
142+
UART3_CR2 = reg;
143+
144+
/* Turn on uart */
145+
UART3_CR1 |= UART_CR1_UART_ENABLE;
146+
return 0;
147+
}
148+

include/uart_flash.h

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/* uart_flash.h
2+
*
3+
* Generic implementation of the read/write/erase
4+
* functionalities, on top of the uart_drv_*.h HAL.
5+
*
6+
* Compile with UART_FLASH=1
7+
*
8+
* Use tools/ufserver on the host to provide a remote
9+
* emulated non-volatile image via UART.
10+
*
11+
*
12+
* Copyright (C) 2020 wolfSSL Inc.
13+
*
14+
* This file is part of wolfBoot.
15+
*
16+
* wolfBoot is free software; you can redistribute it and/or modify
17+
* it under the terms of the GNU General Public License as published by
18+
* the Free Software Foundation; either version 2 of the License, or
19+
* (at your option) any later version.
20+
*
21+
* wolfBoot is distributed in the hope that it will be useful,
22+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
23+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24+
* GNU General Public License for more details.
25+
*
26+
* You should have received a copy of the GNU General Public License
27+
* along with this program; if not, write to the Free Software
28+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
29+
*/
30+
31+
#ifndef UART_FLASH_DRI_H
32+
#define UART_FLASH_DRI_H
33+
#include <stdint.h>
34+
35+
#ifdef UART_FLASH
36+
#ifndef UART_FLASH_BITRATE
37+
#define UART_FLASH_BITRATE 460800
38+
#endif
39+
int uart_init(uint32_t bitrate, uint8_t data, char parity, uint8_t stop);
40+
void uart_send_current_version(void);
41+
#else
42+
#define uart_init(...) (-1)
43+
#define uart_send_current_version() do{}while(0)
44+
#endif /* UART_FLASH */
45+
46+
#endif /* !UART_FLASH_DRI_H */

0 commit comments

Comments
 (0)