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
1 change: 1 addition & 0 deletions apps/gateway_lte/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ CONFIG_BT_MAX_CONN=4
# LTE
CONFIG_NETWORKING=y
CONFIG_LTE_NETWORK_MODE_LTE_M=y
CONFIG_LTE_PSM_REQ=n
CONFIG_INFUSE_NRF_MODEM_MONITOR_CONN_STATE_LOG=y
CONFIG_INFUSE_NRF_MODEM_DATA_PROFILE_DEFAULT=4
CONFIG_INFUSE_NRF_MODEM_MONITOR_MOBILITY_NORDIC_PROPRIETARY=y
Expand Down
2 changes: 1 addition & 1 deletion include/infuse/drivers/watchdog.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ extern "C" {
static int name##_register(void) \
{ \
(void)period_name; \
wdog_channel = \
chan_name = \
IS_ENABLED(dependency) ? infuse_watchdog_install(&period_name) : -ENODEV; \
return 0; \
} \
Expand Down
5 changes: 5 additions & 0 deletions include/infuse/lib/memfault_config/memfault_platform_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,8 @@
#define MEMFAULT_METRICS_BATTERY_ENABLE 1
#define MEMFAULT_METRICS_BATTERY_SOC_PCT_SCALE_VALUE 1
#endif

/* Infuse-IoT does not generate trace events from ISRs */
#define MEMFAULT_TRACE_EVENT_WITH_LOG_FROM_ISR_ENABLED 0
/* Larger event log size required for secure fault info */
#define MEMFAULT_TRACE_EVENT_MAX_LOG_LEN 100
52 changes: 43 additions & 9 deletions lib/memfault/infuse_memfault.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ bool memfault_platform_time_get_current(sMemfaultCurrentTime *current_time)

#include "../core/src/memfault_reboot_tracking_private.h"

static struct k_work_delayable secure_fault_trace;

#ifndef CONFIG_TFM_PLATFORM_FAULT_INFO_QUERY
BUILD_ASSERT(IS_ENABLED(CONFIG_ZTEST));

Expand Down Expand Up @@ -156,14 +158,48 @@ int infuse_common_boot_secure_fault_info(struct fault_exception_info_t *fault_in
#define MEMFAULT_REBOOT_INFO_MAGIC 0x21544252
#define MEMFAULT_REBOOT_INFO_VERSION 2

/* Ensure that the two fault frames match */
BUILD_ASSERT(sizeof(((struct arch_esf *)(NULL))->basic) ==
sizeof(((struct fault_exception_info_t *)(NULL))->EXC_FRAME_COPY));

#define ARCH_ESF_R0_IDX (offsetof(struct arch_esf, basic.r0) / sizeof(uint32_t))
#define ARCH_ESF_R1_IDX (offsetof(struct arch_esf, basic.r1) / sizeof(uint32_t))
#define ARCH_ESF_R2_IDX (offsetof(struct arch_esf, basic.r2) / sizeof(uint32_t))
#define ARCH_ESF_R3_IDX (offsetof(struct arch_esf, basic.r3) / sizeof(uint32_t))
#define ARCH_ESF_PC_IDX (offsetof(struct arch_esf, basic.pc) / sizeof(uint32_t))
#define ARCH_ESF_LR_IDX (offsetof(struct arch_esf, basic.lr) / sizeof(uint32_t))

BUILD_ASSERT(CONFIG_MEMFAULT_INIT_PRIORITY > CONFIG_INFUSE_COMMON_BOOT_INIT_PRIORITY,
"Memfault init must run after common_boot");

static void memfault_secure_fault_trace(struct k_work *work)
{
struct fault_exception_info_t fault_info;
uint8_t SFSR;

/* Pull the complete fault frame */
infuse_common_boot_secure_fault_info(&fault_info);

/* SFSR only has 8 bits of defined information */
SFSR = fault_info.SFSR;

/* Push additional fault information as a trace event */
memfault_trace_event_with_log_capture(
MEMFAULT_TRACE_REASON(secure_fault),
(void *)fault_info.EXC_FRAME_COPY[ARCH_ESF_PC_IDX],
(void *)fault_info.EXC_FRAME_COPY[ARCH_ESF_LR_IDX],
"R0-3 %08x %08x %08x %08x EXC %08x xPSR %08x SFSR %02x SFAR %08x",
fault_info.EXC_FRAME_COPY[ARCH_ESF_R0_IDX],
fault_info.EXC_FRAME_COPY[ARCH_ESF_R1_IDX],
fault_info.EXC_FRAME_COPY[ARCH_ESF_R2_IDX],
fault_info.EXC_FRAME_COPY[ARCH_ESF_R3_IDX], (uint32_t)fault_info.EXC_FRAME,
fault_info.xPSR, SFSR, fault_info.SFAR);
}

void memfault_reboot_tracking_load(sMemfaultRebootTrackingStorage *dst)
{
sMfltRebootInfo *reboot_info = (sMfltRebootInfo *)dst;
struct infuse_reboot_state infuse_reboot;
struct fault_exception_info_t fault_info;

if (infuse_common_boot_last_reboot(&infuse_reboot) != 0) {
/* No reboot knowledge, therefore no secure fault knowledge */
Expand All @@ -184,14 +220,12 @@ void memfault_reboot_tracking_load(sMemfaultRebootTrackingStorage *dst)
.lr = infuse_reboot.param_2.link_register,
};

/* Pull the complete fault frame */
infuse_common_boot_secure_fault_info(&fault_info);
/* Push additional fault information as a trace event */
memfault_trace_event_with_log_capture(
MEMFAULT_TRACE_REASON(secure_fault), (void *)infuse_reboot.param_1.program_counter,
(void *)infuse_reboot.param_2.link_register,
"EXC %08x xPSR %08x SFSR %08x SFAR %08x (%d)", (uint32_t)fault_info.EXC_FRAME,
fault_info.xPSR, fault_info.SFSR, fault_info.SFAR, !!fault_info.SFARVALID);
/* Defer logging of the secure fault trace event until after Memfault has finished
* initialising. Use a delayable worked since an immediate `k_work_submit` will just
* run the work before we have left the function.
*/
k_work_init_delayable(&secure_fault_trace, memfault_secure_fault_trace);
k_work_schedule(&secure_fault_trace, K_SECONDS(1));
}

#endif /* CONFIG_MEMFAULT_INFUSE_SECURE_FAULT_KNOWLEDGE */
Expand Down
12 changes: 4 additions & 8 deletions subsys/epacket/forwarding.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ static K_FIFO_DEFINE(packet_queue);
static const struct device *epacket_backhaul;
static struct conn_state forwarding_state[CONFIG_BT_MAX_CONN];

BUILD_ASSERT(CONFIG_BT_MAX_CONN <= 32, "rpc_disconnect_mask");

static void epacket_forward_direct(struct net_buf *buf)
{
struct epacket_forward_header *hdr =
Expand Down Expand Up @@ -248,6 +246,9 @@ bool bt_central_packet_received(struct net_buf *buf, bool decrypted, void *user_
return true;
}

INFUSE_WATCHDOG_REGISTER_SYS_INIT(forwarding_wdog, CONFIG_TASK_RUNNER_INFUSE_WATCHDOG, wdog_channel,
loop_period);

static void forward_auto_conn_processor(void *a, void *b, void *c)
{
const struct device *bt_central = DEVICE_DT_GET_ONE(embeint_epacket_bt_central);
Expand All @@ -261,8 +262,6 @@ static void forward_auto_conn_processor(void *a, void *b, void *c)
struct epacket_rx_metadata *meta;
struct net_buf *buf;
struct net_buf *tx;
k_timeout_t loop_period = K_FOREVER;
int wdog_channel;
int rc;

k_thread_name_set(NULL, "auto_conn_forward");
Expand All @@ -273,10 +272,7 @@ static void forward_auto_conn_processor(void *a, void *b, void *c)
bt_central_cb.packet_received = bt_central_packet_received;
epacket_register_callback(bt_central, &bt_central_cb);

/* Setup watchdog */
wdog_channel = IS_ENABLED(CONFIG_EPACKET_INFUSE_WATCHDOG)
? infuse_watchdog_install(&loop_period)
: -ENODEV;
/* Register watchdog */
infuse_watchdog_thread_register(wdog_channel, _current);

for (;;) {
Expand Down
8 changes: 8 additions & 0 deletions subsys/epacket/interfaces/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,14 @@ config EPACKET_INTERFACE_UDP_DOWNLINK_WATCHDOG_TIMEOUT
help
Watchdog period in seconds. Default value is 3 days (3 * 86400)

config EPACKET_INTERFACE_UDP_RX_BUFFER_CLAIM_TIMEOUT
int "Timeout duration to claim an ePacket receive buffer"
default 120
help
If this timeout expires, the device is rebooted. This is intended to be
an absolute last resort, other watchdogs should have picked up on blocked
threads by the time this expires.

module = EPACKET_UDP
module-str = epacket_udp
source "subsys/logging/Kconfig.template.log_config"
Expand Down
4 changes: 3 additions & 1 deletion subsys/epacket/interfaces/epacket_udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@

#define UDP_PAYLOAD(max_pkt) EPACKET_INTERFACE_PAYLOAD_FROM_PACKET(DT_DRV_INST(0), max_pkt)

#define CLAIM_TIMEOUT K_SECONDS(CONFIG_EPACKET_INTERFACE_UDP_RX_BUFFER_CLAIM_TIMEOUT)

enum {
UDP_STATE_L4_CONNECTED = BIT(0),
UDP_STATE_VALID_DNS = BIT(1),
Expand Down Expand Up @@ -268,7 +270,7 @@ static int epacket_udp_loop(void *a, void *b, void *c)
}

/* Allocate buffer and receive data */
buf = epacket_alloc_rx(K_SECONDS(30));
buf = epacket_alloc_rx(CLAIM_TIMEOUT);
if (buf == NULL) {
#ifdef CONFIG_INFUSE_REBOOT
/* Could not claim a RX buffer even with an excessive timeout */
Expand Down
4 changes: 3 additions & 1 deletion tests/lib/memfault/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -334,11 +334,13 @@ ZTEST(memfault_integration, test_epacket_dump)
zassert_equal(-ENOTCONN, rc);
/* Reset payload size */
epacket_dummy_set_max_packet(CONFIG_EPACKET_PACKET_SIZE_MAX);
/* Secure faults result in a trace event being logged just after boot */
k_sleep(K_MSEC(2000));
/* Dump all messages */
rc = infuse_memfault_queue_dump_all(K_NO_WAIT);
zassert_equal(0, rc);
/* Validate chunks are dumped (Reboot info should be small) */
expect_memfault_chunks(false, 10, 100);
expect_memfault_chunks(false, 200, 300);
break;
default:
zassert_unreachable("Unexpected reboot count");
Expand Down