Skip to content

Commit 24f2c26

Browse files
author
Memfault Inc
committed
Memfault Firmware SDK 0.27.0 (Build 325530)
1 parent 5e35eb8 commit 24f2c26

36 files changed

+870
-124
lines changed

CHANGES.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,26 @@
1+
### Changes between Memfault SDK 0.27.0 and SDK 0.26.1 - Oct 5, 2021
2+
3+
#### :chart_with_upwards_trend: Improvements
4+
5+
- Added support for using [compact logs](https://mflt.io/compact-logs) with the
6+
Memfault [log subsystem](https://mflt.io/logging).
7+
- Added port for mynewt RTOS to Memfault SDK. (Huge thanks to @t3zeng for the
8+
help here!) See
9+
[sdk/embedded/ports/mynewt](sdk/embedded/ports/mynewt/README.md) for more
10+
details.
11+
- Added support for
12+
[Zephyr 2.7](https://docs.zephyrproject.org/latest/releases/release-notes-2.7.html)
13+
release.
14+
15+
#### :house: Internal
16+
17+
- Fixed a missing symbol linker error for `memfault_fault_handler` that could
18+
arise when compiling with `-flto`.
19+
- Fixed a compiler error in `memfault_fault_handling_arm.c` that arose when
20+
using certain versions of the Clang compiler.
21+
- Cleaned up python scripts after enabling additional PEP8 naming convention
22+
linters.
23+
124
### Changes between Memfault SDK 0.26.1 and SDK 0.26.0 - Sept 20, 2021
225

326
#### :house: Internal

VERSION

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
BUILD ID: 314362
2-
GIT COMMIT: 8ea624d52
1+
BUILD ID: 325530
2+
GIT COMMIT: d622ced50

components/core/src/memfault_log.c

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "memfault/core/platform/overrides.h"
2525
#include "memfault/util/circular_buffer.h"
2626
#include "memfault/util/crc16_ccitt.h"
27+
#include "memfault/core/compact_log_serializer.h"
2728

2829
#include "memfault/config.h"
2930

@@ -93,12 +94,6 @@ bool memfault_log_get_regions(sMemfaultLogRegions *regions) {
9394
return true;
9495
}
9596

96-
typedef enum {
97-
kMemfaultLogRecordType_Preformatted = 0,
98-
99-
kMemfaultLogRecordType_NumTypes,
100-
} eMemfaultLogRecordType;
101-
10297
static uint8_t prv_build_header(eMemfaultPlatformLogLevel level, eMemfaultLogRecordType type) {
10398
MEMFAULT_STATIC_ASSERT(kMemfaultPlatformLogLevel_NumLevels <= 8,
10499
"Number of log levels exceed max number that log module can track");
@@ -223,6 +218,7 @@ static bool prv_read_log_iter_callback(sMfltLogIterator *iter) {
223218

224219
ctx->log->msg[iter->entry.len] = '\0';
225220
ctx->log->level = memfault_log_get_level_from_hdr(iter->entry.hdr);
221+
ctx->log->type = memfault_log_get_type_from_hdr(iter->entry.hdr);
226222
ctx->log->msg_len = iter->entry.len;
227223
ctx->has_log = true;
228224
return false;
@@ -234,6 +230,7 @@ static bool prv_read_log(sMemfaultLog *log) {
234230
const int rv = snprintf(log->msg, sizeof(log->msg), "... %d messages dropped ...",
235231
(int)s_memfault_ram_logger.dropped_msg_count);
236232
log->msg_len = (rv <= 0) ? 0 : MEMFAULT_MIN((uint32_t)rv, sizeof(log->msg) - 1);
233+
log->type = kMemfaultLogRecordType_Preformatted;
237234
s_memfault_ram_logger.dropped_msg_count = 0;
238235
return true;
239236
}
@@ -300,6 +297,7 @@ void memfault_vlog_save(eMemfaultPlatformLogLevel level, const char *fmt, va_lis
300297
if (bytes_written >= available_space) {
301298
bytes_written = available_space - 1;
302299
}
300+
303301
memfault_log_save_preformatted(level, log_buf, bytes_written);
304302
}
305303

@@ -310,8 +308,10 @@ void memfault_log_save(eMemfaultPlatformLogLevel level, const char *fmt, ...) {
310308
va_end(args);
311309
}
312310

313-
void memfault_log_save_preformatted(eMemfaultPlatformLogLevel level,
314-
const char *log, size_t log_len) {
311+
static void prv_log_save(eMemfaultPlatformLogLevel level,
312+
const void *log, size_t log_len,
313+
eMemfaultLogRecordType log_type) {
314+
315315
if (!prv_should_log(level)) {
316316
return;
317317
}
@@ -326,7 +326,7 @@ void memfault_log_save_preformatted(eMemfaultPlatformLogLevel level,
326326
if (space_free) {
327327
sMfltRamLogEntry entry = {
328328
.len = (uint8_t)truncated_log_len,
329-
.hdr = prv_build_header(level, kMemfaultLogRecordType_Preformatted),
329+
.hdr = prv_build_header(level, log_type),
330330
};
331331
memfault_circular_buffer_write(circ_bufp, &entry, sizeof(entry));
332332
memfault_circular_buffer_write(circ_bufp, log, truncated_log_len);
@@ -340,6 +340,41 @@ void memfault_log_save_preformatted(eMemfaultPlatformLogLevel level,
340340
}
341341
}
342342

343+
#if MEMFAULT_COMPACT_LOG_ENABLE
344+
345+
static void prv_fill_compact_log_cb(void *ctx, uint32_t offset, const void *buf, size_t buf_len) {
346+
uint8_t *log = (uint8_t *)ctx;
347+
memcpy(&log[offset], buf, buf_len);
348+
}
349+
350+
void memfault_compact_log_save(eMemfaultPlatformLogLevel level, uint32_t log_id,
351+
uint32_t compressed_fmt, ...) {
352+
char log_buf[MEMFAULT_LOG_MAX_LINE_SAVE_LEN + 1];
353+
354+
sMemfaultCborEncoder encoder;
355+
memfault_cbor_encoder_init(&encoder, prv_fill_compact_log_cb, log_buf, sizeof(log_buf));
356+
357+
va_list args;
358+
va_start(args, compressed_fmt);
359+
bool success = memfault_vlog_compact_serialize(&encoder, log_id, compressed_fmt, args);
360+
va_end(args);
361+
362+
if (!success) {
363+
return;
364+
}
365+
366+
const size_t bytes_written = memfault_cbor_encoder_deinit(&encoder);
367+
prv_log_save(level, log_buf, bytes_written, kMemfaultLogRecordType_Compact);
368+
}
369+
370+
#endif /* MEMFAULT_COMPACT_LOG_ENABLE */
371+
372+
373+
void memfault_log_save_preformatted(eMemfaultPlatformLogLevel level,
374+
const char *log, size_t log_len) {
375+
prv_log_save(level, log, log_len, kMemfaultLogRecordType_Preformatted);
376+
}
377+
343378
bool memfault_log_boot(void *storage_buffer, size_t buffer_len) {
344379
if (storage_buffer == NULL || buffer_len == 0 || s_memfault_ram_logger.enabled) {
345380
return false;

components/core/src/memfault_log_data_source.c

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,15 +96,29 @@ typedef struct {
9696
static bool prv_copy_msg_callback(sMfltLogIterator *iter, MEMFAULT_UNUSED size_t offset,
9797
const char *buf, size_t buf_len) {
9898
sMfltLogEncodingCtx *const ctx = (sMfltLogEncodingCtx *)iter->user_ctx;
99-
return memfault_cbor_encode_string_add(&ctx->encoder, buf, buf_len);
99+
return memfault_cbor_join(&ctx->encoder, buf, buf_len);
100100
}
101101

102102
static bool prv_encode_current_log(sMemfaultCborEncoder *encoder, sMfltLogIterator *iter) {
103-
return (
104-
memfault_cbor_encode_unsigned_integer(encoder, memfault_log_get_level_from_hdr(iter->entry.hdr)) &&
105-
memfault_cbor_encode_string_begin(encoder, iter->entry.len) &&
106-
memfault_log_iter_copy_msg(iter, prv_copy_msg_callback)
107-
);
103+
104+
if (!memfault_cbor_encode_unsigned_integer(encoder,
105+
memfault_log_get_level_from_hdr(iter->entry.hdr))) {
106+
return false;
107+
}
108+
109+
eMemfaultLogRecordType type = memfault_log_get_type_from_hdr(iter->entry.hdr);
110+
bool success;
111+
112+
// Note: We encode "preformatted" logs (i.e logs that have run through printf) as cbor text
113+
// string and "compact" logs as a cbor byte array so we can differentiate between the two while
114+
// decoding
115+
if (type == kMemfaultLogRecordType_Preformatted) {
116+
success = memfault_cbor_encode_string_begin(encoder, iter->entry.len);
117+
} else { // kMemfaultLogRecordType_Compact
118+
success = memfault_cbor_encode_byte_string_begin(encoder, iter->entry.len);
119+
}
120+
121+
return (success && memfault_log_iter_copy_msg(iter, prv_copy_msg_callback));
108122
}
109123

110124
static bool prv_log_iterate_encode_callback(sMfltLogIterator *iter) {

components/core/src/memfault_log_private.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <stdint.h>
1616

1717
#include "memfault/core/compiler.h"
18+
#include "memfault/core/log.h"
1819
#include "memfault/core/platform/debug_log.h"
1920

2021
#ifdef __cplusplus
@@ -31,7 +32,7 @@ extern "C" {
3132
// r = read (1 if the message has been read, 0 otherwise)
3233
// s = sent (1 if the message has been sent, 0 otherwise)
3334
// x = rsvd
34-
// t = type (0 = formatted log)
35+
// t = type (0 = formatted log, 1 = compact log)
3536
// l = log level (eMemfaultPlatformLogLevel)
3637

3738
#define MEMFAULT_LOG_HDR_LEVEL_POS 0
@@ -45,6 +46,10 @@ static inline eMemfaultPlatformLogLevel memfault_log_get_level_from_hdr(uint8_t
4546
return (eMemfaultPlatformLogLevel)((hdr & MEMFAULT_LOG_HDR_LEVEL_MASK) >> MEMFAULT_LOG_HDR_LEVEL_POS);
4647
}
4748

49+
static inline eMemfaultLogRecordType memfault_log_get_type_from_hdr(uint8_t hdr) {
50+
return (eMemfaultLogRecordType)((hdr & MEMFAULT_LOG_HDR_TYPE_MASK) >> MEMFAULT_LOG_HDR_TYPE_POS);
51+
}
52+
4853
typedef MEMFAULT_PACKED_STRUCT {
4954
// data about the message stored (details below)
5055
uint8_t hdr;

components/include/memfault/core/log.h

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,11 @@
2424
#include <stddef.h>
2525
#include <stdint.h>
2626

27+
#include "memfault/config.h"
28+
#include "memfault/core/compact_log_compile_time_checks.h"
29+
#include "memfault/core/compact_log_helpers.h"
2730
#include "memfault/core/compiler.h"
28-
#include "memfault/core/platform/debug_log.h" // For eMemfaultPlatformLogLevel
31+
#include "memfault/core/platform/debug_log.h" // For eMemfaultPlatformLogLevel
2932

3033
#ifdef __cplusplus
3134
extern "C" {
@@ -65,6 +68,30 @@ void memfault_log_set_min_save_level(eMemfaultPlatformLogLevel min_log_level);
6568
//! } while (0)
6669
#define MEMFAULT_LOG_SAVE(_level, ...) memfault_log_save(_level, __VA_ARGS__)
6770

71+
#if MEMFAULT_COMPACT_LOG_ENABLE
72+
73+
//! Same as MEMFAULT_LOG_SAVE except logs use Memfault's "compact" log strategy which offloads
74+
//! formatting to the Memfault cloud to reduce on device codespace and cpu consumption. See
75+
//! https://mflt.io/compact-logs for more details.
76+
#define MEMFAULT_COMPACT_LOG_SAVE(level, format, ...) \
77+
do { \
78+
MEMFAULT_LOGGING_RUN_COMPILE_TIME_CHECKS(format, ## __VA_ARGS__); \
79+
MEMFAULT_LOG_FMT_ELF_SECTION_ENTRY(format, ## __VA_ARGS__); \
80+
memfault_compact_log_save(level, \
81+
MEMFAULT_LOG_FMT_ELF_SECTION_ENTRY_PTR, \
82+
MFLT_GET_COMPRESSED_LOG_FMT(__VA_ARGS__), \
83+
## __VA_ARGS__); \
84+
} while (0)
85+
86+
87+
//! Serializes the provided compact log and saves it to backing storage
88+
//!
89+
//! @note: Should only be called via MEMFAULT_COMPACT_LOG_SAVE macro
90+
void memfault_compact_log_save(eMemfaultPlatformLogLevel level, uint32_t log_id,
91+
uint32_t compressed_fmt, ...);
92+
93+
#endif /* MEMFAULT_COMPACT_LOG_ENABLE */
94+
6895
//! Function which can be called to save a log after it has been formatted
6996
//!
7097
//! Typically a user should be able to use the MEMFAULT_LOG_SAVE macro but if your platform does
@@ -81,15 +108,22 @@ void memfault_log_set_min_save_level(eMemfaultPlatformLogLevel min_log_level);
81108
void memfault_log_save_preformatted(eMemfaultPlatformLogLevel level, const char *log,
82109
size_t log_len);
83110

84-
//! Maximum length a log record can occupy
85-
#define MEMFAULT_LOG_MAX_LINE_SAVE_LEN 128
111+
typedef enum {
112+
kMemfaultLogRecordType_Preformatted = 0,
113+
kMemfaultLogRecordType_Compact = 1,
114+
kMemfaultLogRecordType_NumTypes,
115+
} eMemfaultLogRecordType;
86116

87117
typedef struct {
88118
// the level of the message
89119
eMemfaultPlatformLogLevel level;
120+
// the log returned is a binary "compact log"
121+
// See https://mflt.io/compact-logs for more details
122+
eMemfaultLogRecordType type;
90123
// the length of the msg (not including NUL character)
91124
uint32_t msg_len;
92-
// the message to print which will always be NUL terminated
125+
// the message to print which will always be NUL terminated when a preformatted log is returned
126+
// (so it is always safe to call printf without copying the log into another buffer yourself)
93127
char msg[MEMFAULT_LOG_MAX_LINE_SAVE_LEN + 1 /* '\0' */];
94128
} sMemfaultLog;
95129

@@ -116,7 +150,7 @@ typedef struct {
116150
//! // .. RTOS code to wait for log read event ..
117151
//! sMemfaultLog log = { 0 };
118152
//! const bool log_found = memfault_log_read(&log);
119-
//! if (log_found) {
153+
//! if (log_found && (log.type == kMemfaultLogRecordType_Preformatted)) {
120154
//! my_platform_uart_println(log.level, log, log.msg_len);
121155
//! }
122156
bool memfault_log_read(sMemfaultLog *log);

components/include/memfault/default_config.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,15 @@ extern "C" {
9494
#define MEMFAULT_LOG_DATA_SOURCE_ENABLED 1
9595
#endif
9696

97-
// Shouldn't typically be needed but allows for persisting of MEMFAULT_LOG_*'s
98-
// to be disabled via a CFLAG: CFLAGS += -DMEMFAULT_SDK_LOG_SAVE_DISABLE=1
97+
//! Maximum length a log record can occupy
98+
//!
99+
//! Structs holding this log may be allocated on the stack so care should be taken
100+
//! to make the size is not to large to blow through the allocated space for the stack.
101+
#ifndef MEMFAULT_LOG_MAX_LINE_SAVE_LEN
102+
#define MEMFAULT_LOG_MAX_LINE_SAVE_LEN 128
103+
#endif
104+
105+
//! Control whether or automatic persisting of MEMFAULT_LOG_*'s is enabled
99106
#ifndef MEMFAULT_SDK_LOG_SAVE_DISABLE
100107
#define MEMFAULT_SDK_LOG_SAVE_DISABLE 0
101108
#endif

components/include/memfault/util/cbor.h

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -123,24 +123,20 @@ bool memfault_cbor_encode_string(sMemfaultCborEncoder *encoder, const char *str)
123123
//!
124124
//! @return true on success, false otherwise
125125
//!
126-
//! @note Use one or more calls to memfault_cbor_encode_string_add() to write the contents
126+
//! @note Use one or more calls to memfault_cbor_join() to write the contents
127127
//! of the string.
128128
bool memfault_cbor_encode_string_begin(sMemfaultCborEncoder *encoder, size_t str_len);
129129

130-
//! Called to encode the given C string to the string started with
131-
//! memfault_cbor_encode_string_begin().
132-
//!
133-
//! @note Can be called one or multiple times after calling memfault_cbor_encode_string_begin().
134-
//! It is the responsibililty of the caller to ensure that the total number of bytes added matches
135-
//! the str_len that was passed to memfault_cbor_encode_string_begin().
136-
//! @note It is not expected to add the NULL terminator.
130+
//! Called to start the encoding of an arbitrary binary payload
137131
//!
138132
//! @param encoder The encoder context to use
139-
//! @param str The string to add
140-
//! @param len The number of bytes to add from str
133+
//! @param buf_len The length of the binary payload to store in bytes, excluding NULL terminator.
141134
//!
142135
//! @return true on success, false otherwise
143-
bool memfault_cbor_encode_string_add(sMemfaultCborEncoder *encoder, const char *str, size_t len);
136+
//!
137+
//! @note Use one or more calls to memfault_cbor_join() to write the contents
138+
//! of the string.
139+
bool memfault_cbor_encode_byte_string_begin(sMemfaultCborEncoder *encoder, size_t bin_len);
144140

145141
//! Encodes a IEEE 754 double-precision float that is packed in a uint64_t
146142
//!

components/include/memfault/version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ typedef struct {
1919
uint8_t patch;
2020
} sMfltSdkVersion;
2121

22-
#define MEMFAULT_SDK_VERSION { .major = 0, .minor = 26, .patch = 1 }
22+
#define MEMFAULT_SDK_VERSION { .major = 0, .minor = 27, .patch = 0 }
2323

2424
#ifdef __cplusplus
2525
}

components/panics/src/memfault_fault_handling_arm.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ void memfault_platform_fault_handler(MEMFAULT_UNUSED const sMfltRegState *regs,
109109
}
110110
#endif /* MEMFAULT_PLATFORM_FAULT_HANDLER_CUSTOM */
111111

112+
MEMFAULT_USED
112113
void memfault_fault_handler(const sMfltRegState *regs, eMemfaultRebootReason reason) {
113114
memfault_platform_fault_handler(regs, reason);
114115

@@ -365,10 +366,10 @@ void MEMFAULT_EXC_HANDLER_WATCHDOG(void) {
365366
"mrsne r3, psp \n" \
366367
"push {r3-r11, lr} \n" \
367368
"mov r0, sp \n" \
368-
"ldr r1, =%0 \n" \
369+
"ldr r1, =%c0 \n" \
369370
"b memfault_fault_handler \n" \
370371
: \
371-
: "i" (_x) \
372+
: "i" ((uint16_t)_x) \
372373
)
373374
#else
374375
#define MEMFAULT_HARDFAULT_HANDLING_ASM(_x) \

0 commit comments

Comments
 (0)