Dedupe RX/TX log entry copies by aligning RAM and flash struct layouts

This commit is contained in:
Armel FAUVEAU committed 2026-07-05 23:01:27 +02:00
1 parent a14127867e
commit 4fccdb78b9
2 files changed
+18 -33

No files matched your search

+15 -32
View File
@@ -6,6 +6,7 @@
#ifdef ENABLE_FEAT_F4HWN_RXTX_LOG #ifdef ENABLE_FEAT_F4HWN_RXTX_LOG
#include <assert.h> #include <assert.h>
#include <stddef.h>
#include <string.h> #include <string.h>
#include "app/generic.h" #include "app/generic.h"
@@ -54,6 +55,9 @@ typedef struct __attribute__((packed)) {
static_assert(sizeof(RXTX_LogFlashEntry_t) == 32); static_assert(sizeof(RXTX_LogFlashEntry_t) == 32);
static_assert(RXTX_LOG_VIEW_ANCHOR_COUNT <= 32); static_assert(RXTX_LOG_VIEW_ANCHOR_COUNT <= 32);
// RXTX_LogEntry_t (RAM) and RXTX_LogFlashEntry_t must stay byte-identical up
// to the end of name[] so entries can be copied with a single memcpy.
static_assert(offsetof(RXTX_LogEntry_t, name) == offsetof(RXTX_LogFlashEntry_t, name));
static RXTX_LogEntry_t gViewCache[RXTX_LOG_VIEW_CACHE_COUNT]; static RXTX_LogEntry_t gViewCache[RXTX_LOG_VIEW_CACHE_COUNT];
static uint16_t gViewCacheStart; static uint16_t gViewCacheStart;
@@ -161,22 +165,14 @@ static bool RXTX_LOG_MatchesFlags(uint8_t flags)
const char *RXTX_LOG_GetFilterName(void) const char *RXTX_LOG_GetFilterName(void)
{ {
if (gLogFilter == RXTX_LOG_FILTER_RX) static const char *const filterNames[] = {"ALL", "RX", "TX"};
return "RX";
if (gLogFilter == RXTX_LOG_FILTER_TX) return filterNames[gLogFilter];
return "TX";
return "ALL";
} }
static void RXTX_LOG_CopyFromFlash(RXTX_LogEntry_t *dst, const RXTX_LogFlashEntry_t *src) static void RXTX_LOG_CopyFromFlash(RXTX_LogEntry_t *dst, const RXTX_LogFlashEntry_t *src)
{ {
dst->sequence = src->sequence; memcpy(dst, src, offsetof(RXTX_LogFlashEntry_t, reserved));
dst->frequency = src->frequency;
dst->trafficSeq = src->trafficSeq;
dst->durationSeconds = src->durationSeconds;
dst->channel = src->channel;
dst->flags = src->flags;
memcpy(dst->name, src->name, RXTX_LOG_NAME_LEN);
dst->name[RXTX_LOG_NAME_LEN] = 0; dst->name[RXTX_LOG_NAME_LEN] = 0;
} }
@@ -560,14 +556,8 @@ static uint32_t RXTX_LOG_WriteEntry(const RXTX_LogEntry_t *src)
uint8_t commit = RXTX_LOG_ENTRY_COMMIT; uint8_t commit = RXTX_LOG_ENTRY_COMMIT;
memset(&entry, 0xFF, sizeof(entry)); memset(&entry, 0xFF, sizeof(entry));
entry.sequence = src->sequence; memcpy(&entry, src, offsetof(RXTX_LogFlashEntry_t, reserved));
entry.frequency = src->frequency; entry.crc = RXTX_LOG_Crc8(&entry, sizeof(entry) - 2);
entry.trafficSeq = src->trafficSeq;
entry.durationSeconds = src->durationSeconds;
entry.channel = src->channel;
entry.flags = src->flags;
memcpy(entry.name, src->name, RXTX_LOG_NAME_LEN);
entry.crc = RXTX_LOG_Crc8(&entry, sizeof(entry) - 2);
RXTX_LOG_PrepareNextSlot(); RXTX_LOG_PrepareNextSlot();
@@ -596,18 +586,11 @@ static void RXTX_LOG_EnsureViewCache(void)
{ {
const uint16_t pageStart = RXTX_LOG_PageStart(gLogCursor); const uint16_t pageStart = RXTX_LOG_PageStart(gLogCursor);
if (RXTX_LOG_ViewCacheCovers(gLogCursor) && if (gViewCacheFilter == gLogFilter &&
gViewCacheStart == pageStart) gViewCacheStart == pageStart &&
return; (gViewScanActive ||
gViewCacheComplete ||
if (gViewScanActive && RXTX_LOG_ViewCacheCovers(gLogCursor)))
gViewCacheFilter == gLogFilter &&
gViewCacheStart == pageStart)
return;
if (gViewCacheComplete &&
gViewCacheFilter == gLogFilter &&
gViewCacheStart == pageStart)
return; return;
RXTX_LOG_StartCursorView(gLogCursor); RXTX_LOG_StartCursorView(gLogCursor);
+3 -1
View File
@@ -23,9 +23,11 @@ typedef enum {
RXTX_LOG_DIR_TX = 1, RXTX_LOG_DIR_TX = 1,
} RXTX_LogDirection_t; } RXTX_LogDirection_t;
// Field order mirrors RXTX_LogFlashEntry_t (rxtx_log.c) so both layouts
// match byte-for-byte up to the end of name[] and can be copied in one pass.
typedef struct { typedef struct {
uint32_t frequency;
uint32_t sequence; uint32_t sequence;
uint32_t frequency;
uint32_t trafficSeq; uint32_t trafficSeq;
uint16_t durationSeconds; uint16_t durationSeconds;
uint16_t channel; uint16_t channel;