Skip to content

Commit 920a1ee

Browse files
author
Memfault Inc
committed
Memfault Firmware SDK 0.42.1 (Build 1866)
1 parent 0d7e773 commit 920a1ee

22 files changed

+307
-60
lines changed

CHANGES.md

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
1+
### Changes between Memfault SDK 0.42.1 and 0.42.0 - April 4, 2023
2+
3+
#### :chart_with_upwards_trend: Improvements
4+
5+
- Zephyr:
6+
7+
- Remove `LEGACY_CONFIG_PATH` Kconfig selection, now that the `zephyr.h`
8+
header is no longer used as of Memfault SDK `0.42.0`. This option no longer
9+
exists after Zephyr v3.3.0. Fixes
10+
[#48](https://github.com/memfault/memfault-firmware-sdk/issues/48)
11+
12+
- Minor changes to the [ESP8266 port](ports/esp8266_sdk) to improve
13+
out-of-the-box compilation
14+
- Add new functionality to output buffered log data via
15+
`memfault_log_export_logs()`. See the
16+
[`log.h` header](components/include/memfault/core/log.h) for detailed usage.
17+
118
### Changes between Memfault SDK 0.42.0 and 0.41.2 - Mar 22, 2023
219

320
#### :chart_with_upwards_trend: Improvements
@@ -7,7 +24,8 @@
724
- Add option to capture full thread stacks for classifying stack overflows and
825
determining stack high watermarks. This feature is enabled by setting
926
`CONFIG_MEMFAULT_COREDUMP_FULL_THREAD_STACKS=y`
10-
- Remove usage of the `zephyr.h` header in preparation for Zephyr v3.4.0
27+
- Remove usage of the `zephyr.h` header in preparation for Zephyr v3.4.0.
28+
Thanks to @jfischer-no for the patch!
1129

1230
- `memfault_gdb.py`:
1331
- Add support for exporting data from GCC 12 compiled symbol files
@@ -32,8 +50,9 @@
3250
- Zephyr / nRF-Connect SDK:
3351
- Improve compatibility with Zephyr pre-3.0 deferred logging, when using the
3452
Memfault backend
35-
- Add an option to the [examples/nrf-connect/nrf5](examples/nrf-connect/nrf5)
36-
to enable capturing all of RAM in a coredump.
53+
- Add an option to the
54+
[examples/nrf-connect-sdk/nrf5](examples/nrf-connect-sdk/nrf5) to enable
55+
capturing all of RAM in a coredump.
3756

3857
### Changes between Memfault SDK 0.41.1 and SDK 0.41.0 - Mar 1, 2023
3958

VERSION

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
BUILD ID: 1778
2-
GIT COMMIT: 539b8ab42
1+
BUILD ID: 1866
2+
GIT COMMIT: 96e2f7fa4

components/core/src/memfault_batched_events.c

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,6 @@
1111
#include "memfault/core/sdk_assert.h"
1212
#include "memfault/util/cbor.h"
1313

14-
15-
static void prv_fill_header_cb(void *ctx, uint32_t offset, const void *buf, size_t buf_len) {
16-
uint8_t *header_buf = (uint8_t *)ctx;
17-
memcpy(&header_buf[offset], buf, buf_len);
18-
}
19-
2014
void memfault_batched_events_build_header(
2115
size_t num_events, sMemfaultBatchedEventsHeader *header_out) {
2216
MEMFAULT_SDK_ASSERT(header_out != NULL);
@@ -28,7 +22,7 @@ void memfault_batched_events_build_header(
2822

2923
// there's multiple events to read. We will add a header to indicate the total count
3024
sMemfaultCborEncoder encoder;
31-
memfault_cbor_encoder_init(&encoder, prv_fill_header_cb, header_out->data,
25+
memfault_cbor_encoder_init(&encoder, memfault_cbor_encoder_memcpy_write, header_out->data,
3226
sizeof(header_out->data));
3327
memfault_cbor_encode_array_begin(&encoder, num_events);
3428
header_out->length = memfault_cbor_encoder_deinit(&encoder);

components/core/src/memfault_custom_data_recording.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,6 @@ static void prv_try_get_cdr_source_with_data(sMfltCdrSourceCtx *ctx) {
114114
}
115115
}
116116

117-
static void prv_fill_header_cb(void *ctx, uint32_t offset, const void *buf, size_t buf_len) {
118-
uint8_t *header_buf = (uint8_t *)ctx;
119-
memcpy(&header_buf[offset], buf, buf_len);
120-
}
121-
122117
static bool prv_has_cdr(size_t *total_size) {
123118
sMfltCdrSourceCtx *cdr_ctx = &s_memfault_cdr_source_ctx;
124119

@@ -128,7 +123,8 @@ static bool prv_has_cdr(size_t *total_size) {
128123
}
129124

130125
sMemfaultCborEncoder encoder;
131-
memfault_cbor_encoder_init(&encoder, prv_fill_header_cb, cdr_ctx->encoded_metadata.data,
126+
memfault_cbor_encoder_init(&encoder, memfault_cbor_encoder_memcpy_write,
127+
cdr_ctx->encoded_metadata.data,
132128
sizeof(cdr_ctx->encoded_metadata.data));
133129

134130
if (!prv_encode_cdr_metadata(&encoder, cdr_ctx)) {

components/core/src/memfault_log.c

Lines changed: 63 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,25 @@
77
//! is collected using the panics component, the logs will be decoded and displayed in the Memfault
88
//! cloud UI.
99

10-
#include "memfault/core/log.h"
11-
#include "memfault/core/log_impl.h"
12-
#include "memfault_log_private.h"
13-
1410
#include <stdarg.h>
1511
#include <stddef.h>
1612
#include <stdio.h>
1713
#include <string.h>
1814

1915
#include "memfault/config.h"
16+
#include "memfault/core/compact_log_serializer.h"
2017
#include "memfault/core/compiler.h"
2118
#include "memfault/core/debug_log.h"
19+
#include "memfault/core/log.h"
20+
#include "memfault/core/log_impl.h"
2221
#include "memfault/core/math.h"
2322
#include "memfault/core/platform/debug_log.h"
2423
#include "memfault/core/platform/overrides.h"
24+
#include "memfault/core/sdk_assert.h"
25+
#include "memfault/util/base64.h"
2526
#include "memfault/util/circular_buffer.h"
2627
#include "memfault/util/crc16_ccitt.h"
27-
#include "memfault/core/compact_log_serializer.h"
28-
29-
#include "memfault/config.h"
28+
#include "memfault_log_private.h"
3029

3130
#if MEMFAULT_LOG_DATA_SOURCE_ENABLED
3231
#include "memfault_log_data_source_private.h"
@@ -262,6 +261,61 @@ bool memfault_log_read(sMemfaultLog *log) {
262261
return found_unread_log;
263262
}
264263

264+
MEMFAULT_WEAK void memfault_log_export_msg(MEMFAULT_UNUSED eMemfaultPlatformLogLevel level,
265+
const char *msg, MEMFAULT_UNUSED size_t msg_len) {
266+
memfault_platform_log_raw("%s", msg);
267+
}
268+
269+
void memfault_log_export_log(sMemfaultLog *log) {
270+
MEMFAULT_SDK_ASSERT(log != NULL);
271+
272+
char base64[MEMFAULT_LOG_EXPORT_BASE64_CHUNK_MAX_LEN];
273+
size_t log_read_offset = 0;
274+
275+
switch (log->type) {
276+
case kMemfaultLogRecordType_Compact:
277+
while (log_read_offset < log->msg_len) {
278+
memcpy(base64, MEMFAULT_LOG_EXPORT_BASE64_CHUNK_PREFIX,
279+
MEMFAULT_LOG_EXPORT_BASE64_CHUNK_PREFIX_LEN);
280+
281+
size_t log_read_len =
282+
MEMFAULT_MIN(log->msg_len - log_read_offset, MEMFAULT_LOG_EXPORT_CHUNK_MAX_LEN);
283+
size_t write_offset = MEMFAULT_LOG_EXPORT_BASE64_CHUNK_PREFIX_LEN;
284+
285+
memfault_base64_encode(&log->msg[log_read_offset], log_read_len, &base64[write_offset]);
286+
log_read_offset += log_read_len;
287+
write_offset += MEMFAULT_BASE64_ENCODE_LEN(log_read_len);
288+
289+
memcpy(&base64[write_offset], MEMFAULT_LOG_EXPORT_BASE64_CHUNK_SUFFIX,
290+
MEMFAULT_LOG_EXPORT_BASE64_CHUNK_SUFFIX_LEN);
291+
write_offset += MEMFAULT_LOG_EXPORT_BASE64_CHUNK_SUFFIX_LEN;
292+
293+
base64[write_offset] = '\0';
294+
295+
memfault_log_export_msg(log->level, base64, write_offset);
296+
}
297+
break;
298+
case kMemfaultLogRecordType_Preformatted:
299+
memfault_log_export_msg(log->level, log->msg, log->msg_len);
300+
break;
301+
case kMemfaultLogRecordType_NumTypes: // silences -Wswitch-enum
302+
default:
303+
break;
304+
}
305+
}
306+
307+
void memfault_log_export_logs(void) {
308+
while (1) {
309+
sMemfaultLog log = {0};
310+
const bool log_found = memfault_log_read(&log);
311+
if (!log_found) {
312+
break;
313+
}
314+
315+
memfault_log_export_log(&log);
316+
}
317+
}
318+
265319
static bool prv_should_log(eMemfaultPlatformLogLevel level) {
266320
if (!s_memfault_ram_logger.enabled) {
267321
return false;
@@ -342,17 +396,13 @@ static void prv_log_save(eMemfaultPlatformLogLevel level,
342396

343397
#if MEMFAULT_COMPACT_LOG_ENABLE
344398

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-
350399
void memfault_compact_log_save(eMemfaultPlatformLogLevel level, uint32_t log_id,
351400
uint32_t compressed_fmt, ...) {
352401
char log_buf[MEMFAULT_LOG_MAX_LINE_SAVE_LEN + 1];
353402

354403
sMemfaultCborEncoder encoder;
355-
memfault_cbor_encoder_init(&encoder, prv_fill_compact_log_cb, log_buf, sizeof(log_buf));
404+
memfault_cbor_encoder_init(&encoder, memfault_cbor_encoder_memcpy_write, log_buf,
405+
sizeof(log_buf));
356406

357407
va_list args;
358408
va_start(args, compressed_fmt);

components/core/src/memfault_trace_event.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -245,11 +245,6 @@ int memfault_trace_event_with_log_capture(
245245

246246
#else
247247

248-
static void prv_fill_compact_log_cb(void *ctx, uint32_t offset, const void *buf, size_t buf_len) {
249-
uint8_t *log = (uint8_t *)ctx;
250-
memcpy(&log[offset], buf, buf_len);
251-
}
252-
253248
int memfault_trace_event_with_compact_log_capture(
254249
eMfltTraceReasonUser reason, void *lr_addr,
255250
uint32_t log_id, uint32_t compressed_fmt, ...) {
@@ -266,7 +261,7 @@ int memfault_trace_event_with_compact_log_capture(
266261
uint8_t log[MEMFAULT_TRACE_EVENT_MAX_LOG_LEN] = { 0 };
267262

268263
sMemfaultCborEncoder encoder;
269-
memfault_cbor_encoder_init(&encoder, prv_fill_compact_log_cb, log, sizeof(log));
264+
memfault_cbor_encoder_init(&encoder, memfault_cbor_encoder_memcpy_write, log, sizeof(log));
270265
memfault_vlog_compact_serialize(&encoder, log_id, compressed_fmt, args);
271266
size_t log_len = memfault_cbor_encoder_deinit(&encoder);
272267

components/include/memfault/core/log.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,19 @@
3434
extern "C" {
3535
#endif
3636

37+
#define MEMFAULT_LOG_EXPORT_BASE64_CHUNK_PREFIX "ML:" // *M*emfault *L*og
38+
#define MEMFAULT_LOG_EXPORT_BASE64_CHUNK_PREFIX_LEN \
39+
MEMFAULT_STATIC_STRLEN(MEMFAULT_LOG_EXPORT_BASE64_CHUNK_PREFIX)
40+
41+
#define MEMFAULT_LOG_EXPORT_BASE64_CHUNK_SUFFIX ":"
42+
#define MEMFAULT_LOG_EXPORT_BASE64_CHUNK_SUFFIX_LEN \
43+
MEMFAULT_STATIC_STRLEN(MEMFAULT_LOG_EXPORT_BASE64_CHUNK_SUFFIX)
44+
45+
#define MEMFAULT_LOG_EXPORT_BASE64_CHUNK_MAX_LEN \
46+
(MEMFAULT_LOG_EXPORT_BASE64_CHUNK_PREFIX_LEN + \
47+
MEMFAULT_BASE64_ENCODE_LEN(MEMFAULT_LOG_EXPORT_CHUNK_MAX_LEN) + \
48+
MEMFAULT_LOG_EXPORT_BASE64_CHUNK_SUFFIX_LEN + 1 /* '\0' */)
49+
3750
//! Must be called on boot to initialize the Memfault logging module
3851
//!
3952
//! @param buffer The ram buffer to save logs into
@@ -155,6 +168,25 @@ typedef struct {
155168
//! }
156169
bool memfault_log_read(sMemfaultLog *log);
157170

171+
//! Utility that formats and outputs a log via the output medium defined in
172+
//! `memfault_log_export_msg`.
173+
//!
174+
//! @note In case the log message is stored in the binary "compact log" format, the message is first
175+
//! formatted as 'ML:COMPACT_LOG_DATA_BASE64_ENCODED:'
176+
//! A python library for decoding compact logs can be found here:
177+
//! https://pypi.org/project/mflt-compact-log/
178+
void memfault_log_export_log(sMemfaultLog *log);
179+
180+
//! Helper function that repeatedly calls memfault_log_read() until there are no more logs
181+
//! available. For each log `memfault_log_export_log` is called.
182+
void memfault_log_export_logs(void);
183+
184+
//! Called as part of memfault_log_export() for every time a log message needs to be exported.
185+
//!
186+
//! @note This is a weak function that by default calls `memfault_platform_log_raw`. It can be
187+
//! overriden to change the formatting of the output, as well as where it is stored.
188+
extern void memfault_log_export_msg(eMemfaultPlatformLogLevel level, const char *msg, size_t msg_len);
189+
158190
//! Invoked every time a new log has been saved
159191
//!
160192
//! @note By default this is a weak function which behaves as a no-op. Platforms which dispatch

components/include/memfault/default_config.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,13 @@ extern "C" {
103103
#define MEMFAULT_LOG_DATA_SOURCE_ENABLED 1
104104
#endif
105105

106+
//! Maximum length of a compact log export chunk.
107+
//!
108+
//! Controls the maximum chunk length when exporting compact logs with memfault_log_export.
109+
#ifndef MEMFAULT_LOG_EXPORT_CHUNK_MAX_LEN
110+
#define MEMFAULT_LOG_EXPORT_CHUNK_MAX_LEN 80
111+
#endif
112+
106113
//! Maximum length a log record can occupy
107114
//!
108115
//! Structs holding this log may be allocated on the stack so care should be taken

components/include/memfault/util/cbor.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,15 @@ bool memfault_cbor_encode_long_signed_integer(sMemfaultCborEncoder *encoder, int
161161
//! @return true on success, false otherwise
162162
bool memfault_cbor_encode_null(sMemfaultCborEncoder *encoder);
163163

164+
//! Helper utility to copy a given buffer to the output buffer at the given offset using memcpy.
165+
//!
166+
//! @param ctx Output buffer
167+
//! @param offset Offset data is copied to in output buffer
168+
//! @param buf Input buffer to be copied
169+
//! @param buf_len Length of input buffer
170+
void memfault_cbor_encoder_memcpy_write(void *ctx, uint32_t offset, const void *buf,
171+
size_t buf_len);
172+
164173
//! NOTE: For internal use only, included in the header so it's easy for a caller to statically
165174
//! allocate the structure
166175
struct MemfaultCborEncoder {

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 = 42, .patch = 0 }
22+
#define MEMFAULT_SDK_VERSION { .major = 0, .minor = 42, .patch = 1 }
2323

2424
#ifdef __cplusplus
2525
}

0 commit comments

Comments
 (0)