* nvm

* refactored some nvm event code to separate file

* daily

* nvm_event_log_push_new_event reworked to use x-macro

* macro to create pointers for each logging instance

* nvm event logger

* nvm event logger, documentation and comments to macros and the module configuration

* nvm event: commit before refactoring this bullshit

* ready for integration

* ready for second integration
ZT19
SP8EBC 2024-07-13 12:32:50 +02:00 zatwierdzone przez GitHub
rodzic 273838f9d4
commit bea154e647
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: B5690EEEBB952194
15 zmienionych plików z 488 dodań i 183 usunięć

24
.clang-format 100644
Wyświetl plik

@ -0,0 +1,24 @@
---
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: true
AlignEscapedNewlines: Left
AlignOperands: 'true'
AllowShortBlocksOnASingleLine: 'true'
AllowShortCaseLabelsOnASingleLine: 'true'
AllowShortFunctionsOnASingleLine: InlineOnly
AllowShortIfStatementsOnASingleLine: 'false'
AllowShortLoopsOnASingleLine: 'false'
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: 'false'
AlwaysBreakTemplateDeclarations: MultiLine
BinPackParameters: false
BreakBeforeBraces: Stroustrup
ColumnLimit: '100'
IndentWidth: '4'
Language: Cpp
SpaceBeforeParens: Always
Standard: Cpp11
TabWidth: '4'
UseTab: Always
...

Wyświetl plik

@ -18,6 +18,8 @@
"flash_stm32l4x.h": "c",
"stm32f10x_flash.h": "c",
"nvm_event.h": "c",
"nvm_internals.h": "c"
"nvm_internals.h": "c",
"main.h": "c",
"main_master_time.h": "c"
}
}

23
clang-format 100644
Wyświetl plik

@ -0,0 +1,23 @@
---
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: true
AlignEscapedNewlines: Left
AlignOperands: 'true'
AllowShortBlocksOnASingleLine: 'true'
AllowShortCaseLabelsOnASingleLine: 'true'
AllowShortFunctionsOnASingleLine: InlineOnly
AllowShortIfStatementsOnASingleLine: 'false'
AllowShortLoopsOnASingleLine: 'false'
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: 'false'
AlwaysBreakTemplateDeclarations: MultiLine
BreakBeforeBraces: Stroustrup
ColumnLimit: '100'
IndentWidth: '4'
Language: Cpp
SpaceBeforeParens: Always
Standard: Cpp11
TabWidth: '4'
UseTab: Always
...

Plik binarny nie jest wyświetlany.

Wyświetl plik

@ -48,16 +48,17 @@ inline uint32_t backup_reg_get_monitor(void) {
#endif
}
#define BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_WX (1U)
#define BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_BEACON (1U << 1U)
#define BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_TELEMETRY (1U << 2U)
#define BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_DESCR (1U << 3U)
#define BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_IGATE (1U << 4U)
#define BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_CNTRS (1U << 5U)
#define BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_LOGINSTRING (1U << 6U)
#define BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_OTHER (1U << 7U)
#define BACKUP_REG_ASSERT_ERASE_FAIL_WHILE_STORING_EVENT (1U << 8U)
#define BACKUP_REG_ASSERT_GET_VBAT_SYNCHRONOUS_TOO_LONG (1U << 9U)
#define BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_WX (1U)
#define BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_BEACON (1U << 1U)
#define BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_TELEMETRY (1U << 2U)
#define BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_DESCR (1U << 3U)
#define BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_IGATE (1U << 4U)
#define BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_CNTRS (1U << 5U)
#define BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_LOGINSTRING (1U << 6U)
#define BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_OTHER (1U << 7U)
#define BACKUP_REG_ASSERT_ERASE_FAIL_WHILE_STORING_EVENT (1U << 8U)
#define BACKUP_REG_ASSERT_GENERAL_FAIL_FROM_NVM_EVENT (1U << 9U)
#define BACKUP_REG_ASSERT_GET_VBAT_SYNCHRONOUS_TOO_LONG (1U << 10U)
uint32_t backup_reg_get_configuration(void);
void backup_reg_set_configuration(uint32_t value);

Wyświetl plik

@ -18,8 +18,9 @@
* @param PointerBasedAccess set to true if this event logger target is memory mapped i/o
*/
#define NVM_EVENT_LOGGING_TARGETS(ENTRY) \
/* TargetName, NonPtrBasedWriteFunction, AreaStartAddress, AreaEndAddress, EraseFunction, PgmingEnableFunction, WaitPgmCompleteFunction, PgmingDisableFunction, MinimumSeverityLevel, PointerBasedAccess */ \
ENTRY( Flash, NULL, MEMORY_MAP_EVENT_LOG_START, MEMORY_MAP_EVENT_LOG_END, FLASH_ErasePage, NVM_CONFIG_ENABLE_PGM, WAIT_FOR_PGM_COMPLETION, NVM_CONFIG_DISABLE_PGM, 1, true) \
/* TargetName, NonPtrBasedWriteFunction, AreaStartAddress, AreaEndAddress, EraseFunction, PgmingEnableFunction, WaitPgmCompleteFunction, PgmingDisableFunction, MinimumSeverityLevel, PageSize, PointerBasedAccess */ \
ENTRY( Flash, NULL, MEMORY_MAP_EVENT_LOG_START, MEMORY_MAP_EVENT_LOG_END, FLASH_ErasePage, NVM_CONFIG_ENABLE_PGM, WAIT_FOR_PGM_COMPLETION, NVM_CONFIG_DISABLE_PGM, 1, NVM_PAGE_SIZE, true) \
/**
* Macro for waiting for flash programming to finish

Wyświetl plik

@ -10,66 +10,89 @@
#include "stdint.h"
#define EVENT_LOG_GET_SEVERITY(x) ((x & 0xF0) >> 4)
/// ==================================================================================================
/// GLOBAL MACROS
/// ==================================================================================================
#define EVENT_LOG_GET_SOURCE(x) (x & 0x0F)
#define EVENT_LOG_GET_SEVERITY(x) ((x & 0xF0) >> 4)
#define EVENT_LOG_TIMESYNC_BOOTUP_WPARAM (0x77U)
#define EVENT_LOG_GET_SOURCE(x) (x & 0x0F)
#define EVENT_LOG_SET_SEVERITY_SOURCE(severity, source) \
(((uint8_t)severity & 0xF) << 4) | ((uint8_t)source & 0xF)
/// ==================================================================================================
/// GLOBAL DEFINITIONS
/// ==================================================================================================
#define EVENT_LOG_TIMESYNC_BOOTUP_WPARAM (0x77U)
/// ==================================================================================================
/// GLOBAL TYPEDEFS
/// ==================================================================================================
/**
* TYpe used to distinguish between event of different severity
*/
typedef enum event_log_severity_t {
EVENT_BOOTUP, /**< EVENT_BOOTUP all info events generated during bootup */
EVENT_TIMESYNC,/**< EVENT_TIMESYNC event generated once at startup and then every 6 hours to keep master_time and RTC date and time sync */
EVENT_DEBUG, /**< EVENT_DEBUG */
EVENT_INFO, /**< EVENT_INFO */
EVENT_WARNING, /**< EVENT_WARNING */
EVENT_ERROR, /**< EVENT_ERROR */
EVENT_ASSERT /**< EVENT_ASSERT assert failure, which result in hard reset*/
}event_log_severity_t;
EVENT_BOOTUP, /**< EVENT_BOOTUP all info events generated during bootup */
EVENT_TIMESYNC, /**< EVENT_TIMESYNC event generated once at startup and then every 6 hours to
keep master_time and RTC date and time sync */
EVENT_DEBUG, /**< EVENT_DEBUG */
EVENT_INFO, /**< EVENT_INFO */
EVENT_WARNING, /**< EVENT_WARNING */
EVENT_ERROR, /**< EVENT_ERROR */
EVENT_ASSERT /**< EVENT_ASSERT assert failure, which result in hard reset*/
} event_log_severity_t;
/**
* Where this long entry was generated
*/
typedef enum event_log_source_t {
EVENT_SRC_MAIN, /**< EVENT_SRC_MAIN everywhere within main.c source file */
EVENT_SRC_WX_HANDLER, /**< EVENT_SRC_WX_HANDLER */
EVENT_SRC_PWR_SAVE, /**< EVENT_SRC_PWR_SAVE */
EVENT_SRC_PACKET_TX_HANDLER,/**< EVENT_SRC_PACKET_TX_HANDLER */
EVENT_SRC_APRSIS, /**< EVENT_SRC_APRSIS */
EVENT_SRC_KISS, /**< EVENT_SRC_KISS */
EVENT_SRC_APRS_RF, /**< EVENT_SRC_APRS_RF */
EVENT_SRC_GSM_GPRS, /**< EVENT_SRC_GSM_GPRS */
EVENT_SRC_TCPIP, /**< EVENT_SRC_TCPIP */
EVENT_SRC_HTTP_CLIENT, /**< EVENT_SRC_HTTP_CLIENT */
EVENT_SRC_MODBUS, /**< EVENT_SRC_MODBUS */
EVENT_SRC_UMB, /**< EVENT_SRC_UMB */
EVENT_SRC_DRV_ANEMOMETER, /**< EVENT_SRC_DRV_ANEMOMETER */
EVENT_SRC_DRV_I2C, /**< EVENT_SRC_DRV_I2C */
EVENT_SRC_DRV_UART, /**< EVENT_SRC_DRV_UART */
EVENT_SRC_DRV_SPI, /**< EVENT_SRC_DRV_SPI */
}event_log_source_t;
EVENT_SRC_MAIN, /**< EVENT_SRC_MAIN everywhere within main.c source file */
EVENT_SRC_WX_HANDLER, /**< EVENT_SRC_WX_HANDLER */
EVENT_SRC_PWR_SAVE, /**< EVENT_SRC_PWR_SAVE */
EVENT_SRC_PACKET_TX_HANDLER, /**< EVENT_SRC_PACKET_TX_HANDLER */
EVENT_SRC_APRSIS, /**< EVENT_SRC_APRSIS */
EVENT_SRC_KISS, /**< EVENT_SRC_KISS */
EVENT_SRC_APRS_RF, /**< EVENT_SRC_APRS_RF */
EVENT_SRC_GSM_GPRS, /**< EVENT_SRC_GSM_GPRS */
EVENT_SRC_TCPIP, /**< EVENT_SRC_TCPIP */
EVENT_SRC_HTTP_CLIENT, /**< EVENT_SRC_HTTP_CLIENT */
EVENT_SRC_MODBUS, /**< EVENT_SRC_MODBUS */
EVENT_SRC_UMB, /**< EVENT_SRC_UMB */
EVENT_SRC_DRV_ANEMOMETER, /**< EVENT_SRC_DRV_ANEMOMETER */
EVENT_SRC_DRV_I2C, /**< EVENT_SRC_DRV_I2C */
EVENT_SRC_DRV_UART, /**< EVENT_SRC_DRV_UART */
EVENT_SRC_DRV_SPI, /**< EVENT_SRC_DRV_SPI */
} event_log_source_t;
/**
* Structure used to store single system event in RAM2 area and Flash
* non volatile storage
*/
typedef struct __attribute__((aligned(1))) event_log_t {
uint32_t event_master_time; //!< value of maser time at the moment an event is generated
uint8_t severity_and_source; //!< high nibble -> severity level, low nibble -> source
uint8_t event_id; //!< event id, unique across different sources & severity level
uint16_t wparam; //!< Optional 2-byte data, specific per event
uint32_t lparam; //!< Optional 4-byte data, specific per event
uint32_t lparam2;
}event_log_t;
typedef struct __attribute__ ((aligned (1))) event_log_t {
uint32_t event_counter_id; //!< counter used to check which event is the oldest and newest one
uint32_t event_master_time; //!< value of maser time at the moment an event is generated
uint8_t severity_and_source; //!< high nibble -> severity level, low nibble -> source
uint8_t event_id; //!< event id, unique across different sources & severity level
uint8_t param; //!< Optional single-byte data, specific per event
uint8_t param2; //!< Optional single-byte data, specific per event
uint16_t wparam; //!< Optional 2-byte data, specific per event
uint16_t wparam2; //!< Optional 2-byte data, specific per event
uint32_t lparam; //!< Optional 4-byte data, specific per event
uint32_t lparam2; //!< Optional 4-byte data, specific per event
} event_log_t;
/// ==================================================================================================
/// GLOBAL FUNCTIONS
/// ==================================================================================================
/**
* Initializes everything log related
*/
void event_log_init(uint8_t flash_enabled_severity, uint8_t ram_enabled_severity);
void event_log_init (void);
/**
* Stores new event in RAM2_NOINIT area. It might trigger asynchronous
@ -79,9 +102,24 @@ void event_log_init(uint8_t flash_enabled_severity, uint8_t ram_enabled_severity
* @param lparam
* @param lparam2
*/
void event_log(event_log_severity_t severity, event_log_source_t source, uint16_t wparam, uint32_t lparam, uint32_t lparam2);
void event_log_sync(event_log_severity_t severity, event_log_source_t source, uint16_t wparam, uint32_t lparam, uint32_t lparam2);
void event_log (event_log_severity_t severity,
event_log_source_t source,
uint8_t event_id,
uint8_t param,
uint8_t param2,
uint16_t wparam,
uint16_t wparam2,
uint32_t lparam,
uint32_t lparam2);
void event_log_sync (event_log_severity_t severity,
event_log_source_t source,
uint8_t event_id,
uint8_t param,
uint8_t param2,
uint16_t wparam,
uint16_t wparam2,
uint32_t lparam,
uint32_t lparam2);
#endif /* EVENT_LOG_H_ */

Wyświetl plik

@ -0,0 +1,15 @@
/*
* events_bootup.h
*
* Created on: Jul 13, 2024
* Author: mateusz
*/
#ifndef EVENTS_DEFINITIONS_EVENTS_BOOTUP_H_
#define EVENTS_DEFINITIONS_EVENTS_BOOTUP_H_
#define EVENTS_BOOTUP_START 0x01U
#endif /* EVENTS_DEFINITIONS_EVENTS_BOOTUP_H_ */

Wyświetl plik

@ -11,8 +11,17 @@
#include <stdint.h>
#include "nvm_t.h"
/// ==================================================================================================
/// GLOBAL DEFINES
/// ==================================================================================================
#define NVM_RECORD_SIZE 8 // in bytes!!
/// ==================================================================================================
/// GLOBAL TYPES
/// ==================================================================================================
typedef struct __attribute__((packed)) nvm_measurement_t {
/**
* Date-time timestamp in timezone local for a place where station is installed.
@ -45,6 +54,11 @@ typedef struct __attribute__((packed)) nvm_measurement_t {
/// ==================================================================================================
/// GLOBAL FUNCTIONS
/// ==================================================================================================
/**
*
*/

Wyświetl plik

@ -3,12 +3,21 @@
#include "event_log.h"
#include "nvm_t.h"
/// ==================================================================================================
/// GLOBAL FUNCTIONS
/// ==================================================================================================
void nvm_event_log_init(void);
/**
*
* @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 nvm_event_log_find_first_oldest_newest(event_log_t** oldest, event_log_t** newest, void * area_start, void * area_end, int16_t page_size);
/**
* @param event

Wyświetl plik

@ -1,16 +1,29 @@
#ifndef E365347D_02F3_4DCB_A254_BF10A5E57B60
#define E365347D_02F3_4DCB_A254_BF10A5E57B60
// clang-format off
/// ==================================================================================================
/// X-MACROS
/// ==================================================================================================
#define NVM_EVENT_CREATE_ENUM_FOR_TARGETS(_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, _page_size, pointer_based_access) \
typedef enum nvm_event_target_ereas_t { \
NVM_EVENT_TARGET_AREA_##_name, \
NVM_EVENT_TARGET_AREA_COUNT \
}nvm_event_target_ereas_t; \
/**
* Macro used for creating work pointers to all event logger targets,
* which is configured as directly mapped into i/o area
*
* @param _name preconfigured name of a event logger target
*/
#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) \
#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, _page_size, pointer_based_access) \
event_log_t* nvm_event_oldest##_name; \
event_log_t* nvm_event_newest##_name; \
\
uint32_t nvm_event_counter_id_for_last_##_name \
/**
* Macro performing pre-insertion pointer arithmetics for all directly i/o
@ -23,14 +36,16 @@
* @param _area_end_addr the highest address of an area for this target
* @param _erase_fn a function (a pointer to) which performs flash memory erasure.
* It should implement an interface FLASH_Status(*erase_fn)(uint32_t), where a parameter is
* an address of flash memory page to be erased. If the targer is configured to store in RAM
* memory, or anything else which does not require explicit erase, the function might be simply nop
* an address of flash memory page of size @link{_page_size} to be erased.
* If the target is configured to store in RAM memory, or anything else which
* does not require explicit erase, the function might be simply nop
* @param _severity level of an event
*
* @param _page_size
*/
#define NVM_EVENT_PUSH_POINTERS_ARITM(_name, _area_start_addr, _area_end_addr, _erase_fn, _severity) \
#define NVM_EVENT_PUSH_POINTERS_ARITM(_name, _area_start_addr, _area_end_addr, _erase_fn, _severity, _page_size) \
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); \
nvm_event_log_perform_pointer_arithmetics(&nvm_event_oldest##_name, &nvm_event_newest##_name, _area_start_addr, _area_end_addr, &nvm_event_counter_id_for_last_##_name, _erase_fn, _page_size); \
} \
/**
@ -47,6 +62,11 @@ if (EVENT_LOG_GET_SEVERITY(event->severity_and_source) >= _severity ) { \
*/
#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 ) { \
/* Set event counter id, if it hasn't been set so far */ \
if (event->event_counter_id == 0) { \
event->event_counter_id = nvm_event_counter_id_for_last_##_name; \
} \
/* 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; \
@ -73,18 +93,19 @@ if (EVENT_LOG_GET_SEVERITY(event->severity_and_source) >= _severity ) {
* Macro to perform pointer arithmetics after an event is stored in target area. It
* updates pointers to oldest and newest pointer
*/
#define NVM_EVENT_PUSH_POINTERS_ARITM_SEC(_name, _area_start_addr, _area_end_addr) \
#define NVM_EVENT_PUSH_POINTERS_ARITM_SEC(_name, _area_start_addr, _area_end_addr, _page_size) \
/* 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); \
nvm_general_state = nvm_event_log_find_first_oldest_newest(&nvm_event_oldest##_name, &nvm_event_newest##_name, (void*)_area_start_addr, (void*)_area_end_addr, _page_size); \
\
/**
*
*/
#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); \
#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, _page_size) \
NVM_EVENT_PUSH_POINTERS_ARITM(_name, _area_start_addr, _area_end_addr, _erase_fn, _severity, _page_size); \
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); \
NVM_EVENT_PUSH_POINTERS_ARITM_SEC(_name, _area_start_addr, _area_end_addr, _page_size); \
/**
* Main macro used in @link{nvm_event_log_push_new_event} to expand all event i/o operations for all target configured
@ -98,22 +119,37 @@ if (EVENT_LOG_GET_SEVERITY(event->severity_and_source) >= _severity ) {
* @param _wait_for_pgm_fn macro which should expand to function call or a piece of code to wait for flash memory programming to finish
* @param _disable_pgm_fn macro which should expand to function call or a piece of code to disable programming
* @param _severity level of an event
* @param _page_size
* @param pointer_based_access set to true if this event logger target is memory mapped i/o
*/
#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_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, _page_size, 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, _page_size); \
/**
*
*/
#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_true(_name, _area_start_addr, _area_end_addr, _page_size) \
const nvm_state_result_t res##_name = nvm_event_log_find_first_oldest_newest(&nvm_event_oldest##_name, &nvm_event_newest##_name, (void*)_area_start_addr, (void*)_area_end_addr, _page_size); \
if (res##_name == NVM_GENERAL_ERROR) { \
nvm_general_state = res##_name; \
} \
/**
*
*/
#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) \
#define NVM_EVENT_PERFORM_INIT(_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, _page_size, pointer_based_access) \
NVM_EVENT_PERFORM_INIT_##pointer_based_access(_name, _area_start_addr, _area_end_addr, _page_size) \
/// ==================================================================================================
/// GLOBAL MACROS
/// ==================================================================================================
#define NVM_EVENT_GET_SEVERITY(x) (x->severity_and_source & 0xF0) >> 4
#define NVM_EVENT_GET_SOURCE(x) (x->severity_and_source & 0xF)
/// ==================================================================================================
/// GLOBAL DEFINITIONS
/// ==================================================================================================
#ifdef STM32L471xx
@ -138,8 +174,14 @@ if (EVENT_LOG_GET_SEVERITY(event->severity_and_source) >= _severity ) {
//!< How flash program operation are aligned, how many bytes must be programmed at once
#define NVM_WRITE_BYTE_ALIGN 8
#endif
/// ==================================================================================================
/// GLOBAL TYPES
/// ==================================================================================================
#if (defined UNIT_TEST)
// currently defined here for unit tests
typedef enum
{

Wyświetl plik

@ -6,14 +6,14 @@ typedef enum nvm_state_result_t {
NVM_OK,
NVM_NO_SPACE_LEFT,
NVM_INIT_ERROR,
NVM_PGM_ERROR
NVM_PGM_ERROR,
NVM_GENERAL_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_SINGLE,
NVM_EVENT_EMPTY,
NVM_EVENT_AREA_ERROR
}nvm_event_result_t;

Wyświetl plik

@ -6,19 +6,71 @@
*/
#include "event_log.h"
#include "./nvm/nvm_event.h"
#include "main_master_time.h"
/**
* Structure to manage noinit RAM storage and FLASH storage
*/
typedef struct event_log_fifo_t {
uint16_t oldest_event_index;
uint32_t oldest_event_master_time;
event_log_t * oldest_event_pointer;
uint16_t newest_event_index;
uint32_t newest_event_master_time;
event_log_t * newest_event_pointer;
};
/// ==================================================================================================
/// LOCAL DEFINITIONS
/// ==================================================================================================
void event_log_init(uint8_t flash_enabled_severity, uint8_t ram_enabled_severity) {
#define EVENT_LOG_ASYNC_FIFO_LENGTH 16
/// ==================================================================================================
/// LOCAL VARIABLES
/// ==================================================================================================
static event_log_t event_log_async_fifo[EVENT_LOG_ASYNC_FIFO_LENGTH];
static int8_t event_log_fifo_current_depth = 0;
/// ==================================================================================================
/// LOCAL FUNCTIONS
/// ==================================================================================================
void event_log_init (void)
{
memset (event_log_async_fifo, 0x00, sizeof (event_log_t) * EVENT_LOG_ASYNC_FIFO_LENGTH);
event_log_fifo_current_depth = 0;
}
void event_log (event_log_severity_t severity,
event_log_source_t source,
uint8_t event_id,
uint8_t param,
uint8_t param2,
uint16_t wparam,
uint16_t wparam2,
uint32_t lparam,
uint32_t lparam2)
{
}
void event_log_sync (event_log_severity_t severity,
event_log_source_t source,
uint8_t event_id,
uint8_t param,
uint8_t param2,
uint16_t wparam,
uint16_t wparam2,
uint32_t lparam,
uint32_t lparam2)
{
event_log_t new_event = {0u};
// left this to zero, to be automatically set to appropriate value by
// pushing function
new_event.event_counter_id = 0;
new_event.event_id = event_id;
new_event.event_master_time = main_get_master_time();
new_event.severity_and_source = EVENT_LOG_SET_SEVERITY_SOURCE(severity, source);
new_event.param = param;
new_event.param2 = param2;
new_event.wparam = wparam;
new_event.wparam2 = wparam2;
new_event.lparam = lparam;
new_event.lparam2 = lparam2;
nvm_event_log_push_new_event(&new_event);
}

Wyświetl plik

@ -22,6 +22,8 @@
#include "http_client/http_client.h"
#include "./nvm/nvm.h"
#include "./nvm/nvm_event.h"
#include "./event_log.h"
#include "aprsis.h"
#include "api/api.h"
@ -659,6 +661,9 @@ int main(int argc, char* argv[]){
rte_main_reboot_req = 0;
// initialize nvm logger
nvm_event_log_init();
// initializing variables & arrays in rte_wx
rte_wx_init();
rte_rtu_init();

Wyświetl plik

@ -1,32 +1,97 @@
#include "./nvm/nvm_event.h"
#include "./nvm/nvm_internals.h"
#include "nvm_configuration.h"
#include "memory_map.h"
#include "backup_registers.h"
#include "memory_map.h"
#include "nvm_configuration.h"
/// ==================================================================================================
/// LOCAL DATA TYPES
/// ==================================================================================================
/**
*
*/
typedef enum nvm_event_next_t {
NVM_EVENT_NEXT_ERASED, ///!< There is no next element, the next one is just erased memory
NVM_EVENT_NEXT_END, ///!< There is no next element, because the current one is the last
NVM_EVENT_NEXT_OLDER, ///!< Next event is older that the current one
NVM_EVENT_NEXT_NEWER, ///!< Next event is newer (later timestamp)
NVM_EVENT_NEXT_TIMESTAMP, ///!< Next element is a timestamp event
NVM_EVENT_NEXT_UNKNOWN/**< NVM_EVENT_NEXT_UNKNOWN */
} nvm_event_next_t;
/// ==================================================================================================
/// LOCAL VARIABLES
/// ==================================================================================================
/**
* Variable stores a result of last flash operation
*/
static nvm_state_result_t nvm_general_state = NVM_UNINITIALIZED;
NVM_EVENT_LOGGING_TARGETS (NVM_EVENT_CREATE_ENUM_FOR_TARGETS);
NVM_EVENT_LOGGING_TARGETS(NVM_EVENT_CREATE_POINTERS_FOR_TARGET);
/**
* Definition of all pointers, two of them per event logging target area, used
* to find oldest and newest event
*/
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)) {
/// ==================================================================================================
/// LOCAL FUNCTIONS
/// ==================================================================================================
static void nvm_event_erase_all(void *area_start, void *area_end, int16_t page_size) {
#if defined(STM32L471xx)
const uint32_t area_size = (uint32_t) area_end - (uint32_t) area_start;
const int16_t pages = area_size / page_size;
FLASH_Unlock();
for (int i = 0; i < pages; i++) {
FLASH_ErasePage((uint32_t)area_start + (i * page_size));
}
FLASH_Lock();
#endif
}
/**
*
* @param oldest
* @param newest
* @param area_start
* @param area_end
* @param erase_fn
*/
static void nvm_event_log_perform_pointer_arithmetics (event_log_t **oldest,
event_log_t **newest,
void *area_start,
void *area_end,
uint32_t *next_event_counter_id,
FLASH_Status (*erase_fn) (uint32_t),
int16_t page_size)
{
*next_event_counter_id = (*newest)->event_counter_id + 1;
if (*next_event_counter_id == 0xFFFFFFFFU) {
*next_event_counter_id = 0x1U;
}
// pointers
const event_log_t* oldest_init_ptr = *oldest;
const event_log_t* next_newest_init_ptr = *newest + 1;
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);
const FLASH_Status flash_status = erase_fn ((intptr_t)*oldest);
/* check operation result */
if (flash_status != FLASH_COMPLETE) {
@ -34,37 +99,57 @@ static void nvm_event_log_perform_pointer_arithmetics(
}
/* rescan for oldest and newest event one more time */
nvm_event_log_find_first_oldest_newest(oldest, newest, (void*)area_start, (void*)area_end);
nvm_event_log_find_first_oldest_newest (oldest, newest, (void *)area_start,
(void *)area_end, page_size);
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);
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) {
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);
(void)erase_fn ((intptr_t)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));
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;
}
}
}
/// ==================================================================================================
/// GLOBAL FUNCTIONS
/// ==================================================================================================
/**
*
*/
void nvm_event_log_init(void)
{
NVM_EVENT_LOGGING_TARGETS(NVM_EVENT_PERFORM_INIT);
if (nvm_general_state == NVM_GENERAL_ERROR) {
nvm_event_erase_all((void*)MEMORY_MAP_EVENT_LOG_START, (void*)MEMORY_MAP_EVENT_LOG_END, NVM_PAGE_SIZE);
}
}
/**
@ -72,100 +157,95 @@ static void nvm_event_log_perform_pointer_arithmetics(
* @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 nvm_event_log_find_first_oldest_newest (
event_log_t **oldest, event_log_t **newest, void *area_start, void *area_end, int16_t page_size)
{
nvm_event_result_t res = NVM_EVENT_OK;
// pointer to last, non null and non TIMESYNC entry
event_log_t* last_non_ts = 0x0;
// pointer to the oldest non TIMESYNC event log entry
event_log_t* oldest_non_ts = 0x0;
// size of single log entry
const uint8_t log_entry_size = sizeof(event_log_t);
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;
#ifndef NVM_EVENT_PAGE_SIZE_CHECK_WITH_ADDRESS_PTR
const int8_t page_size_in_events = page_size / log_entry_size;
#endif
uint32_t lowest_time = 0xFFFFFFFFu;
// lowest date found within events in NVM
uint32_t lowest_counter_id = 0xFFFFFFFFu;
// highest counter id found within events in NVM
uint32_t highest_counter_id = 0x0u;
// as name suggest this is a counter value of last
// event found
uint32_t previous_counter_id = 0u;
// sanity check if everything is set correctly
if ((area_end - area_start) % log_entry_size != 0 ) {
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++) {
// temp pointer to currently processed event
const event_log_t *const current = ((const event_log_t *)area_start) + i;
// set pointer to currently checked event
const event_log_t* const current = (area_start + (log_entry_size) * i);
// do not go through erased flash memory on uninitialized RAM. The first valid counter
// value is 1 and the last valid is 0xFFFFFFFE
if (current->event_counter_id != 0x0u && current->event_counter_id != 0xFFFFFFFFu) {
//event_log_severity_t severity = (current->severity_and_source & 0xF0) >> 4;
//event_log_source_t source = (current->severity_and_source & 0xF);
// check if this event counter id value is lower than a previous one
if (current->event_counter_id < previous_counter_id) {
// skip erased memory
if (current->event_id == 0xFFU && current->event_master_time == 0xFFFFFFFFU) {
oldest_non_ts = 0x00;
continue;
}
// look for timesync event created at bootup
if (current->event_id == EVENT_TIMESYNC && current->wparam == EVENT_LOG_TIMESYNC_BOOTUP_WPARAM) {
// 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 == 0x0) {
oldest_non_ts = (event_log_t*)current;
// address of next event element
//const intptr_t address_of_current = (intptr_t)((void *)current);
#ifndef NVM_EVENT_PAGE_SIZE_CHECK_WITH_ADDRESS_PTR
// check if this is a boundary of two flash areas
if (page_size == 0 || (i % page_size_in_events) == 0) {
#else
// check if this is a boundary of two flash areas
if (page_size == 0 || (address_of_current % page_size) == 0) {
#endif
// we are fine. event counter for consecutive events
// can be decreasing on an edge of memory pages.
// this check is also enabled if page_size is set to
// zero, what is a case for RAM, freely accessible
// for read and write in single byte granularity.
// no explicit erasure is required
res = NVM_EVENT_OVERRUN;
}
else {
// NVM event area is screwed very badly and cannot be recovered at all
// it must be formatted and reinitialized from scratch
return NVM_EVENT_AREA_ERROR;
}
}
previous_counter_id = current->event_counter_id;
if (current->event_counter_id < lowest_counter_id) {
lowest_counter_id = current->event_counter_id;
// the smallest counter id is, the older this event is
*oldest = (event_log_t*)current;
}
if (current->event_counter_id > highest_counter_id) {
highest_counter_id = current->event_counter_id;
// the higher counter id is, the newer this event is
*newest = (event_log_t*)current;
}
}
}
// check if any non-timesync event has been found at all
if (last_non_ts == 0x0) {
// 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;
}
// if these values have not been updated, the memory is in erased state
if ((lowest_counter_id == 0xFFFFFFFFu) && (highest_counter_id == 0x0u)) {
res = NVM_EVENT_EMPTY;
}
return res;
@ -177,12 +257,11 @@ 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) {
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);
NVM_EVENT_LOGGING_TARGETS (NVM_EVENT_EXPAND_POINTER_BASE_ACCESS);
return out;
}