zephyr: allow recovery over usb cdc-acm with logs enabled

Modified serial_adapter so log are allowed when using USB
CDC ACM serial port emulation.

Added dedicated thread for log processing of the highest application
priority. This allows to transmit all logs without adding k_sleep
anywhere else int the code.

Introduced boot log thread is simpler than the default log threat
which decreases flash footprint by a few dozen bytes.
Added configuration for nrf52840_pca10056 which shows how
to enable looging along with USB - among other, thread log
processing is required.

build command (form zephyr-project root directory)
west build -d build/mcuboot/nrf52840_pca10056 -b nrf52840_pca10056
./bootloader/mcuboot/boot/zephyr/
 -- -DDTC_OVERLAY_FILE=./boards/nrf52840_pca10056_big.overlay
-DOVERLAY_CONFIG=./usb_cdc_acm_log_recovery.conf

Signed-off-by: Andrzej Puzdrowski <andrzej.puzdrowski@nordicsemi.no>
This commit is contained in:
Andrzej Puzdrowski 2020-02-17 13:25:32 +01:00
parent 9a4946ce9a
commit 3f092bd313
6 changed files with 123 additions and 1 deletions

View File

@ -359,6 +359,14 @@ config MULTITHREADING
config LOG_IMMEDIATE
default n if MULTITHREADING
default y
config LOG_PROCESS_THREAD
default n # mcuboot has its own log processing thread
# override USB device name
config USB_DEVICE_PRODUCT
default "MCUBOOT"
config UPDATEABLE_IMAGE_NUMBER
int "Number of updateable images"

View File

@ -0,0 +1,30 @@
/*
* Copyright (c) 2020 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
/delete-node/ &boot_partition;
/delete-node/ &slot0_partition;
/delete-node/ &slot1_partition;
&flash0 {
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
boot_partition: partition@0 {
label = "mcuboot";
reg = <0x000000000 0x00010000>;
};
slot0_partition: partition@10000 {
label = "image-0";
reg = <0x000010000 0x000074000>;
};
slot1_partition: partition@75000 {
label = "image-1";
reg = <0x00084000 0x000074000>;
};
};
};

View File

@ -44,6 +44,28 @@ const struct boot_uart_funcs boot_funcs = {
#include <usb/class/usb_dfu.h>
#endif
#if defined(CONFIG_LOG) && !defined(CONFIG_LOG_IMMEDIATE)
#ifdef CONFIG_LOG_PROCESS_THREAD
#warning "The log internal thread for log processing can't transfer the log"\
"well for MCUBoot."
#else
#include <logging/log_ctrl.h>
#define BOOT_LOG_STACK_SIZE 768
#define BOOT_LOG_PROCESSING_INTERVAL 30 /* [ms] */
/* log are processing in custom routine */
K_THREAD_STACK_DEFINE(boot_log_stack, BOOT_LOG_STACK_SIZE);
struct k_thread boot_log_thread;
/* log processing need to be initalized by the application */
#define ZEPHYR_BOOT_LOG_START() zephyr_boot_log_start()
#endif /* CONFIG_LOG_PROCESS_THREAD */
#else
/* synchronous log mode doesn't need to be initalized by the application */
#define ZEPHYR_BOOT_LOG_START() do { } while (false)
#endif /* defined(CONFIG_LOG) && !defined(CONFIG_LOG_IMMEDIATE) */
#ifdef CONFIG_SOC_FAMILY_NRF
#include <hal/nrf_power.h>
@ -175,6 +197,45 @@ static void do_boot(struct boot_rsp *rsp)
}
#endif
#if defined(CONFIG_LOG) && !defined(CONFIG_LOG_IMMEDIATE) &&\
!defined(CONFIG_LOG_PROCESS_THREAD)
/* The log internal thread for log processing can't transfer log well as has too
* low priority.
* Dedicated thread for log processing below uses highest application
* priority. This allows to transmit all logs without adding k_sleep/k_yield
* anywhere else int the code.
*/
/* most simple log processing theread */
void boot_log_thread_func(void *dummy1, void *dummy2, void *dummy3)
{
(void)dummy1;
(void)dummy2;
(void)dummy3;
log_init();
while (1) {
if (log_process(false) == false) {
k_sleep(BOOT_LOG_PROCESSING_INTERVAL);
}
}
}
void zephyr_boot_log_start(void)
{
/* start logging thread */
k_thread_create(&boot_log_thread, boot_log_stack,
K_THREAD_STACK_SIZEOF(boot_log_stack),
boot_log_thread_func, NULL, NULL, NULL,
K_HIGHEST_APPLICATION_THREAD_PRIO, 0,
BOOT_LOG_PROCESSING_INTERVAL);
k_thread_name_set(&boot_log_thread, "logging");
}
#endif/* defined(CONFIG_LOG) && !defined(CONFIG_LOG_IMMEDIATE) &&\
!defined(CONFIG_LOG_PROCESS_THREAD) */
void main(void)
{
struct boot_rsp rsp;
@ -184,6 +245,8 @@ void main(void)
os_heap_init();
ZEPHYR_BOOT_LOG_START();
#if (!defined(CONFIG_XTENSA) && defined(DT_FLASH_DEV_NAME))
if (!flash_device_get_binding(DT_FLASH_DEV_NAME)) {
BOOT_LOG_ERR("Flash device %s not found", DT_FLASH_DEV_NAME);

View File

@ -13,3 +13,8 @@ tests:
sample.bootloader.mcuboot.usb_cdc_acm_recovery:
tags: bootloader_mcuboot
platform_whitelist: nrf52840_pca10059
sample.bootloader.mcuboot.usb_cdc_acm_recovery_log:
extra_args: OVERLAY_CONFIG=./usb_cdc_acm_log_recovery.conf
DTC_OVERLAY=./boards/nrf52840_pca10056_big.overlay
platform_whitelist: nrf52840_pca10056
tags: bootloader_mcuboot

View File

@ -22,7 +22,7 @@
#include "bootutil/bootutil_log.h"
#include <usb/usb_device.h>
#ifdef CONFIG_UART_CONSOLE
#if defined(CONFIG_BOOT_SERIAL_UART) && defined(CONFIG_UART_CONSOLE)
#error Zephyr UART console must been disabled if serial_adapter module is used.
#endif

View File

@ -0,0 +1,16 @@
CONFIG_LOG=y
# The build won't fit on the partition allocated for it without size
# optimizations.
CONFIG_SIZE_OPTIMIZATIONS=y
# Serial
CONFIG_SERIAL=y
CONFIG_UART_LINE_CTRL=y
# MCUBoot serial
CONFIG_MCUBOOT_SERIAL=y
CONFIG_BOOT_SERIAL_CDC_ACM=y
CONFIG_LOG_BACKEND_UART=y
CONFIG_LOG_BACKEND_RTT=n