Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions include/infuse/dfu/helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,26 @@ extern "C" {
* @{
*/

/**
* @brief Prepare a flash area for write/erase
*
* Prepare to erase or write to a flash area.
*
* @note MUST call @ref infuse_dfu_write_erase_finish when complete
*
* @param fa Flash area (must be already opened)
*/
void infuse_dfu_write_erase_start(const struct flash_area *fa);

/**
* @brief Finalise a flash area write/erase
*
* Cleanup the @ref infuse_dfu_write_erase_start call once complete.
*
* @param fa Flash area (must be already opened)
*/
void infuse_dfu_write_erase_finish(const struct flash_area *fa);

/**
* @brief Erase a flash area to be ready for a new image
*
Expand Down Expand Up @@ -57,6 +77,17 @@ int infuse_dfu_nrf91_modem_delta_prepare(void);
*/
int infuse_dfu_nrf91_modem_delta_finish(void);

#ifdef CONFIG_ZTEST

/**
* @brief Get the current balance count of the start/finish helpers
*
* @return int Number of start calls minus finish calls
*/
int infuse_dfu_write_erase_call_count(void);

#endif /* CONFIG_ZTEST */

/**
* @}
*/
Expand Down
25 changes: 25 additions & 0 deletions include/infuse/epacket/interface/epacket_bt_adv.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,31 @@ extern "C" {

#define epacket_bt_adv_frame epacket_v0_versioned_frame_format

/**
* @brief Request Bluetooth scanning to be suspended
*
* After calling, any active Bluetooth scanning is suspended and any future
* scanning is disabled until @ref epacket_bt_adv_scan_resume is called.
*
* A call to @ref epacket_receive received between these two function calls will
* be actioned once @ref epacket_bt_adv_scan_resume is called for the remaining
* duration.
*
* The duration of any suspension should be tightly bounded to much less than
* CONFIG_EPACKET_INTERFACE_BT_ADV_SCAN_WATCHDOG_SEC (default 10 minutes).
*
* This can be useful when performing actions where performance is typically degraded
* by Bluetooth activity, for example writing to internal flash.
*/
void epacket_bt_adv_scan_suspend(void);

/**
* @brief Release a request for Bluetooth scanning to be suspended
*
* Release the constraint of Bluetooth scanning created by @ref epacket_bt_adv_scan_suspend.
*/
void epacket_bt_adv_scan_resume(void);

/**
* @}
*/
Expand Down
54 changes: 52 additions & 2 deletions subsys/dfu/dfu_helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,52 @@
#include <zephyr/dfu/mcuboot.h>

#include <infuse/dfu/helpers.h>
#include <infuse/epacket/interface/epacket_bt_adv.h>

#ifdef CONFIG_NRF_MODEM_LIB
#include "nrf_modem_delta_dfu.h"
#endif /* CONFIG_NRF_MODEM_LIB */

#define INTERNAL_FLASH DEVICE_DT_GET(DT_CHOSEN(zephyr_flash_controller))

#ifdef CONFIG_ZTEST
static int write_erase_call_count;

int infuse_dfu_write_erase_call_count(void)
{
return write_erase_call_count;
}

#endif /* CONFIG_ZTEST */

void infuse_dfu_write_erase_start(const struct flash_area *fa)
{
#ifdef CONFIG_EPACKET_INTERFACE_BT_ADV
if (fa->fa_dev == INTERNAL_FLASH) {
/* Erasing/writing internal flash while Bluetooth scanning is very slow */
epacket_bt_adv_scan_suspend();
}
#endif /* CONFIG_EPACKET_INTERFACE_BT_ADV */
#ifdef CONFIG_ZTEST
write_erase_call_count += 1;
#endif /* CONFIG_ZTEST */
}

void infuse_dfu_write_erase_finish(const struct flash_area *fa)
{
#ifdef CONFIG_EPACKET_INTERFACE_BT_ADV
if (fa->fa_dev == INTERNAL_FLASH) {
epacket_bt_adv_scan_resume();
}
#endif /* CONFIG_EPACKET_INTERFACE_BT_ADV */
#ifdef CONFIG_ZTEST
write_erase_call_count -= 1;
#endif /* CONFIG_ZTEST */
}

/* Implementation taken from zephyr_img_mgmt.c */
int infuse_dfu_image_erase(const struct flash_area *fa, size_t image_len,
infuse_progress_cb_t progress_cb, bool mcuboot_trailer)
int infuse_dfu_image_erase_wrapped(const struct flash_area *fa, size_t image_len,
infuse_progress_cb_t progress_cb, bool mcuboot_trailer)
{
const struct device *dev = flash_area_get_device(fa);
struct flash_pages_info page;
Expand Down Expand Up @@ -96,6 +134,18 @@ int infuse_dfu_image_erase(const struct flash_area *fa, size_t image_len,
#endif
}

int infuse_dfu_image_erase(const struct flash_area *fa, size_t image_len,
infuse_progress_cb_t progress_cb, bool mcuboot_trailer)
{
int rc;

infuse_dfu_write_erase_start(fa);
rc = infuse_dfu_image_erase_wrapped(fa, image_len, progress_cb, mcuboot_trailer);
infuse_dfu_write_erase_finish(fa);

return rc;
}

#ifdef CONFIG_NRF_MODEM_LIB
int infuse_dfu_nrf91_modem_delta_prepare(void)
{
Expand Down
50 changes: 47 additions & 3 deletions subsys/epacket/interfaces/epacket_bt_adv.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ static struct net_buf *adv_set_bufs[CONFIG_BT_EXT_ADV_MAX_ADV_SET];
static K_FIFO_DEFINE(tx_buf_queue);
static struct bt_le_ext_adv *adv_set;
static bool adv_set_active;
static uint8_t scan_suspended;
static K_SEM_DEFINE(scan_control, 1, 1);

static void bt_adv_broadcast(const struct device *dev, struct net_buf *pkt)
{
Expand Down Expand Up @@ -218,15 +220,23 @@ static void scan_cb(const bt_addr_le_t *addr, int8_t rssi, uint8_t adv_type,

static int epacket_bt_adv_receive_control(const struct device *dev, bool enable)
{
int rc;
int rc = 0;

k_sem_take(&scan_control, K_FOREVER);
if (enable) {
rc = bt_le_scan_start(&scan_param, scan_cb);
if (scan_suspended == 0) {
/* Scanning has been temporarily blocked */
rc = bt_le_scan_start(&scan_param, scan_cb);
}
infuse_work_reschedule(&scan_watchdog_work, SCAN_WDOG_TIMEOUT);
} else {
k_work_cancel_delayable(&scan_watchdog_work);
rc = bt_le_scan_stop();
if (scan_suspended == 0) {
/* Scanning has already been stopped */
rc = bt_le_scan_stop();
}
}
k_sem_give(&scan_control);
return rc;
}

Expand Down Expand Up @@ -262,6 +272,40 @@ static void scan_rx_watchdog_expired(struct k_work *work)
}
}

void epacket_bt_adv_scan_suspend(void)
{
int rc;

k_sem_take(&scan_control, K_FOREVER);
if (k_work_delayable_is_pending(&scan_watchdog_work) && (scan_suspended == 0)) {
/* Scanning is currently ongoing, cancel it */
LOG_INF("Suspending scanning");
rc = bt_le_scan_stop();
if (rc != 0) {
LOG_ERR("Failed to stop scanning (%d)", rc);
}
}
scan_suspended += 1;
k_sem_give(&scan_control);
}

void epacket_bt_adv_scan_resume(void)
{
int rc;

k_sem_take(&scan_control, K_FOREVER);
scan_suspended -= 1;
if (k_work_delayable_is_pending(&scan_watchdog_work) && (scan_suspended == 0)) {
/* Scanning is still desired by the application */
LOG_INF("Resuming scanning");
rc = bt_le_scan_start(&scan_param, scan_cb);
if (rc != 0) {
LOG_ERR("Failed to restart scanning (%d)", rc);
}
}
k_sem_give(&scan_control);
}

static int epacket_bt_adv_init(const struct device *dev)
{
k_work_init_delayable(&scan_watchdog_work, scan_rx_watchdog_expired);
Expand Down
25 changes: 25 additions & 0 deletions subsys/rpc/commands/common_file_actions.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ int rpc_common_file_actions_start(struct rpc_common_file_actions_ctx *ctx,
ctx->action = action;
ctx->received = 0;
ctx->crc = 0;
ctx->needs_cleanup = false;

switch (ctx->action) {
case RPC_ENUM_FILE_ACTION_DISCARD:
Expand Down Expand Up @@ -142,6 +143,17 @@ int rpc_common_file_actions_start(struct rpc_common_file_actions_ctx *ctx,
default:
rc = -EINVAL;
}

#ifdef CONFIG_INFUSE_DFU_HELPERS
if (ctx->fa && (rc == 0)) {
/* Write should proceed, closed by either:
* rpc_common_file_actions_finish or
* rpc_common_file_actions_error_cleanup
*/
infuse_dfu_write_erase_start(ctx->fa);
ctx->needs_cleanup = true;
}
#endif /* CONFIG_INFUSE_DFU_HELPERS */
return rc;
}

Expand Down Expand Up @@ -255,6 +267,7 @@ static int finish_cpatch(struct rpc_common_file_actions_ctx *ctx)

flash_area_open(FIXED_PARTITION_ID(slot0_partition), &fa_original);
flash_area_open(FIXED_PARTITION_ID(slot1_partition), &fa_output);
infuse_dfu_write_erase_start(fa_output);

/* Start patch process */
rc = cpatch_patch_start(fa_original, ctx->fa, &header);
Expand Down Expand Up @@ -295,6 +308,7 @@ static int finish_cpatch(struct rpc_common_file_actions_ctx *ctx)

cleanup:
/* Cleanup files */
infuse_dfu_write_erase_finish(fa_output);
flash_area_close(fa_output);
flash_area_close(fa_original);

Expand All @@ -314,6 +328,11 @@ int rpc_common_file_actions_finish(struct rpc_common_file_actions_ctx *ctx, uint
size_t mem_size;
uint8_t *mem;

if (ctx->needs_cleanup) {
infuse_dfu_write_erase_finish(ctx->fa);
ctx->needs_cleanup = false;
}

/* Temporary memory buffer */
mem = rpc_server_command_working_mem(&mem_size);

Expand Down Expand Up @@ -425,6 +444,12 @@ int rpc_common_file_actions_error_cleanup(struct rpc_common_file_actions_ctx *ct
{
int rc = 0;

#ifdef CONFIG_INFUSE_DFU_HELPERS
if (ctx->needs_cleanup) {
infuse_dfu_write_erase_finish(ctx->fa);
}
#endif /* CONFIG_INFUSE_DFU_HELPERS */

switch (ctx->action) {
#ifdef SUPPORT_APP_IMG
#ifdef SUPPORT_APP_CPATCH
Expand Down
3 changes: 2 additions & 1 deletion subsys/rpc/commands/common_file_actions.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ struct rpc_common_file_actions_ctx {
const struct flash_area *fa;
uint32_t client_ctx;
};
enum rpc_enum_file_action action;
uint32_t received;
uint32_t crc;
enum rpc_enum_file_action action;
bool needs_cleanup;
};

#define FILE_ALREADY_PRESENT 1
Expand Down
Loading