Skip to content

Commit 0901fbb

Browse files
author
Memfault Inc
committed
Memfault Firmware SDK 1.10.1 (Build 9081)
1 parent a4711bc commit 0901fbb

20 files changed

+294
-215
lines changed

CHANGELOG.md

Lines changed: 111 additions & 82 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1+
# Memfault Firmware SDK
2+
13
[![CircleCI](https://circleci.com/gh/memfault/memfault-firmware-sdk.svg?style=svg)](https://circleci.com/gh/memfault/memfault-firmware-sdk)
24
[![Coverage](https://img.shields.io/codecov/c/gh/memfault/memfault-firmware-sdk/master)](https://codecov.io/gh/memfault/memfault-firmware-sdk/)
35

4-
# Memfault Firmware SDK
5-
66
Ship Firmware with Confidence.
77

88
More details about the Memfault platform itself, how it works, and step-by-step
99
integration guides
1010
[can be found here](https://mflt.io/embedded-getting-started).
1111

12-
# Getting Started
12+
## Getting Started
1313

1414
To start integrating in your platform today,
1515
[create a Memfault cloud account](https://mflt.io/signup).
1616

17-
# Components
17+
## Components
1818

1919
The SDK is designed as a collection of components, so you can include only what
2020
is needed for your project. The SDK has been designed to have minimal impact on
@@ -53,14 +53,14 @@ Please refer to the `README.md` in each of these for more details.
5353
Memfault service from devices.
5454
- `util` – various utilities.
5555

56-
# Integrating the Memfault SDK
56+
## Integrating the Memfault SDK
5757

5858
## Add Memfault SDK to Your Repository
5959

6060
The Memfault SDK can be added directly into your repository. The structure
6161
typically looks like:
6262

63-
```
63+
```bash
6464
<YOUR_PROJECT>
6565
├── third_party/memfault
6666
│ ├── memfault-firmware-sdk (submodule)
@@ -79,8 +79,8 @@ typically looks like:
7979
If you are using `git`, the Memfault SDK is typically added to a project as a
8080
submodule:
8181

82-
```
83-
$ git submodule add https://github.com/memfault/memfault-firmware-sdk.git $YOUR_PROJECT/third_party/memfault/memfault-firmware-sdk
82+
```bash
83+
git submodule add https://github.com/memfault/memfault-firmware-sdk.git $YOUR_PROJECT/third_party/memfault/memfault-firmware-sdk
8484
```
8585

8686
This makes it easy to track the history of the Memfault SDK. You should not need
@@ -147,7 +147,7 @@ out
147147
The unit tests are run by CircleCI upon every commit to this repo. See badges at
148148
the top for build & test coverage status of the `master` branch.
149149
150-
# FAQ
150+
## FAQ
151151
152152
- Why does a coredump not show up under "Issues" after uploading it?
153153
@@ -163,7 +163,7 @@ the top for build & test coverage status of the `master` branch.
163163
- Don't hesitate to contact us for help! You can reach us through
164164
<https://mflt.io/contact-support>.
165165
166-
# License
166+
## License
167167
168168
Unless specifically indicated otherwise in a file, all memfault-firmware-sdk
169169
files are all licensed under the [Memfault License](/License.txt). (A few files

VERSION

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
BUILD ID: 8899
2-
GIT COMMIT: 7e534eec9c
3-
VERSION: 1.10.0
1+
BUILD ID: 9081
2+
GIT COMMIT: 5183b73f74
3+
VERSION: 1.10.1

components/core/src/memfault_self_test.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -336,9 +336,9 @@ MEMFAULT_NO_OPT static uint32_t prv_get_time_since_boot_test(void) {
336336

337337
uint64_t end_time_ms = memfault_platform_get_time_since_boot_ms();
338338
if ((end_time_ms <= start_time_ms)) {
339-
MEMFAULT_LOG_ERROR("Time since boot not monotonically increasing: start[%" PRIu64
340-
"] vs end[%" PRIu64 "]",
341-
start_time_ms, end_time_ms);
339+
MEMFAULT_LOG_ERROR("Time since boot not monotonically increasing: start[%" PRIu32
340+
"] vs end[%" PRIu32 "]",
341+
(uint32_t)start_time_ms, (uint32_t)end_time_ms);
342342
return (1 << 1);
343343
}
344344

@@ -369,12 +369,13 @@ static uint32_t prv_platform_time_get_current_test(void) {
369369
}
370370

371371
if (time.info.unix_timestamp_secs < MEMFAULT_SELF_TEST_TIMESTAMP_ANCHOR) {
372-
MEMFAULT_LOG_ERROR("Timestamp too far in the past: %" PRIu64, time.info.unix_timestamp_secs);
372+
MEMFAULT_LOG_ERROR("Timestamp too far in the past: %" PRIu32,
373+
(uint32_t)time.info.unix_timestamp_secs);
373374
return (1 << 4);
374375
}
375376

376-
MEMFAULT_LOG_INFO("Verify received timestamp for accuracy. Timestamp received %" PRIu64,
377-
time.info.unix_timestamp_secs);
377+
MEMFAULT_LOG_INFO("Verify received timestamp for accuracy. Timestamp received %" PRIu32,
378+
(uint32_t)time.info.unix_timestamp_secs);
378379
return 0;
379380
}
380381

@@ -390,9 +391,16 @@ uint32_t memfault_self_test_time_test(void) {
390391

391392
uint32_t memfault_self_test_coredump_storage_capacity_test(void) {
392393
MEMFAULT_SELF_TEST_PRINT_HEADER("Coredump Storage Capacity Test");
393-
bool result = memfault_coredump_storage_check_size();
394+
bool capacity_ok = memfault_coredump_storage_check_size();
395+
if (capacity_ok) {
396+
size_t total_size = 0;
397+
size_t capacity = 0;
398+
memfault_coredump_size_and_storage_capacity(&total_size, &capacity);
399+
MEMFAULT_LOG_INFO("Total size required: %u bytes", (unsigned)total_size);
400+
MEMFAULT_LOG_INFO("Storage capacity: %u bytes", (unsigned)capacity);
401+
}
394402
MEMFAULT_LOG_INFO(MEMFAULT_SELF_TEST_END_OUTPUT);
395-
return result ? 0 : 1;
403+
return capacity_ok ? 0 : 1;
396404
}
397405

398406
uint32_t memfault_self_test_coredump_storage_test(void) {

components/include/memfault/panics/arch/arm/v7_a_r.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
extern "C" {
1818
#endif
1919

20-
//! Register State collected for ARMv7-R when a fault occurs. Non-arch-specific
20+
//! Register State collected for ARMv7-A/R when a fault occurs. Non-arch-specific
2121
//! name for the struct type- this type is used when defining the coredump
2222
//! header layout.
2323
MEMFAULT_PACKED_STRUCT MfltRegState {

components/include/memfault/version.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ typedef struct {
1919
uint8_t patch;
2020
} sMfltSdkVersion;
2121

22-
#define MEMFAULT_SDK_VERSION { .major = 1, .minor = 10, .patch = 0 }
23-
#define MEMFAULT_SDK_VERSION_STR "1.10.0"
22+
#define MEMFAULT_SDK_VERSION { .major = 1, .minor = 10, .patch = 1 }
23+
#define MEMFAULT_SDK_VERSION_STR "1.10.1"
2424

2525
#ifdef __cplusplus
2626
}

components/panics/src/memfault_fault_handling_armv7_a_r.c

Lines changed: 46 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,6 @@
99
#include "memfault/core/compiler.h"
1010

1111
#if MEMFAULT_COMPILER_ARM_V7_A_R
12-
13-
//! Only ARMv7-R is officially supported, notify the user if compiling for
14-
//! ARMv7-A
15-
#if defined(__ARM_ARCH_7A__)
16-
#pragma message \
17-
"ARMv7-A is not officially supported yet by Memfault. Please contact [email protected] with questions!"
18-
#endif
19-
2012
#include "memfault/components.h"
2113
#include "memfault/panics/arch/arm/v7_a_r.h"
2214
#include "memfault/panics/coredump_impl.h"
@@ -43,27 +35,6 @@ extern void MEMFAULT_EXC_HANDLER_PREFETCH_ABORT(void);
4335

4436
static eMemfaultRebootReason s_crash_reason = kMfltRebootReason_Unknown;
4537

46-
//! These are the regs pushed by the exception wrapper, which are transcribed
47-
//! into 'struct MfltRegState' for the coredump.
48-
MEMFAULT_PACKED_STRUCT ExceptionPushedRegs {
49-
uint32_t r0;
50-
uint32_t r1;
51-
uint32_t r2;
52-
uint32_t r3;
53-
uint32_t r4;
54-
uint32_t r5;
55-
uint32_t r6;
56-
uint32_t r7;
57-
uint32_t r8;
58-
uint32_t r9;
59-
uint32_t r10;
60-
uint32_t r11;
61-
uint32_t r12;
62-
uint32_t sp; // R13
63-
uint32_t lr; // R14
64-
uint32_t cpsr;
65-
};
66-
6738
const sMfltCoredumpRegion *memfault_coredump_get_arch_regions(size_t *num_regions) {
6839
*num_regions = 0;
6940
return NULL;
@@ -247,6 +218,17 @@ MEMFAULT_USED void memfault_fault_handler(const sMfltRegState *regs, eMemfaultRe
247218
// We push callee r0-r12, lr, pc, and cpsr onto the stack, then pass the stack
248219
// pointer to the C memfault_fault_handler.
249220
//
221+
// Note that r0-r7 are shared across all execution modes, and r8-r12 are
222+
// shared in all modes except for FIQ.
223+
//
224+
// We need to ensure that we enter SYS MODE rather than USER MODE, so we
225+
// perform a check and mask if the fault occurred in USER mode.
226+
//
227+
// In order to preserve the layout of `MfltRegState` and ensure that we don't
228+
// clobber any registers, pushing to the stack to the stack is done out of
229+
// order, moving the stack pointer around manually to ensure ordering is
230+
// consistent.
231+
//
250232
// Here's a worked example of the position the registers are saved on the stack:
251233
//
252234
// sp = 128 <- starting example stack pointer value
@@ -256,16 +238,10 @@ MEMFAULT_USED void memfault_fault_handler(const sMfltRegState *regs, eMemfaultRe
256238
// cpsr @ 124
257239
// pc @ 120
258240
//
259-
// // Now push user mode r8-r12, sp, lr, by first switching to user mode
260-
// lr @ 116
261-
// sp @ 112
262-
// r12 @ 108
263-
// r11 @ 104
264-
// r10 @ 100
265-
// r9 @ 96
266-
// r8 @ 92
241+
// // Now, create a hole for the user mode registers.
242+
// sp -> 92
267243
//
268-
// // Now switch back to exception mode, save r0-r7 to the stack
244+
// // Now push r0-r7 to the stack
269245
// r7 @ 88
270246
// r6 @ 84
271247
// r5 @ 80
@@ -274,43 +250,39 @@ MEMFAULT_USED void memfault_fault_handler(const sMfltRegState *regs, eMemfaultRe
274250
// r2 @ 68
275251
// r1 @ 64
276252
// r0 @ 60 <- this is the struct address we pass to memfault_fault_handler
277-
253+
//
254+
// // Now enter user mode, with r2 address @ 120 (the hole we made earlier)
255+
// // Now push user mode r8-r12, sp, lr, using r2 as the stack pointer
256+
// lr @ 116
257+
// sp @ 112
258+
// r12 @ 108
259+
// r11 @ 104
260+
// r10 @ 100
261+
// r9 @ 96
262+
// r8 @ 92
263+
//
264+
// // Now switch back to exception mode, set up args in r0 & r1, and call the
265+
// // fault handler.
278266
#define MEMFAULT_FAULT_HANDLING_ASM(_mode_string, _reason) \
279-
__asm volatile( /* assemble in ARM mode so we can copy sp with a stm instruction */ \
280-
".arm \n" /* save callee pc (exception handler adjusted lr) + spsr (callee \
281-
cpsr) of the current mode */ \
282-
"srsdb sp!, #" _mode_string \
283-
" \n" /* push user mode regs at point of fault, including sp + lr */ \
284-
"mov r8, r1 \n" \
285-
"mov r1, sp \n" /* Save SPSR and mask mode bits */ \
286-
"mrs r9, spsr \n" \
287-
"and r9, #0x1f \n" /* Check each applicable mode and set current mode on a \
288-
match */ \
289-
"cmp r9, #" CPU_MODE_IRQ_STR " \n" \
290-
"bne fiq_mode_%= \n" \
291-
"cps #" CPU_MODE_IRQ_STR " \n" \
292-
"b store_regs_%= \n" \
293-
"fiq_mode_%=: \n" \
294-
"cmp r9, #" CPU_MODE_FIQ_STR " \n" \
295-
"bne supervisor_mode_%= \n" \
296-
"cps #" CPU_MODE_FIQ_STR " \n" \
297-
"b store_regs_%= \n" \
298-
"supervisor_mode_%=: \n" \
299-
"cmp r9, #" CPU_MODE_SUPERVISOR_STR " \n" \
300-
"bne system_mode_%= \n" \
301-
"cps #" CPU_MODE_SUPERVISOR_STR " \n" \
302-
"b store_regs_%= \n" /* Fall back to system mode if no match */ \
303-
"system_mode_%=: \n" \
304-
"cps #" CPU_MODE_SYSTEM_STR " \n" \
305-
"store_regs_%=: \n" \
306-
"stmfd r1!, {r8-r12, sp, lr} \n" \
307-
"cps #" _mode_string " \n" /* save active registers in exception frame */ \
308-
"mov sp, r1 \n" \
309-
"mov r1, r8 \n" \
310-
"stmfd sp!, {r0-r7} \n" /* load the pushed frame and reason into r0+r1 for \
311-
the handler args */ \
312-
"mov r0, sp \n" \
313-
"ldr r1, =%c0 \n" \
267+
__asm volatile(".arm \n" /* assemble in ARM mode so we can copy sp with a stm instruction */ \
268+
\
269+
"srsdb sp!, #" _mode_string " \n" /* Push PC + CPSR of previous mode */ \
270+
"sub sp, sp, #28 \n" /* Want r0-r7 after r8 - r14, make space */ \
271+
"stmfd sp!, {r0-r7} \n" /* Push r0-r7, shared amongst all modes */ \
272+
"add r2, sp, #60 \n" /* r2 for previous mode to push r8-r14 */ \
273+
\
274+
"mrs r3, cpsr \n" /* r3: CPSR to return to exception mode */ \
275+
"mrs r4, spsr \n" /* Get the previous mode CPSR */ \
276+
"tst r4, #0xf \n" /* Set Z Flag if in USR mode */ \
277+
"orreq r4, r4, #0xf \n" /* r4: Previous mode changed to SYS if was USR */ \
278+
\
279+
"msr CPSR_c, r4 \n" /* Enter the previous mode */ \
280+
"stmfd r2!, {r8-r12, sp, lr} \n" /* Push all banked registers */ \
281+
\
282+
"msr CPSR_cxsf, r3 \n" /* Back to our exception mode */ \
283+
\
284+
"mov r0, sp \n" /* arg0 = sp */ \
285+
"ldr r1, =%c0 \n" /* arg1 = reason */ \
314286
"b memfault_fault_handler \n" \
315287
: \
316288
: "i"((uint16_t)_reason))

examples/freertos/src/memfault/memfault_platform_port.c

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
//! See License.txt for details
55

66
#include <stdio.h>
7+
#include <time.h>
78

89
#include "memfault/components.h"
910
#include "memfault/ports/freertos.h"
1011
#include "memfault/ports/reboot_reason.h"
11-
1212
// Buffer used to store formatted string for output
1313
#define MEMFAULT_DEBUG_LOG_BUFFER_SIZE_BYTES (MEMFAULT_DATA_EXPORT_BASE64_CHUNK_MAX_LEN)
1414

@@ -74,6 +74,32 @@ void memfault_platform_log_raw(const char *fmt, ...) {
7474
va_end(args);
7575
}
7676

77+
bool memfault_platform_time_get_current(sMemfaultCurrentTime *time_output) {
78+
// Get time from time.h
79+
80+
// Debug: print time fields
81+
time_t time_now = time(NULL);
82+
83+
struct tm *tm_time = gmtime(&time_now);
84+
MEMFAULT_LOG_DEBUG("Time: %u-%u-%u %u:%u:%u", tm_time->tm_year + 1900, tm_time->tm_mon + 1,
85+
tm_time->tm_mday, tm_time->tm_hour, tm_time->tm_min, tm_time->tm_sec);
86+
87+
// If pre-2023, something is wrong
88+
if ((tm_time->tm_year < 123) || (tm_time->tm_year > 200)) {
89+
MEMFAULT_LOG_WARN("Time doesn't make sense: year %u", tm_time->tm_year + 1900);
90+
return false;
91+
}
92+
93+
// load the timestamp and return true for a valid timestamp
94+
*time_output = (sMemfaultCurrentTime){
95+
.type = kMemfaultCurrentTimeType_UnixEpochTimeSec,
96+
.info = {
97+
.unix_timestamp_secs = (uint64_t)time_now,
98+
},
99+
};
100+
return true;
101+
}
102+
77103
void memfault_platform_reboot_tracking_boot(void) {
78104
sResetBootupInfo reset_info = { 0 };
79105
memfault_reboot_reason_get(&reset_info);

examples/zephyr/stm32l4_disco/apps/memfault_demo_app/prj.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,4 @@ CONFIG_HEAP_MEM_POOL_SIZE=1024
8686
# Currently not supported on older Zephyr, so explicitly disable until this
8787
# sample is updated
8888
CONFIG_MEMFAULT_METRICS_CPU_TEMP=n
89+
CONFIG_MEMFAULT_DTS_IN_ELF=n

0 commit comments

Comments
 (0)