From 302df0230d029e76feeb4f03a3acf4b00d08d70f Mon Sep 17 00:00:00 2001 From: skiinder Date: Tue, 31 Mar 2026 15:09:23 +0800 Subject: [PATCH] =?UTF-8?q?feat(app):=20=E4=BD=BF=E7=94=A8=E4=BC=A0?= =?UTF-8?q?=E6=84=9F=E5=99=A8=E9=A9=B1=E5=8A=A8=E9=87=8D=E6=9E=84=E7=94=B5?= =?UTF-8?q?=E6=B1=A0=E5=92=8C=E6=A8=A1=E5=BC=8F=E5=88=87=E6=8D=A2=E6=A8=A1?= =?UTF-8?q?=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将电池模块从ADC直接采样改为使用sensor子系统,通过battery_sense传感器获取电压 - 将模式切换模块从ADC采样改为使用mode_sense传感器获取模式电压 - 移除GPIO控制的电池使能脚,改用传感器的PM管理机制 - 更新DTS配置,移除大量设备状态设置,添加boot-mode保留内存支持 perf(pm): 调整分区大小以支持单应用引导模式 - 将mcuboot分区从0xc000扩大到0x100,为单应用模式提供更大空间 - 相应调整app分区地址布局,确保内存分配合理 - 移除secondary镜像相关配置,优化flash使用 refactor(boot): 添加MCUBOOT单应用模式配置 - 在sysbuild中启用单应用模式支持 - 为引导加载程序添加保留内存和启动模式配置 - 配置CDC ACM串口用于引导模式通信 --- app.overlay | 71 +------ pm_static.yml | 26 +-- prj.conf | 4 + src/modules/battery_module.c | 322 ++++++++++++++++--------------- src/modules/mode_switch_module.c | 44 ++--- sysbuild.conf | 1 + sysbuild/mcuboot.conf | 25 +++ sysbuild/mcuboot.overlay | 23 +++ 8 files changed, 243 insertions(+), 273 deletions(-) create mode 100644 sysbuild/mcuboot.conf create mode 100644 sysbuild/mcuboot.overlay diff --git a/app.overlay b/app.overlay index 496849d..8b7a48f 100644 --- a/app.overlay +++ b/app.overlay @@ -2,16 +2,7 @@ / { chosen { - zephyr,display = &st7789v3; - }; - - aliases { - backlight = &backlight; - }; - - zephyr,user { - vbat-en-gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>; - io-channels = <&adc 5>, <&adc 7>; + zephyr,boot-mode = &boot_mode0; }; hid_dev_0: hid_dev_0 { @@ -45,64 +36,12 @@ }; }; -&gpio0 { - status = "okay"; -}; - -&gpio1 { - status = "okay"; -}; - -&gpiote { - status = "okay"; -}; - -&led_0 { - status = "okay"; -}; - -&led_1 { - status = "okay"; -}; - -/* 使能 SAADC,mode_switch_module 使用 channel 7 采样模式拨码电压。 */ -&adc { - status = "okay"; -}; - -&i2c1 { +&gpregret1 { status = "okay"; - ip5305: pmic@75 { + boot_mode0: boot_mode@0 { + compatible = "zephyr,retention"; status = "okay"; - keepalive-interval-ms = <10000>; + reg = <0x0 0x1>; }; }; - -&usbd { - status = "okay"; -}; - -qdec: &qdec { - status = "okay"; -}; - -&spi3 { - status = "okay"; -}; - -&mipi_dbi { - status = "okay"; -}; - -&st7789v3 { - status = "okay"; -}; - -&pwm_leds { - status = "okay"; -}; - -&pwm0 { - status = "okay"; -}; diff --git a/pm_static.yml b/pm_static.yml index 2f28ea2..f85e5e7 100644 --- a/pm_static.yml +++ b/pm_static.yml @@ -1,37 +1,31 @@ mcuboot: address: 0x0 - end_address: 0xc000 + end_address: 0x10000 region: flash_primary - size: 0xc000 + size: 0x10000 mcuboot_pad: - address: 0xc000 - end_address: 0xc200 + address: 0x10000 + end_address: 0x10200 region: flash_primary size: 0x200 app: - address: 0xc200 - end_address: 0x82000 + address: 0x10200 + end_address: 0xf8000 region: flash_primary - size: 0x75e00 + size: 0xe7e00 mcuboot_primary: - address: 0xc000 - end_address: 0x82000 + address: 0x10000 + end_address: 0xf8000 orig_span: &id001 - mcuboot_pad - app region: flash_primary - size: 0x76000 + size: 0xe8000 span: *id001 -mcuboot_secondary: - address: 0x82000 - end_address: 0xf8000 - region: flash_primary - size: 0x76000 - settings_storage: address: 0xf8000 end_address: 0x100000 diff --git a/prj.conf b/prj.conf index dccd133..a46e503 100644 --- a/prj.conf +++ b/prj.conf @@ -16,6 +16,10 @@ CONFIG_MCUMGR_GRP_OS=n CONFIG_IMG_MANAGER=n CONFIG_STREAM_FLASH=n +CONFIG_RETAINED_MEM=y +CONFIG_RETENTION=y +CONFIG_RETENTION_BOOT_MODE=y + CONFIG_BT=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_SMP=y diff --git a/src/modules/battery_module.c b/src/modules/battery_module.c index a615fa3..5d357c2 100644 --- a/src/modules/battery_module.c +++ b/src/modules/battery_module.c @@ -2,9 +2,9 @@ #include #include -#include -#include #include +#include +#include #include #include @@ -20,11 +20,8 @@ #include LOG_MODULE_REGISTER(MODULE); -#define BATTERY_USER_NODE DT_PATH(zephyr_user) -#define BATTERY_ADC_IO_CH_IDX 1 +#define BATTERY_SENSE_NODE DT_NODELABEL(battery_sense) #define BATTERY_SAMPLE_INTERVAL_MS 1000 -#define BATTERY_VDIV_NUM 2 -#define BATTERY_VDIV_DEN 1 #define BATTERY_MV_WINDOW_SIZE 10 /* @@ -35,18 +32,26 @@ LOG_MODULE_REGISTER(MODULE); #define BATTERY_EMPTY_MV 3300 #define BATTERY_FULL_MV 4100 -static const struct adc_dt_spec battery_adc = - ADC_DT_SPEC_GET_BY_IDX(BATTERY_USER_NODE, BATTERY_ADC_IO_CH_IDX); +static const struct device *const ip5305_dev = DEVICE_DT_GET(DT_NODELABEL(ip5305)); +static const struct device *const battery_sensor_dev = DEVICE_DT_GET(BATTERY_SENSE_NODE); /* - * 电池采样使能脚从 zephyr,user/vbat-en-gpios 读取,避免把引脚号硬编码在 C 里。 - * 后续板级改脚位只需改 DTS,不需要改固件代码。 + * 板级电源采样结果: + * - 由 board provider 负责给出“原始但可用”的充电状态与电压值; + * - 本模块基于这些采样结果做滤波、SOC 估算和事件发布。 */ -static const struct gpio_dt_spec battery_en_gpio = - GPIO_DT_SPEC_GET(BATTERY_USER_NODE, vbat_en_gpios); - -static const struct device *const ip5305_dev = DEVICE_DT_GET(DT_NODELABEL(ip5305)); +struct board_power_sample +{ + int32_t voltage_mv; + bool charging; + bool full; +}; +/* + * 对外上报状态: + * - 保持现有 battery_status_event 语义不变; + * - 只承载业务层需要的 charging/full/soc 三元组。 + */ struct battery_status { bool charging; @@ -62,10 +67,16 @@ struct battery_filter_state size_t index; }; +/* + * 模块上下文: + * - sample_work 周期性拉取 board power sample; + * - filter 负责平滑电池电压; + * - last_status 用于抑制重复事件; + * - pm_restrict_level 跟踪当前对 power manager 的限制等级。 + */ struct battery_ctx { struct k_work_delayable sample_work; - int16_t adc_sample_buffer; atomic_t active; struct battery_status last_status; bool has_last_status; @@ -77,17 +88,14 @@ static struct battery_ctx battery = { .pm_restrict_level = POWER_MANAGER_LEVEL_MAX, }; -static void battery_module_resume(void); - +/* 线性 SOC 估算:把平滑后的电池电压映射到 0~100%。 */ static uint8_t soc_from_mv(int32_t mv) { - if (mv <= BATTERY_EMPTY_MV) - { + if (mv <= BATTERY_EMPTY_MV) { return 0; } - if (mv >= BATTERY_FULL_MV) - { + if (mv >= BATTERY_FULL_MV) { return 100; } @@ -95,109 +103,126 @@ static uint8_t soc_from_mv(int32_t mv) return (uint8_t)CLAMP(soc, 0, 100); } -static int adc_sample_once_mv(int32_t *mv) +/* 初始化/恢复时清空滤波器,避免旧样本影响新一轮估算。 */ +static void battery_filter_reset(void) { - struct adc_sequence sequence = {0}; - int err = adc_sequence_init_dt(&battery_adc, &sequence); - if (err) - { - return err; - } - - sequence.buffer = &battery.adc_sample_buffer; - sequence.buffer_size = sizeof(battery.adc_sample_buffer); - - err = adc_read_dt(&battery_adc, &sequence); - if (err) - { - LOG_WRN("adc_read_dt failed (err=%d)", err); - return err; - } - - *mv = battery.adc_sample_buffer; - err = adc_raw_to_millivolts_dt(&battery_adc, mv); - if (err) - { - LOG_WRN("adc_raw_to_millivolts_dt failed (err=%d raw=%d)", - err, battery.adc_sample_buffer); - } - - return err; + battery.filter.sum = 0; + battery.filter.count = 0; + battery.filter.index = 0; } -static int read_battery_mv(int32_t *mv) +/* + * 将最新电压样本写入固定窗口平均滤波器。 + * 返回值始终是“窗口平均后的电池电压”,供上层做 SOC 估算。 + */ +static int32_t battery_filter_apply(int32_t voltage_mv) { - int err; - int32_t sensed_mv; - - err = adc_sample_once_mv(&sensed_mv); - if (err) - { - return err; - } - - /* - * 板级电池检测存在分压,ADC 读到的是分压后电压。 - * 这里按分压比还原电池端真实电压,供 SOC 估算与事件上报使用。 - */ - int32_t battery_mv = (sensed_mv * BATTERY_VDIV_NUM) / BATTERY_VDIV_DEN; - - /* - * 使用固定窗口平均抑制采样抖动。 - * 窗口未填满前按当前样本数求平均,填满后使用环形缓冲滚动更新。 - */ - if (battery.filter.count < BATTERY_MV_WINDOW_SIZE) - { - battery.filter.window[battery.filter.index] = battery_mv; - battery.filter.sum += battery_mv; + if (battery.filter.count < BATTERY_MV_WINDOW_SIZE) { + battery.filter.window[battery.filter.index] = voltage_mv; + battery.filter.sum += voltage_mv; battery.filter.count++; - } - else - { + } else { battery.filter.sum -= battery.filter.window[battery.filter.index]; - battery.filter.window[battery.filter.index] = battery_mv; - battery.filter.sum += battery_mv; + battery.filter.window[battery.filter.index] = voltage_mv; + battery.filter.sum += voltage_mv; } battery.filter.index = (battery.filter.index + 1U) % BATTERY_MV_WINDOW_SIZE; - *mv = (int32_t)(battery.filter.sum / (int64_t)battery.filter.count); - - return 0; + return (int32_t)(battery.filter.sum / (int64_t)battery.filter.count); } -static int read_battery_status(struct battery_status *status) +/* + * 控制 board-provided battery_sense sensor 的供电状态。 + * 这里不直接操纵 GPIO,而是走 sensor 的 PM action,让 power-gpios + * 与 ADC runtime PM 都由 voltage-divider 驱动统一管理。 + */ +static int board_power_monitor_set_voltage_sensor_enabled(bool enable) { - int err; - int32_t mv; + return pm_device_action_run(battery_sensor_dev, + enable ? PM_DEVICE_ACTION_RESUME : + PM_DEVICE_ACTION_SUSPEND); +} - err = ip5305_is_charging(ip5305_dev, &status->charging); - if (err) - { +/* 从 battery_sense 读取一次当前电池电压(单位 mV)。 */ +static int board_power_monitor_read_voltage_mv(int32_t *voltage_mv) +{ + struct sensor_value value; + int err = sensor_sample_fetch(battery_sensor_dev); + + if (err) { + LOG_WRN("sensor_sample_fetch(battery) failed (err=%d)", err); return err; } - err = ip5305_is_charge_full(ip5305_dev, &status->full); - if (err) - { + err = sensor_channel_get(battery_sensor_dev, SENSOR_CHAN_VOLTAGE, &value); + if (err) { + LOG_WRN("sensor_channel_get(battery) failed (err=%d)", err); return err; } - err = read_battery_mv(&mv); - if (err) - { - LOG_WRN("read_battery_mv failed (err=%d)", err); - return err; - } - - status->soc = soc_from_mv(mv); + *voltage_mv = (int32_t)sensor_value_to_milli(&value); return 0; } +/* 从 IP5305 读取一次充电态与满电态。 */ +static int board_power_monitor_read_charge_state(bool *charging, bool *full) +{ + int err = ip5305_is_charging(ip5305_dev, charging); + + if (err) { + LOG_WRN("ip5305_is_charging failed (err=%d)", err); + return err; + } + + err = ip5305_is_charge_full(ip5305_dev, full); + if (err) { + LOG_WRN("ip5305_is_charge_full failed (err=%d)", err); + return err; + } + + return 0; +} + +/* + * 聚合一次完整的 board power sample: + * 1) 先读 PMIC 状态; + * 2) 再读 battery_sense 电压; + * 3) 最后对电压做窗口平均,输出稳定值。 + */ +static int board_power_monitor_collect_sample(struct board_power_sample *sample) +{ + int32_t voltage_mv; + int err = board_power_monitor_read_charge_state(&sample->charging, &sample->full); + + if (err) { + return err; + } + + err = board_power_monitor_read_voltage_mv(&voltage_mv); + if (err) { + return err; + } + + sample->voltage_mv = battery_filter_apply(voltage_mv); + return 0; +} + +/* 将 board sample 映射成对外 battery status。 */ +static void battery_status_from_sample(const struct board_power_sample *sample, + struct battery_status *status) +{ + status->charging = sample->charging; + status->full = sample->full; + status->soc = soc_from_mv(sample->voltage_mv); +} + +/* 统一封装 battery_status_event 发布,隔离事件总线细节。 */ static void publish_battery_status_event(const struct battery_status *status) { battery_status_event_submit(status->charging, status->full, status->soc); } +/* 判断本轮状态是否值得上报,避免重复事件淹没总线。 */ static bool battery_status_changed(const struct battery_status *lhs, const struct battery_status *rhs) { @@ -223,99 +248,79 @@ static void update_power_restrict_by_charging(bool charging) power_manager_restrict(MODULE_IDX(MODULE), target); } +/* + * 启停采样: + * - enable=true 时恢复 battery_sense,等待前端稳定后开始周期采样; + * - enable=false 时停止 work 并挂起 battery_sense,避免持续耗电。 + */ static void battery_sampling_set_enabled(bool enable) { atomic_set(&battery.active, enable); - (void)gpio_pin_set_dt(&battery_en_gpio, enable ? GPIO_OUTPUT_ACTIVE : GPIO_OUTPUT_INACTIVE); + int err = board_power_monitor_set_voltage_sensor_enabled(enable); - if (enable) - { - // 延迟2s开始采样等待电池电压稳定 - k_work_reschedule(&battery.sample_work, K_MSEC(2000)); + if (err) { + LOG_WRN("board_power_monitor_set_voltage_sensor_enabled(%d) failed (err=%d)", + enable, err); } - else - { + + if (enable) { + /* 延迟开始采样,等待板上采样前端和分压网络稳定。 */ + k_work_reschedule(&battery.sample_work, K_MSEC(2000)); + } else { (void)k_work_cancel_delayable(&battery.sample_work); } } +/* 周期性读取 board power sample,并在需要时上报业务状态。 */ static void battery_sample_fn(struct k_work *work) { ARG_UNUSED(work); - if (!atomic_get(&battery.active)) - { + if (!atomic_get(&battery.active)) { return; } + struct board_power_sample sample; + struct battery_status status; + int err = board_power_monitor_collect_sample(&sample); - struct battery_status sampled; - int err = read_battery_status(&sampled); - if (err) - { + if (err) { goto out_reschedule; } - update_power_restrict_by_charging(sampled.charging); + battery_status_from_sample(&sample, &status); + update_power_restrict_by_charging(status.charging); - /* - * 仅在状态发生变化时上报,避免重复事件淹没总线。 - * 变化条件:充电标志、满电标志、SOC 任意一个变化。 - */ if (!battery.has_last_status || - battery_status_changed(&sampled, &battery.last_status)) - { - battery.last_status = sampled; + battery_status_changed(&status, &battery.last_status)) { + battery.last_status = status; battery.has_last_status = true; - publish_battery_status_event(&sampled); + publish_battery_status_event(&status); } out_reschedule: k_work_reschedule(&battery.sample_work, K_MSEC(BATTERY_SAMPLE_INTERVAL_MS)); } +/* 初始化 board power monitor consumer,并拉起首轮采样。 */ static int battery_module_init(void) { - if (!device_is_ready(ip5305_dev)) - { + if (!device_is_ready(ip5305_dev)) { LOG_ERR("IP5305 device not ready"); return -ENODEV; } - if (!adc_is_ready_dt(&battery_adc)) - { - LOG_ERR("Battery ADC device not ready"); + if (!device_is_ready(battery_sensor_dev)) { + LOG_ERR("Battery sense device not ready"); return -ENODEV; } - if (!device_is_ready(battery_en_gpio.port)) - { - LOG_ERR("Battery EN GPIO device not ready"); - return -ENODEV; - } - - int err = gpio_pin_configure_dt(&battery_en_gpio, GPIO_OUTPUT_INACTIVE); - if (err) - { - LOG_ERR("Battery EN GPIO configure failed (err=%d)", err); - return err; - } - - err = adc_channel_setup_dt(&battery_adc); - if (err) - { - LOG_ERR("Battery ADC channel setup failed (err=%d)", err); - return err; - } - /* 默认非充电态允许进入 SUSPENDED,但禁止进入 OFF。 */ update_power_restrict_by_charging(false); k_work_init_delayable(&battery.sample_work, battery_sample_fn); battery.has_last_status = false; - battery.filter.sum = 0; - battery.filter.count = 0; - battery.filter.index = 0; + battery_filter_reset(); atomic_set(&battery.active, false); battery_sampling_set_enabled(true); @@ -323,10 +328,10 @@ static int battery_module_init(void) return 0; } +/* 响应系统挂起:停止采样,并把本模块切到 STANDBY。 */ static void battery_module_suspend(void) { - if (!atomic_get(&battery.active)) - { + if (!atomic_get(&battery.active)) { /* 已经处于挂起态,避免重复上报 STANDBY 造成 power_down 循环。 */ return; } @@ -335,10 +340,10 @@ static void battery_module_suspend(void) module_set_state(MODULE_STATE_STANDBY); } +/* 响应系统唤醒:恢复电压传感器并重启周期采样。 */ static void battery_module_resume(void) { - if (atomic_get(&battery.active)) - { + if (atomic_get(&battery.active)) { return; } @@ -346,21 +351,18 @@ static void battery_module_resume(void) module_set_state(MODULE_STATE_READY); } +/* 仅处理模块 ready 和系统电源状态事件,保持模块职责单一。 */ static bool app_event_handler(const struct app_event_header *aeh) { - if (is_module_state_event(aeh)) - { + if (is_module_state_event(aeh)) { const struct module_state_event *event = cast_module_state_event(aeh); - if (check_state(event, MODULE_ID(main), MODULE_STATE_READY)) - { + if (check_state(event, MODULE_ID(main), MODULE_STATE_READY)) { int err = battery_module_init(); - if (err) - { + + if (err) { module_set_state(MODULE_STATE_ERROR); - } - else - { + } else { module_set_state(MODULE_STATE_READY); } } diff --git a/src/modules/mode_switch_module.c b/src/modules/mode_switch_module.c index 0680330..7f27bbe 100644 --- a/src/modules/mode_switch_module.c +++ b/src/modules/mode_switch_module.c @@ -1,7 +1,6 @@ #include #include -#include -#include +#include #include #include #include @@ -18,35 +17,25 @@ #include LOG_MODULE_REGISTER(MODULE); -#define MODE_USER_NODE DT_PATH(zephyr_user) -#define MODE_ADC_IO_CH_IDX 0 +#define MODE_SENSE_NODE DT_NODELABEL(mode_sense) #define MODE_SAMPLE_INTERVAL_MS 50 -static const struct adc_dt_spec mode_adc = - ADC_DT_SPEC_GET_BY_IDX(MODE_USER_NODE, MODE_ADC_IO_CH_IDX); +static const struct device *const mode_sensor_dev = DEVICE_DT_GET(MODE_SENSE_NODE); static struct k_work_delayable mode_sample_work; -static int16_t adc_sample_buffer; static atomic_t active; static mode_type_t current_mode; static uint8_t mode_stable_status; -static int init_adc(void) +static int init_mode_sensor(void) { - if (!adc_is_ready_dt(&mode_adc)) + if (!device_is_ready(mode_sensor_dev)) { - LOG_ERR("ADC device not ready"); + LOG_ERR("Mode sense device not ready"); return -ENODEV; } - int err = adc_channel_setup_dt(&mode_adc); - if (err) - { - LOG_ERR("ADC channel setup failed (err=%d)", err); - return err; - } - return 0; } @@ -81,29 +70,22 @@ static mode_type_t classify_mode_from_mv(int32_t mv) static int read_mode(mode_type_t *mode) { - struct adc_sequence sequence = {0}; - int err = adc_sequence_init_dt(&mode_adc, &sequence); + struct sensor_value value; + int err = sensor_sample_fetch(mode_sensor_dev); if (err) { + LOG_WRN("sensor_sample_fetch(mode) failed (err=%d)", err); return err; } - sequence.buffer = &adc_sample_buffer; - sequence.buffer_size = sizeof(adc_sample_buffer); - - err = adc_read_dt(&mode_adc, &sequence); - if (err) - { - return err; - } - - int32_t v = adc_sample_buffer; - err = adc_raw_to_millivolts_dt(&mode_adc, &v); + err = sensor_channel_get(mode_sensor_dev, SENSOR_CHAN_VOLTAGE, &value); if (err) { + LOG_WRN("sensor_channel_get(mode) failed (err=%d)", err); return err; } + int32_t v = (int32_t)sensor_value_to_milli(&value); *mode = classify_mode_from_mv(v); return 0; @@ -187,7 +169,7 @@ static void init_mode_switch(void) if (atomic_get(&active)) return; - if (init_adc()) + if (init_mode_sensor()) { module_set_state(MODULE_STATE_ERROR); return; diff --git a/sysbuild.conf b/sysbuild.conf index 47f00ff..1e134e9 100644 --- a/sysbuild.conf +++ b/sysbuild.conf @@ -1 +1,2 @@ SB_CONFIG_BOOTLOADER_MCUBOOT=y +SB_CONFIG_MCUBOOT_MODE_SINGLE_APP=y diff --git a/sysbuild/mcuboot.conf b/sysbuild/mcuboot.conf new file mode 100644 index 0000000..90b7843 --- /dev/null +++ b/sysbuild/mcuboot.conf @@ -0,0 +1,25 @@ +CONFIG_LOG=n +CONFIG_CONSOLE=n +CONFIG_UART_CONSOLE=n + +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_UART_LINE_CTRL=y + +CONFIG_USB_DEVICE_STACK=y +CONFIG_USB_DEVICE_REMOTE_WAKEUP=n +CONFIG_USB_CDC_ACM=y +CONFIG_USB_NRFX=y +CONFIG_USB_DEVICE_PRODUCT="MCUBOOT" +CONFIG_USB_DEVICE_MANUFACTURER="new_kbd" +CONFIG_USB_DEVICE_VID=0x1209 +CONFIG_USB_DEVICE_PID=0x0002 + +CONFIG_RETAINED_MEM=y +CONFIG_RETENTION=y +CONFIG_RETENTION_BOOT_MODE=y + +CONFIG_MCUBOOT_SERIAL=y +CONFIG_BOOT_SERIAL_CDC_ACM=y +CONFIG_BOOT_SERIAL_BOOT_MODE=y +CONFIG_BOOT_SERIAL_NO_APPLICATION=y diff --git a/sysbuild/mcuboot.overlay b/sysbuild/mcuboot.overlay new file mode 100644 index 0000000..01c42dc --- /dev/null +++ b/sysbuild/mcuboot.overlay @@ -0,0 +1,23 @@ +/ { + chosen { + zephyr,boot-mode = &boot_mode0; + }; +}; + +&usbd { + status = "okay"; + + cdc_acm_uart0: cdc_acm_uart0 { + compatible = "zephyr,cdc-acm-uart"; + }; +}; + +&gpregret1 { + status = "okay"; + + boot_mode0: boot_mode@0 { + compatible = "zephyr,retention"; + status = "okay"; + reg = <0x0 0x1>; + }; +};