nvm event logger

nvm_events^2
Mateusz Lubecki 2024-07-10 19:37:27 +02:00 zatwierdzone przez SP8EBC
rodzic 1e23ed3af8
commit d444bad214
10 zmienionych plików z 339 dodań i 299 usunięć

Wyświetl plik

@ -1,7 +1,7 @@
{
"configurations": [
{
"name": "Linux",
"name": "PARAMETEO",
"includePath": [
"${workspaceFolder}/**"
],
@ -10,6 +10,17 @@
"cStandard": "c17",
"cppStandard": "gnu++17",
"intelliSenseMode": "linux-gcc-x64"
},
{
"name": "UNIT_TESTS",
"includePath": [
"${workspaceFolder}/**"
],
"defines": ["UNIT_TEST"],
"compilerPath": "/usr/bin/gcc",
"cStandard": "c17",
"cppStandard": "gnu++17",
"intelliSenseMode": "linux-gcc-x64"
}
],
"version": 4

Wyświetl plik

@ -16,6 +16,8 @@
"event_log.h": "c",
"nvm_configuration.h": "c",
"flash_stm32l4x.h": "c",
"stm32f10x_flash.h": "c"
"stm32f10x_flash.h": "c",
"nvm_event.h": "c",
"nvm_internals.h": "c"
}
}

Wyświetl plik

@ -8,8 +8,8 @@
#ifndef NVM_H_
#define NVM_H_
#include "nvm_internals.h"
#include <stdint.h>
#include "nvm_t.h"
#define NVM_RECORD_SIZE 8 // in bytes!!

Wyświetl plik

@ -1,9 +1,8 @@
#ifndef B9059D46_61C3_45A2_A688_7297F71FC356
#define B9059D46_61C3_45A2_A688_7297F71FC356
#include "nvm_internals.h"
#include "event_log.h"
#include "nvm_t.h"
/**
*
* @param oldest
@ -16,7 +15,7 @@ nvm_event_result_t nvm_event_log_find_first_oldest_newest(event_log_t** oldest,
* @param oldest
* @param newest
*/
nvm_event_result_t nvm_event_log_push_new_event(event_log_t* event, event_log_t** oldest, event_log_t** newest);
nvm_event_result_t nvm_event_log_push_new_event(event_log_t* event);
#endif /* B9059D46_61C3_45A2_A688_7297F71FC356 */

Wyświetl plik

@ -0,0 +1,111 @@
#ifndef E365347D_02F3_4DCB_A254_BF10A5E57B60
#define E365347D_02F3_4DCB_A254_BF10A5E57B60
/**
*
*/
#define NVM_EVENT_CREATE_POINTERS_FOR_TARGET(_name, _non_ptr_based_write_function, _area_start_addr, _area_end_addr, _erase_fn, _enable_pgm_fn, _wait_for_pgm_fn, _disable_pgm_fn, _severity, pointer_based_access) \
event_log_t* nvm_event_oldest##_name; \
event_log_t* nvm_event_newest##_name; \
\
/**
*
*/
#define NVM_EVENT_PUSH_POINTERS_ARITM(_name, _area_start_addr, _area_end_addr, _erase_fn, _severity) \
if (EVENT_LOG_GET_SEVERITY(event->severity_and_source) >= _severity ) { \
nvm_event_log_perform_pointer_arithmetics(&nvm_event_oldest##_name, &nvm_event_newest##_name, _area_start_addr, _area_end_addr, _erase_fn); \
} \
/**
*
*/
#define NVM_EVENT_PUSH_POINTERS_FLASH_OPER(_name, _event_to_insert, _area_end_addr, _erase_fn, _enable_pgm_fn, _wait_for_pgm_fn, _disable_pgm_fn, _severity) \
if (EVENT_LOG_GET_SEVERITY(event->severity_and_source) >= _severity ) { \
/* programming 32 bits at once */ \
uint32_t * ptr_event_to_insert = (uint32_t*)_event_to_insert; \
uint32_t * ptr_place_for_new_event = (uint32_t*)nvm_event_newest##_name; \
\
_enable_pgm_fn \
\
*((uint32_t*)(ptr_place_for_new_event)) = *ptr_event_to_insert; \
_wait_for_pgm_fn \
\
*((uint32_t*)(ptr_place_for_new_event)+ 1) = *(ptr_event_to_insert + 1); \
_wait_for_pgm_fn \
\
*((uint32_t*)(ptr_place_for_new_event)+ 2) = *(ptr_event_to_insert + 2); \
_wait_for_pgm_fn \
\
*((uint32_t*)(ptr_place_for_new_event)+ 3) = *(ptr_event_to_insert + 3); \
_wait_for_pgm_fn \
\
_disable_pgm_fn \
\
} \
/**
*
*/
#define NVM_EVENT_PUSH_POINTERS_ARITM_SEC(_name, _area_start_addr, _area_end_addr) \
/* rescan for oldest and newest event one more time */ \
nvm_event_log_find_first_oldest_newest(&nvm_event_oldest##_name, &nvm_event_newest##_name, (void*)_area_start_addr, (void*)_area_end_addr); \
\
/**
*
*/
#define NVM_EVENT_EXPAND_POINTER_BASE_ACCESS_true(_name, _area_start_addr, _area_end_addr, _erase_fn, _enable_pgm_fn, _wait_for_pgm_fn, _disable_pgm_fn, _severity) \
NVM_EVENT_PUSH_POINTERS_ARITM(_name, _area_start_addr, _area_end_addr, _erase_fn, _severity); \
NVM_EVENT_PUSH_POINTERS_FLASH_OPER(_name, event, _area_end_addr, _erase_fn, _enable_pgm_fn, _wait_for_pgm_fn, _disable_pgm_fn, _severity); \
NVM_EVENT_PUSH_POINTERS_ARITM_SEC(_name, _area_start_addr, _area_end_addr); \
/**
*
*/
#define NVM_EVENT_EXPAND_POINTER_BASE_ACCESS(_name, _non_ptr_based_write_function, _area_start_addr, _area_end_addr, _erase_fn, _enable_pgm_fn, _wait_for_pgm_fn, _disable_pgm_fn, _severity, pointer_based_access) \
NVM_EVENT_EXPAND_POINTER_BASE_ACCESS_##pointer_based_access(_name, _area_start_addr, _area_end_addr, _erase_fn, _enable_pgm_fn, _wait_for_pgm_fn, _disable_pgm_fn, _severity); \
#define NVM_EVENT_PERFORM_INIT_true(_name, _area_start_addr, _area_end_addr) \
NVM_EVENT_PUSH_POINTERS_ARITM_SEC(_name, _area_start_addr, _area_end_addr) \
#define NVM_EVENT_PERFORM_INIT(_name, _area_start_addr, _area_end_addr, pointer_based_access) \
NVM_EVENT_PERFORM_INIT_##pointer_based_access(_name, _area_start_addr, _area_end_addr) \
#ifdef STM32L471xx
//!< Size of single flash memory page
#define NVM_PAGE_SIZE 2048
//!< How flash program operation are aligned, how many bytes must be programmed at once
#define NVM_WRITE_BYTE_ALIGN 8
#endif
#ifdef STM32F10X_MD_VL
/*
* NVM logger currently not implemented for this platform
*/
#endif
#if (defined UNIT_TEST)
//!< Size of single flash memory page
#define NVM_PAGE_SIZE 2048
//!< How flash program operation are aligned, how many bytes must be programmed at once
#define NVM_WRITE_BYTE_ALIGN 8
// currently defined here for unit tests
typedef enum
{
FLASH_BUSY = 1, /**< FLASH_BUSY */
FLASH_ERROR_PG, /**< FLASH_ERROR_PG */
FLASH_ERROR_WRP,/**< FLASH_ERROR_WRP */
FLASH_COMPLETE, /**< FLASH_COMPLETE */
FLASH_TIMEOUT /**< FLASH_TIMEOUT */
}FLASH_Status;
#endif
#endif /* E365347D_02F3_4DCB_A254_BF10A5E57B60 */

Wyświetl plik

@ -0,0 +1,21 @@
#ifndef D693DD34_021C_482B_A532_AB5B31D18C64
#define D693DD34_021C_482B_A532_AB5B31D18C64
typedef enum nvm_state_result_t {
NVM_UNINITIALIZED,
NVM_OK,
NVM_NO_SPACE_LEFT,
NVM_INIT_ERROR,
NVM_PGM_ERROR
}nvm_state_result_t;
typedef enum nvm_event_result_t {
NVM_EVENT_OK,
NVM_EVENT_OVERRUN_NO_TS,
NVM_EVENT_OVERRUN,
NVM_EVENT_SINGLE_TS,
NVM_EVENT_EMPTY,
NVM_EVENT_AREA_ERROR
}nvm_event_result_t;
#endif /* D693DD34_021C_482B_A532_AB5B31D18C64 */

Wyświetl plik

@ -1,50 +0,0 @@
#ifndef E365347D_02F3_4DCB_A254_BF10A5E57B60
#define E365347D_02F3_4DCB_A254_BF10A5E57B60
typedef enum nvm_state_result_t {
NVM_UNINITIALIZED,
NVM_OK,
NVM_NO_SPACE_LEFT,
NVM_INIT_ERROR,
NVM_PGM_ERROR
}nvm_state_result_t;
typedef enum nvm_event_result_t {
NVM_EVENT_OK,
NVM_EVENT_OVERRUN_NO_TS,
NVM_EVENT_OVERRUN,
NVM_EVENT_SINGLE_TS,
NVM_EVENT_EMPTY,
NVM_EVENT_AREA_ERROR
}nvm_event_result_t;
#ifdef STM32L471xx
//!< Size of single flash memory page
#define NVM_PAGE_SIZE 2048
//!< How flash program operation are aligned, how many bytes must be programmed at once
#define NVM_WRITE_BYTE_ALIGN 8
#endif
#ifdef STM32F10X_MD_VL
/*
* NVM logger currently not implemented for this platform
*/
#endif
#if (defined UNIT_TEST)
// currently defined here for unit tests
typedef enum
{
FLASH_BUSY = 1, /**< FLASH_BUSY */
FLASH_ERROR_PG, /**< FLASH_ERROR_PG */
FLASH_ERROR_WRP,/**< FLASH_ERROR_WRP */
FLASH_COMPLETE, /**< FLASH_COMPLETE */
FLASH_TIMEOUT /**< FLASH_TIMEOUT */
}FLASH_Status;
#endif
#endif /* E365347D_02F3_4DCB_A254_BF10A5E57B60 */

Wyświetl plik

@ -6,6 +6,7 @@
*/
#include "nvm.h"
#include "nvm_internals.h"
#include "nvm_configuration.h"
#include "memory_map.h"
#include "backup_registers.h"

188
src/nvm/nvm_event.c 100644
Wyświetl plik

@ -0,0 +1,188 @@
#include "nvm_event.h"
#include "nvm_configuration.h"
#include "memory_map.h"
#include "backup_registers.h"
#include "nvm_internals.h"
static nvm_state_result_t nvm_general_state = NVM_UNINITIALIZED;
NVM_EVENT_LOGGING_TARGETS(NVM_EVENT_CREATE_POINTERS_FOR_TARGET);
static void nvm_event_log_perform_pointer_arithmetics(
event_log_t** oldest,
event_log_t** newest,
void * area_start,
void * area_end,
FLASH_Status(*erase_fn)(uint32_t)) {
// pointers
const event_log_t* oldest_init_ptr = *oldest;
const event_log_t* next_newest_init_ptr = *newest + 1;
/* check if we reach boundary between two flash memory pages */
/* and the newest entry is just before the oldest pne */
if (next_newest_init_ptr == oldest_init_ptr) {
/* erase next flash memory page to make a room for next events */
const FLASH_Status flash_status = erase_fn (*oldest);
/* check operation result */
if (flash_status != FLASH_COMPLETE) {
nvm_general_state = NVM_PGM_ERROR;
}
/* rescan for oldest and newest event one more time */
nvm_event_log_find_first_oldest_newest(oldest, newest, (void*)area_start, (void*)area_end);
const uint8_t old_new_events_spacing = *oldest - *newest;
/* oldest - newest should be located NVM_PAGE_SIZE bytes apart */
/* please note, that pointers points to the beginning of each */
/* entry, hence this minus one */
if ((old_new_events_spacing - 1) * sizeof(event_log_t) != NVM_PAGE_SIZE) {
backup_assert(BACKUP_REG_ASSERT_ERASE_FAIL_WHILE_STORING_EVENT);
}
/* move pointer to newest, to point to a place where */
/* newly inserted event will be located */
*newest = *(newest) + 1;
}
else if ((void*)next_newest_init_ptr >= (void*)area_end) {
/* we have reached an end of the event area in flash */
/* erase first memory page */
(void)erase_fn (area_start);
/* set pointers accordingly */
event_log_t* new_newest = (event_log_t*)area_start;
event_log_t* new_oldest = (event_log_t*)(area_end - sizeof(event_log_t));
*newest = new_newest;
*oldest = new_oldest;
}
else {
*newest = *(newest) + 1;
}
}
/**
*
* @param oldest
* @param newest
*/
nvm_event_result_t nvm_event_log_find_first_oldest_newest(event_log_t** oldest, event_log_t** newest, void * area_start, void * area_end) {
nvm_event_result_t res = NVM_EVENT_OK;
// pointer to last, non null and non TIMESYNC entry
event_log_t* last_non_ts = NULL;
// pointer to the oldest non TIMESYNC event log entry
event_log_t* oldest_non_ts = NULL;
// size of single log entry
const uint8_t log_entry_size = sizeof(event_log_t);
// how any events could be stored in NVM flash memory
const uint16_t log_entries = (area_end - area_start) / log_entry_size;
// lowest date found within events in NVM
uint32_t lowest_date = 0xFFFFFFFFu;
uint32_t lowest_time = 0xFFFFFFFFu;
// sanity check if everything is set correctly
if ((area_end - area_start) % log_entry_size != 0 ) {
return NVM_EVENT_AREA_ERROR;
}
last_non_ts = (event_log_t *)area_start;
// iterate through all event log flash area
for (int i = 0; i < log_entries; i++) {
// set pointer to currently checked event
const event_log_t* const current = (area_start + (log_entry_size) * i);
event_log_severity_t severity = (current->severity_and_source & 0xF0) >> 4;
event_log_source_t source = (current->severity_and_source & 0xF);
// skip erased memory
if (current->event_id == 0xFFU && current->event_master_time == 0xFFFFFFFFU) {
oldest_non_ts = NULL;
continue;
}
// look for timesync event created at bootup
if (current->event_id == EVENT_TIMESYNC && current->wparam == 0x77) {
// check if this timestamp is before the oldest found before
if (lowest_date > current->lparam && lowest_time > current->lparam2) {
// set this as the oldest
lowest_date = current->lparam;
lowest_time = current->lparam2;
// timestamp are always created after the first one after power up, so that
// with oldest RTC date and time will be the oldest in general
*oldest = (event_log_t*)current;
}
}
else {
if (current->event_master_time > last_non_ts->event_master_time) {
// store a pointer to last non-null and non-timesync event
last_non_ts = (event_log_t*)current;
// updated output pointer with newest
*newest = last_non_ts;
}
else {
// this loop goes forward in memory. if consecutive non timesync event
// has decreasing master_time value it means, that nvm events area
// has overruned at least one time
res = NVM_EVENT_OVERRUN;
if (oldest_non_ts == NULL) {
oldest_non_ts = (event_log_t*)current;
}
}
}
}
// check if any non-timesync event has been found at all
if (last_non_ts == NULL) {
// no, NVM log contains only single timesync event
res = NVM_EVENT_SINGLE_TS;
}
// check if any timesync event has been found
if (lowest_date == 0xFFFFFFFFu && lowest_time == 0xFFFFFFFF) {
if (last_non_ts == (event_log_t *)area_start) {
res = NVM_EVENT_EMPTY; // nvm event area is empty
}
else {
*oldest = oldest_non_ts;
res = NVM_EVENT_OVERRUN_NO_TS;
}
}
return res;
}
/**
* @param event
* @param oldest
* @param newest
*/
nvm_event_result_t nvm_event_log_push_new_event(event_log_t* event) {
nvm_event_result_t out = NVM_EVENT_OK;
NVM_EVENT_LOGGING_TARGETS(NVM_EVENT_EXPAND_POINTER_BASE_ACCESS);
return out;
}

Wyświetl plik

@ -1,243 +0,0 @@
#include "nvm_event.h"
#include "nvm_configuration.h"
#include "memory_map.h"
#include "backup_registers.h"
/**
*
*/
#define NVM_EVENT_CREATE_POINTERS_FOR_TARGET(_name, _non_ptr_based_write_function, _area_start_addr, _area_end_addr, _erase_fn, _enable_pgm_fn, _wait_for_pgm_fn, _disable_pgm_fn, _severity, pointer_based_access) \
event_log_t** nvm_event_oldest##_name; \
event_log_t** nvm_event_newest##_name; \
\
/**
*
*/
#define NVM_EVENT_PUSH_POINTERS_ARITM(_area_start_addr, _area_end_addr, _erase_fn, _severity) \
if (EVENT_LOG_GET_SEVERITY(event->severity_and_source) >= _severity ) { \
/* check if we reach boundary between two flash memory pages */ \
/* and the newest entry is just before the oldest pne */ \
if (next_newest_init_ptr == oldest_init_ptr) { \
/* erase next flash memory page to make a room for next events */ \
flash_status = _erase_fn (*oldest); \
\
/* check operation result */ \
if (flash_status != FLASH_COMPLETE) { \
nvm_general_state = NVM_PGM_ERROR; \
} \
\
/* rescan for oldest and newest event one more time */ \
nvm_event_log_find_first_oldest_newest(oldest, newest, (void*)_area_start_addr, (void*)_area_end_addr); \
\
const uint8_t old_new_events_spacing = *oldest - *newest; \
\
/* oldest - newest should be located NVM_PAGE_SIZE bytes apart */ \
/* please note, that pointers points to the beginning of each */ \
/* entry, hence this minus one */ \
if ((old_new_events_spacing - 1) * sizeof(event_log_t) != NVM_PAGE_SIZE) { \
backup_assert(BACKUP_REG_ASSERT_ERASE_FAIL_WHILE_STORING_EVENT); \
} \
\
/* move pointer to newest, to point to a place where */ \
/* newly inserted event will be located */ \
*newest = *(newest) + 1; \
} \
else if ((void*)next_newest_init_ptr >= (void*)_area_end_addr) { \
/* we have reached an end of the event area in flash */ \
\
/* erase first memory page */ \
flash_status = _erase_fn (_area_start_addr); \
\
/* set pointers accordingly */ \
event_log_t* new_newest = (event_log_t*)_area_start_addr; \
event_log_t* new_oldest = (event_log_t*)(_area_end_addr - sizeof(event_log_t)); \
\
*newest = new_newest; \
*oldest = new_oldest; \
} \
else { \
*newest = *(newest) + 1; \
} \
} \
/**
*
*/
#define NVM_EVENT_PUSH_POINTERS_FLASH_OPER(_event_to_insert, _area_end_addr, _erase_fn, _enable_pgm_fn, _wait_for_pgm_fn, _disable_pgm_fn, _severity) \
if (EVENT_LOG_GET_SEVERITY(event->severity_and_source) >= _severity ) { \
/* programming 32 bits at once */ \
uint32_t * ptr_event_to_insert = (uint32_t*)_event_to_insert; \
uint32_t * ptr_place_for_new_event = (uint32_t*)*newest; \
\
_enable_pgm_fn \
\
*((uint32_t*)(ptr_place_for_new_event)) = *ptr_event_to_insert; \
_wait_for_pgm_fn \
\
*((uint32_t*)(ptr_place_for_new_event)+ 1) = *(ptr_event_to_insert + 1); \
_wait_for_pgm_fn \
\
*((uint32_t*)(ptr_place_for_new_event)+ 2) = *(ptr_event_to_insert + 2); \
_wait_for_pgm_fn \
\
*((uint32_t*)(ptr_place_for_new_event)+ 3) = *(ptr_event_to_insert + 3); \
_wait_for_pgm_fn \
\
_disable_pgm_fn \
\
} \
/**
*
*/
#define NVM_EVENT_PUSH_POINTERS_ARITM_SEC(_area_start_addr, _area_end_addr) \
/* rescan for oldest and newest event one more time */ \
nvm_event_log_find_first_oldest_newest(oldest, newest, (void*)_area_start_addr, (void*)_area_end_addr); \
\
/**
*
*/
#define NVM_EVENT_EXPAND_POINTER_BASE_ACCESS_true(_area_start_addr, _area_end_addr, _erase_fn, _enable_pgm_fn, _wait_for_pgm_fn, _disable_pgm_fn, _severity) \
NVM_EVENT_PUSH_POINTERS_ARITM(_area_start_addr, _area_end_addr, _erase_fn, _severity); \
NVM_EVENT_PUSH_POINTERS_FLASH_OPER(event, _area_end_addr, _erase_fn, _enable_pgm_fn, _wait_for_pgm_fn, _disable_pgm_fn, _severity); \
NVM_EVENT_PUSH_POINTERS_ARITM_SEC(_area_start_addr, _area_end_addr); \
/**
*
*/
#define NVM_EVENT_EXPAND_POINTER_BASE_ACCESS(_name, _non_ptr_based_write_function, _area_start_addr, _area_end_addr, _erase_fn, _enable_pgm_fn, _wait_for_pgm_fn, _disable_pgm_fn, _severity, pointer_based_access) \
NVM_EVENT_EXPAND_POINTER_BASE_ACCESS_##pointer_based_access(_area_start_addr, _area_end_addr, _erase_fn, _enable_pgm_fn, _wait_for_pgm_fn, _disable_pgm_fn, _severity); \
static nvm_state_result_t nvm_general_state = NVM_UNINITIALIZED;
NVM_EVENT_LOGGING_TARGETS(NVM_EVENT_CREATE_POINTERS_FOR_TARGET);
/**
*
* @param oldest
* @param newest
*/
nvm_event_result_t nvm_event_log_find_first_oldest_newest(event_log_t** oldest, event_log_t** newest, void * area_start, void * area_end) {
nvm_event_result_t res = NVM_EVENT_OK;
// pointer to last, non null and non TIMESYNC entry
event_log_t* last_non_ts = NULL;
// pointer to the oldest non TIMESYNC event log entry
event_log_t* oldest_non_ts = NULL;
// size of single log entry
const uint8_t log_entry_size = sizeof(event_log_t);
// how any events could be stored in NVM flash memory
const uint16_t log_entries = (area_end - area_start) / log_entry_size;
// lowest date found within events in NVM
uint32_t lowest_date = 0xFFFFFFFFu;
uint32_t lowest_time = 0xFFFFFFFFu;
// sanity check if everything is set correctly
if ((area_end - area_start) % log_entry_size != 0 ) {
return NVM_EVENT_AREA_ERROR;
}
last_non_ts = (event_log_t *)area_start;
// iterate through all event log flash area
for (int i = 0; i < log_entries; i++) {
// set pointer to currently checked event
const event_log_t* const current = (area_start + (log_entry_size) * i);
event_log_severity_t severity = (current->severity_and_source & 0xF0) >> 4;
event_log_source_t source = (current->severity_and_source & 0xF);
// skip erased memory
if (current->event_id == 0xFFU && current->event_master_time == 0xFFFFFFFFU) {
oldest_non_ts = NULL;
continue;
}
// look for timesync event created at bootup
if (current->event_id == EVENT_TIMESYNC && current->wparam == 0x77) {
// check if this timestamp is before the oldest found before
if (lowest_date > current->lparam && lowest_time > current->lparam2) {
// set this as the oldest
lowest_date = current->lparam;
lowest_time = current->lparam2;
// timestamp are always created after the first one after power up, so that
// with oldest RTC date and time will be the oldest in general
*oldest = (event_log_t*)current;
}
}
else {
if (current->event_master_time > last_non_ts->event_master_time) {
// store a pointer to last non-null and non-timesync event
last_non_ts = (event_log_t*)current;
// updated output pointer with newest
*newest = last_non_ts;
}
else {
// this loop goes forward in memory. if consecutive non timesync event
// has decreasing master_time value it means, that nvm events area
// has overruned at least one time
res = NVM_EVENT_OVERRUN;
if (oldest_non_ts == NULL) {
oldest_non_ts = (event_log_t*)current;
}
}
}
}
// check if any non-timesync event has been found at all
if (last_non_ts == NULL) {
// no, NVM log contains only single timesync event
res = NVM_EVENT_SINGLE_TS;
}
// check if any timesync event has been found
if (lowest_date == 0xFFFFFFFFu && lowest_time == 0xFFFFFFFF) {
if (last_non_ts == (event_log_t *)area_start) {
res = NVM_EVENT_EMPTY; // nvm event area is empty
}
else {
*oldest = oldest_non_ts;
res = NVM_EVENT_OVERRUN_NO_TS;
}
}
return res;
}
/**
* @param event
* @param oldest
* @param newest
*/
nvm_event_result_t nvm_event_log_push_new_event(event_log_t* event, event_log_t** oldest, event_log_t** newest) {
nvm_event_result_t out = NVM_EVENT_OK;
// flash operation result
FLASH_Status flash_status = 0;
// pointers
const event_log_t* oldest_init_ptr = *oldest;
const event_log_t* next_newest_init_ptr = *newest + 1;
NVM_EVENT_LOGGING_TARGETS(NVM_EVENT_EXPAND_POINTER_BASE_ACCESS);
return out;
}