boot_serial; improve platform abstraction.
Pass function pointers to do reads/writes from uart.
Signed-off-by: Marko Kiiskila <marko@runtime.io>
diff --git a/boot/boot_serial/include/boot_serial/boot_serial.h b/boot/boot_serial/include/boot_serial/boot_serial.h
index b93c28f..3393213 100644
--- a/boot/boot_serial/include/boot_serial/boot_serial.h
+++ b/boot/boot_serial/include/boot_serial/boot_serial.h
@@ -24,12 +24,24 @@
extern "C" {
#endif
-/*
- * Start processing newtmgr commands for uploading image0 over serial.
- *
- * Open console serial port and wait for download command.
+/**
+ * Function pointers to read/write data from uart.
+ * read returns the number of bytes read, str points to buffer to fill,
+ * cnt is the number of bytes to fill within buffer, *newline will be
+ * set if newline is the last character.
+ * write takes as it's arguments pointer to data to write, and the count
+ * of bytes.
*/
-void boot_serial_start(int max_input);
+struct boot_uart_funcs {
+ int (*read)(char *str, int cnt, int *newline);
+ void (*write)(const char *ptr, int cnt);
+};
+
+/**
+ * Start processing newtmgr commands for uploading image0 over serial.
+ * Assumes serial port is open and waits for download command.
+ */
+void boot_serial_start(const struct boot_uart_funcs *f);
#ifdef __cplusplus
}
diff --git a/boot/boot_serial/pkg.yml b/boot/boot_serial/pkg.yml
index 69d90e1..f1431c7 100644
--- a/boot/boot_serial/pkg.yml
+++ b/boot/boot_serial/pkg.yml
@@ -29,7 +29,6 @@
- "@apache-mynewt-core/hw/hal"
- "@apache-mynewt-core/kernel/os"
- "@apache-mynewt-core/encoding/tinycbor"
- - "@apache-mynewt-core/encoding/cborattr"
- "@apache-mynewt-core/encoding/base64"
- "@mcuboot/boot/mynewt/flash_map_backend"
- "@mcuboot/boot/mynewt/boot_uart"
diff --git a/boot/boot_serial/src/CMakeLists.txt b/boot/boot_serial/src/CMakeLists.txt
index 7b0bf99..20feaa1 100644
--- a/boot/boot_serial/src/CMakeLists.txt
+++ b/boot/boot_serial/src/CMakeLists.txt
@@ -2,7 +2,4 @@
zephyr_include_directories(${BOOT_DIR}/bootutil/include)
-zephyr_include_directories($ENV{ZEPHYR_BASE}/ext/lib/mgmt/mcumgr/cborattr/include)
-zephyr_sources($ENV{ZEPHYR_BASE}/ext/lib/mgmt/mcumgr/cborattr/src/cborattr.c)
-
zephyr_link_libraries_ifdef(CONFIG_TINYCBOR TINYCBOR)
diff --git a/boot/boot_serial/src/boot_serial.c b/boot/boot_serial/src/boot_serial.c
index e67e68d..9b63043 100644
--- a/boot/boot_serial/src/boot_serial.c
+++ b/boot/boot_serial/src/boot_serial.c
@@ -32,7 +32,6 @@
#include <misc/__assert.h>
#include <flash.h>
#include <crc16.h>
-#include <serial_adapter/serial_adapter.h>
#include <base64.h>
#include <cbor.h>
#else
@@ -40,18 +39,12 @@
#include <hal/hal_system.h>
#include <os/endian.h>
#include <os/os_cputime.h>
-#include <boot_uart/boot_uart.h>
#include <crc/crc16.h>
#include <base64/base64.h>
#include <tinycbor/cbor.h>
#include <tinycbor/cbor_buf_reader.h>
-
-#define console_write boot_uart_write
-#define console_read boot_uart_read
-
#endif /* __ZEPHYR__ */
-#include <cborattr/cborattr.h>
#include <flash_map_backend/flash_map_backend.h>
#include <hal/hal_flash.h>
#include <os/os.h>
@@ -62,6 +55,7 @@
#include "boot_serial/boot_serial.h"
#include "boot_serial_priv.h"
+#define BOOT_SERIAL_INPUT_MAX 512
#define BOOT_SERIAL_OUT_MAX 80
#ifdef __ZEPHYR__
@@ -74,10 +68,10 @@
#define ntohs(x) sys_be16_to_cpu(x)
#define htons(x) sys_cpu_to_be16(x)
-static char in_buf[CONFIG_BOOT_MAX_LINE_INPUT_LEN + 1];
-static char dec_buf[CONFIG_BOOT_MAX_LINE_INPUT_LEN + 1];
#endif
-
+static char in_buf[BOOT_SERIAL_INPUT_MAX + 1];
+static char dec_buf[BOOT_SERIAL_INPUT_MAX + 1];
+static const struct boot_uart_funcs *boot_uf;
static uint32_t curr_off;
static uint32_t img_size;
static struct nmgr_hdr *bs_hdr;
@@ -484,7 +478,7 @@
#endif
crc = htons(crc);
- console_write(pkt_start, sizeof(pkt_start));
+ boot_uf->write(pkt_start, sizeof(pkt_start));
totlen = len + sizeof(*bs_hdr) + sizeof(crc);
totlen = htons(totlen);
@@ -504,8 +498,8 @@
#else
totlen = base64_encode(buf, totlen, encoded_buf, 1);
#endif
- console_write(encoded_buf, totlen);
- console_write("\n\r", 2);
+ boot_uf->write(encoded_buf, totlen);
+ boot_uf->write("\n\r", 2);
BOOT_LOG_INF("TX");
}
@@ -561,7 +555,7 @@
* serial port.
*/
void
-boot_serial_start(int max_input)
+boot_serial_start(const struct boot_uart_funcs *f)
{
int rc;
int off;
@@ -569,24 +563,16 @@
char *dec;
int dec_off;
int full_line;
+ int max_input;
-#ifdef __ZEPHYR__
- rc = boot_console_init();
+ boot_uf = f;
buf = in_buf;
dec = dec_buf;
- assert(max_input <= sizeof(in_buf) && max_input <= sizeof(dec_buf));
-#else
- rc = boot_uart_open();
- assert(rc == 0);
-
- buf = os_malloc(max_input);
- dec = os_malloc(max_input);
- assert(buf && dec);
-#endif
+ max_input = sizeof(in_buf);
off = 0;
while (1) {
- rc = console_read(buf + off, max_input - off, &full_line);
+ rc = f->read(buf + off, sizeof(in_buf) - off, &full_line);
if (rc <= 0 && !full_line) {
continue;
}
diff --git a/boot/mynewt/boot_uart/include/boot_uart/boot_uart.h b/boot/mynewt/boot_uart/include/boot_uart/boot_uart.h
index 29b6d00..6d69668 100644
--- a/boot/mynewt/boot_uart/include/boot_uart/boot_uart.h
+++ b/boot/mynewt/boot_uart/include/boot_uart/boot_uart.h
@@ -23,6 +23,6 @@
int boot_uart_open(void);
void boot_uart_close(void);
int boot_uart_read(char *str, int cnt, int *newline);
-void boot_uart_write(char *ptr, int cnt);
+void boot_uart_write(const char *ptr, int cnt);
#endif /* _BOOT_UART_H_ */
diff --git a/boot/mynewt/boot_uart/src/boot_uart.c b/boot/mynewt/boot_uart/src/boot_uart.c
index 5e2fbbe..ad6d772 100644
--- a/boot/mynewt/boot_uart/src/boot_uart.c
+++ b/boot/mynewt/boot_uart/src/boot_uart.c
@@ -150,14 +150,14 @@
* sends, so we can drop the outgoing data here.
*/
void
-boot_uart_write(char *ptr, int cnt)
+boot_uart_write(const char *ptr, int cnt)
{
}
#else
void
-boot_uart_write(char *ptr, int cnt)
+boot_uart_write(const char *ptr, int cnt)
{
int sr;
diff --git a/boot/mynewt/src/main.c b/boot/mynewt/src/main.c
index b504896..7521e3b 100755
--- a/boot/mynewt/src/main.c
+++ b/boot/mynewt/src/main.c
@@ -31,13 +31,14 @@
#include <hal/hal_bsp.h>
#include <hal/hal_system.h>
#include <hal/hal_flash.h>
+#include <hal/hal_watchdog.h>
#include <sysinit/sysinit.h>
#ifdef MCUBOOT_SERIAL
#include <hal/hal_gpio.h>
#include <hal/hal_nvreg.h>
#include <boot_serial/boot_serial.h>
#endif
-#if defined(MCUBOOT_SERIAL) && MYNEWT_VAL(BOOT_SERIAL_DETECT_TIMEOUT) != 0
+#if defined(MCUBOOT_SERIAL)
#include <boot_uart/boot_uart.h>
#endif
#include <console/console.h>
@@ -45,26 +46,42 @@
#include "bootutil/bootutil.h"
#include "bootutil/bootutil_log.h"
-#define BOOT_AREA_DESC_MAX (256)
-#define AREA_DESC_MAX (BOOT_AREA_DESC_MAX)
-
-#ifdef MCUBOOT_SERIAL
+#if defined(MCUBOOT_SERIAL)
+#define BOOT_SERIAL_REPORT_DUR \
+ (MYNEWT_VAL(OS_CPUTIME_FREQ) / MYNEWT_VAL(BOOT_SERIAL_REPORT_FREQ))
#define BOOT_SERIAL_INPUT_MAX (512)
-#endif
-/*
- * Temporary flash_device_base() implementation.
- *
- * TODO: remove this when mynewt needs to support flash_device_base()
- * for devices with nonzero base addresses.
- */
-int flash_device_base(uint8_t fd_id, uintptr_t *ret)
+static int boot_read(char *str, int cnt, int *newline);
+static const struct boot_uart_funcs boot_uart_funcs = {
+ .read = boot_read,
+ .write = boot_uart_write
+};
+
+static int
+boot_read(char *str, int cnt, int *newline)
{
- *ret = 0;
- return 0;
+#if MYNEWT_VAL(BOOT_SERIAL_REPORT_PIN) != -1
+ static uint32_t tick = 0;
+
+ if (tick == 0) {
+ /*
+ * Configure GPIO line as output. This is a pin we toggle at the
+ * given frequency.
+ */
+ hal_gpio_init_out(MYNEWT_VAL(BOOT_SERIAL_REPORT_PIN), 0);
+ tick = os_cputime_get32();
+ } else {
+ if (os_cputime_get32() - tick > BOOT_SERIAL_REPORT_DUR) {
+ hal_gpio_toggle(MYNEWT_VAL(BOOT_SERIAL_REPORT_PIN));
+ tick = os_cputime_get32();
+ }
+ }
+#endif
+ hal_watchdog_tickle();
+
+ return boot_uart_read(str, cnt, newline);
}
-#ifdef MCUBOOT_SERIAL
#if MYNEWT_VAL(BOOT_SERIAL_DETECT_TIMEOUT) != 0
/** Don't include null-terminator in comparison. */
@@ -93,14 +110,14 @@
MYNEWT_VAL(BOOT_SERIAL_DETECT_TIMEOUT) /
(1000.0 / MYNEWT_VAL(OS_CPUTIME_FREQ));
- rc = boot_serial_uart_open();
+ rc = boot_uart_open();
assert(rc == 0);
start_tick = os_cputime_get32();
while (1) {
/* Read a single character from the UART. */
- rc = boot_serial_uart_read(&ch, 1, &newline);
+ rc = boot_uart_read(&ch, 1, &newline);
if (rc > 0) {
/* Eliminate the oldest character in the buffer to make room for
* the new one.
@@ -115,14 +132,14 @@
MYNEWT_VAL(BOOT_SERIAL_DETECT_STRING),
BOOT_SERIAL_DETECT_STRING_LEN);
if (rc == 0) {
- boot_serial_uart_close();
+ boot_uart_close();
return true;
}
}
/* Abort the listen on timeout. */
if (os_cputime_get32() >= start_tick + timeout_dur) {
- boot_serial_uart_close();
+ boot_uart_close();
return false;
}
}
@@ -141,11 +158,8 @@
MYNEWT_VAL(BOOT_SERIAL_NVREG_MAGIC)) {
hal_nvreg_write(MYNEWT_VAL(BOOT_SERIAL_NVREG_INDEX), 0);
-
- boot_serial_start(BOOT_SERIAL_INPUT_MAX);
- assert(0);
+ goto serial_boot;
}
-
#endif
/*
@@ -157,8 +171,7 @@
MYNEWT_VAL(BOOT_SERIAL_DETECT_PIN_CFG));
if (hal_gpio_read(MYNEWT_VAL(BOOT_SERIAL_DETECT_PIN)) ==
MYNEWT_VAL(BOOT_SERIAL_DETECT_PIN_VAL)) {
- boot_serial_start(BOOT_SERIAL_INPUT_MAX);
- assert(0);
+ goto serial_boot;
}
#endif
@@ -168,13 +181,29 @@
*/
#if MYNEWT_VAL(BOOT_SERIAL_DETECT_TIMEOUT) != 0
if (serial_detect_uart_string()) {
- boot_serial_start(BOOT_SERIAL_INPUT_MAX);
- assert(0);
+ goto serial_boot;
}
#endif
+ return;
+serial_boot:
+ boot_uart_open();
+ boot_serial_start(&boot_uart_funcs);
+ assert(0);
}
#endif
+/*
+ * Temporary flash_device_base() implementation.
+ *
+ * TODO: remove this when mynewt needs to support flash_device_base()
+ * for devices with nonzero base addresses.
+ */
+int flash_device_base(uint8_t fd_id, uintptr_t *ret)
+{
+ *ret = 0;
+ return 0;
+}
+
int
main(void)
{
diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c
index 07ca387..b8887e0 100644
--- a/boot/zephyr/main.c
+++ b/boot/zephyr/main.c
@@ -29,7 +29,13 @@
#include "flash_map_backend/flash_map_backend.h"
#ifdef CONFIG_MCUBOOT_SERIAL
-#include <boot_serial/boot_serial.h>
+#include "boot_serial/boot_serial.h"
+#include "serial_adapter/serial_adapter.h"
+
+const struct boot_uart_funcs boot_funcs = {
+ .read = console_read,
+ .write = console_write
+};
#endif
struct device *boot_flash_device;
@@ -121,7 +127,9 @@
if (detect_value == CONFIG_BOOT_SERIAL_DETECT_PIN_VAL) {
BOOT_LOG_INF("Enter the serial recovery mode");
- boot_serial_start(CONFIG_BOOT_MAX_LINE_INPUT_LEN + 1);
+ rc = boot_console_init();
+ __ASSERT(rc, "Error initializing boot console.\n");
+ boot_serial_start(&boot_funcs);
__ASSERT(0, "Bootloader serial process was terminated unexpectedly.\n");
}
#endif