mirror of
https://github.com/dalathegreat/Battery-Emulator.git
synced 2025-10-03 17:59:27 +02:00
First commit
This commit is contained in:
parent
df3acc7401
commit
23e62defb5
2 changed files with 0 additions and 175 deletions
|
@ -1,40 +1,7 @@
|
|||
#include "events.h"
|
||||
#include "../../datalayer/datalayer.h"
|
||||
#ifndef UNIT_TEST
|
||||
#include <EEPROM.h>
|
||||
#endif
|
||||
|
||||
#include "../../../USER_SETTINGS.h"
|
||||
#include "timer.h"
|
||||
|
||||
#define EE_NOF_EVENT_ENTRIES 30
|
||||
#define EE_EVENT_ENTRY_SIZE sizeof(EVENT_LOG_ENTRY_TYPE)
|
||||
#define EE_WRITE_PERIOD_MINUTES 10
|
||||
|
||||
/** EVENT LOG STRUCTURE
|
||||
*
|
||||
* The event log is stored in a simple header-block structure. The
|
||||
* header contains a magic number to identify it as an event log,
|
||||
* a head index and a tail index. The head index points to the last
|
||||
* recorded event, the tail index points to the "oldest" event in the
|
||||
* log. The event log is set up like a circular buffer, so we only
|
||||
* store the set amount of events. The head continuously overwrites
|
||||
* the oldest events, and both the head and tail indices wrap around
|
||||
* to 0 at the end of the event log:
|
||||
*
|
||||
* [ HEADER ]
|
||||
* [ MAGIC NUMBER ][ HEAD INDEX ][ TAIL INDEX ][ EVENT BLOCK 0 ][ EVENT BLOCK 1]...
|
||||
* [ 2 bytes ][ 2 bytes ][ 2 bytes ][ 6 bytes ][ 6 bytes ]
|
||||
*
|
||||
* 1024 bytes are allocated to the event log in flash emulated EEPROM,
|
||||
* giving room for (1024 - (2 + 2 + 2)) / 6 ~= 169 events
|
||||
*
|
||||
* For now, we store 30 to make it easier to handle initial debugging.
|
||||
*/
|
||||
#define EE_EVENT_LOG_START_ADDRESS 0
|
||||
#define EE_EVENT_LOG_HEAD_INDEX_ADDRESS EE_EVENT_LOG_START_ADDRESS + 2
|
||||
#define EE_EVENT_LOG_TAIL_INDEX_ADDRESS EE_EVENT_LOG_HEAD_INDEX_ADDRESS + 2
|
||||
#define EE_EVENT_ENTRY_START_ADDRESS EE_EVENT_LOG_TAIL_INDEX_ADDRESS + 2
|
||||
|
||||
typedef struct {
|
||||
EVENTS_ENUM_TYPE event;
|
||||
|
@ -45,12 +12,7 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
EVENTS_STRUCT_TYPE entries[EVENT_NOF_EVENTS];
|
||||
MyTimer ee_timer;
|
||||
EVENTS_LEVEL_TYPE level;
|
||||
uint16_t event_log_head_index;
|
||||
uint16_t event_log_tail_index;
|
||||
uint8_t nof_logged_events;
|
||||
uint16_t nof_eeprom_writes;
|
||||
} EVENT_TYPE;
|
||||
|
||||
/* Local variables */
|
||||
|
@ -62,54 +24,14 @@ static const char* EVENTS_LEVEL_TYPE_STRING[] = {EVENTS_LEVEL_TYPE(GENERATE_STRI
|
|||
static void set_event(EVENTS_ENUM_TYPE event, uint8_t data, bool latched);
|
||||
static void update_event_level(void);
|
||||
static void update_bms_status(void);
|
||||
static void log_event(EVENTS_ENUM_TYPE event, uint8_t millisrolloverCount, uint32_t timestamp, uint8_t data);
|
||||
static void print_event_log(void);
|
||||
|
||||
/* Initialization function */
|
||||
void init_events(void) {
|
||||
|
||||
EEPROM.begin(1024);
|
||||
events.nof_logged_events = 0;
|
||||
|
||||
uint16_t header = EEPROM.readUShort(EE_EVENT_LOG_START_ADDRESS);
|
||||
if (header != EE_MAGIC_HEADER_VALUE) {
|
||||
// The header doesn't appear to be a compatible event log, clear it and initialize
|
||||
EEPROM.writeUShort(EE_EVENT_LOG_START_ADDRESS, EE_MAGIC_HEADER_VALUE);
|
||||
EEPROM.writeUShort(EE_EVENT_LOG_HEAD_INDEX_ADDRESS, 0);
|
||||
EEPROM.writeUShort(EE_EVENT_LOG_TAIL_INDEX_ADDRESS, 0);
|
||||
|
||||
// Prepare an empty event block to write
|
||||
EVENT_LOG_ENTRY_TYPE entry = {.event = EVENT_NOF_EVENTS, .millisrolloverCount = 0, .timestamp = 0, .data = 0};
|
||||
|
||||
// Put the event in (what I guess is) the RAM EEPROM mirror, or write buffer
|
||||
|
||||
for (int i = 0; i < EE_NOF_EVENT_ENTRIES; i++) {
|
||||
// Start at the oldest event, work through the log all the way the the head
|
||||
int address = EE_EVENT_ENTRY_START_ADDRESS + EE_EVENT_ENTRY_SIZE * i;
|
||||
EEPROM.put(address, entry);
|
||||
}
|
||||
|
||||
// Push changes to eeprom
|
||||
EEPROM.commit();
|
||||
#ifdef DEBUG_LOG
|
||||
logging.println("EEPROM wasn't ready");
|
||||
#endif
|
||||
} else {
|
||||
events.event_log_head_index = EEPROM.readUShort(EE_EVENT_LOG_HEAD_INDEX_ADDRESS);
|
||||
events.event_log_tail_index = EEPROM.readUShort(EE_EVENT_LOG_TAIL_INDEX_ADDRESS);
|
||||
#ifdef DEBUG_LOG
|
||||
logging.println("EEPROM was initialized for event logging");
|
||||
logging.println("head: " + String(events.event_log_head_index) + ", tail: " + String(events.event_log_tail_index));
|
||||
#endif
|
||||
print_event_log();
|
||||
}
|
||||
|
||||
for (uint16_t i = 0; i < EVENT_NOF_EVENTS; i++) {
|
||||
events.entries[i].data = 0;
|
||||
events.entries[i].timestamp = 0;
|
||||
events.entries[i].millisrolloverCount = 0;
|
||||
events.entries[i].occurences = 0;
|
||||
events.entries[i].log = true;
|
||||
events.entries[i].MQTTpublished = false; // Not published by default
|
||||
}
|
||||
|
||||
|
@ -176,7 +98,6 @@ void init_events(void) {
|
|||
events.entries[EVENT_SERIAL_RX_FAILURE].level = EVENT_LEVEL_ERROR;
|
||||
events.entries[EVENT_SERIAL_TX_FAILURE].level = EVENT_LEVEL_ERROR;
|
||||
events.entries[EVENT_SERIAL_TRANSMITTER_FAILURE].level = EVENT_LEVEL_ERROR;
|
||||
events.entries[EVENT_EEPROM_WRITE].level = EVENT_LEVEL_INFO;
|
||||
events.entries[EVENT_RESET_UNKNOWN].level = EVENT_LEVEL_INFO;
|
||||
events.entries[EVENT_RESET_POWERON].level = EVENT_LEVEL_INFO;
|
||||
events.entries[EVENT_RESET_EXT].level = EVENT_LEVEL_INFO;
|
||||
|
@ -206,11 +127,6 @@ void init_events(void) {
|
|||
events.entries[EVENT_PERIODIC_BMS_RESET_AT_INIT_SUCCESS].level = EVENT_LEVEL_INFO;
|
||||
events.entries[EVENT_PERIODIC_BMS_RESET_AT_INIT_FAILED].level = EVENT_LEVEL_WARNING;
|
||||
events.entries[EVENT_BATTERY_TEMP_DEVIATION_HIGH].level = EVENT_LEVEL_WARNING;
|
||||
|
||||
events.entries[EVENT_EEPROM_WRITE].log = false; // Don't log the logger...
|
||||
|
||||
// Write to EEPROM every X minutes (if an event has been set)
|
||||
events.ee_timer.set_interval(EE_WRITE_PERIOD_MINUTES * 60 * 1000);
|
||||
}
|
||||
|
||||
void set_event(EVENTS_ENUM_TYPE event, uint8_t data) {
|
||||
|
@ -230,14 +146,12 @@ void clear_event(EVENTS_ENUM_TYPE event) {
|
|||
}
|
||||
|
||||
void reset_all_events() {
|
||||
events.nof_logged_events = 0;
|
||||
for (uint16_t i = 0; i < EVENT_NOF_EVENTS; i++) {
|
||||
events.entries[i].data = 0;
|
||||
events.entries[i].state = EVENT_STATE_INACTIVE;
|
||||
events.entries[i].timestamp = 0;
|
||||
events.entries[i].millisrolloverCount = 0;
|
||||
events.entries[i].occurences = 0;
|
||||
events.entries[i].log = true;
|
||||
events.entries[i].MQTTpublished = false; // Not published by default
|
||||
}
|
||||
events.level = EVENT_LEVEL_INFO;
|
||||
|
@ -386,8 +300,6 @@ const char* get_event_message_string(EVENTS_ENUM_TYPE event) {
|
|||
return "OTA update started!";
|
||||
case EVENT_OTA_UPDATE_TIMEOUT:
|
||||
return "OTA update timed out!";
|
||||
case EVENT_EEPROM_WRITE:
|
||||
return "The EEPROM was written";
|
||||
case EVENT_RESET_UNKNOWN:
|
||||
return "The board was reset unexpectedly, and reason can't be determined";
|
||||
case EVENT_RESET_POWERON:
|
||||
|
@ -482,9 +394,6 @@ static void set_event(EVENTS_ENUM_TYPE event, uint8_t data, bool latched) {
|
|||
(events.entries[event].state != EVENT_STATE_ACTIVE_LATCHED)) {
|
||||
events.entries[event].occurences++;
|
||||
events.entries[event].MQTTpublished = false;
|
||||
if (events.entries[event].log) {
|
||||
log_event(event, events.entries[event].millisrolloverCount, events.entries[event].timestamp, data);
|
||||
}
|
||||
#ifdef DEBUG_LOG
|
||||
logging.print("Event: ");
|
||||
logging.println(get_event_message_string(event));
|
||||
|
@ -547,69 +456,3 @@ static void update_event_level(void) {
|
|||
}
|
||||
events.level = temporary_level;
|
||||
}
|
||||
|
||||
static void log_event(EVENTS_ENUM_TYPE event, uint8_t millisrolloverCount, uint32_t timestamp, uint8_t data) {
|
||||
// Update head with wrap to 0
|
||||
if (++events.event_log_head_index == EE_NOF_EVENT_ENTRIES) {
|
||||
events.event_log_head_index = 0;
|
||||
}
|
||||
|
||||
// If the head now points to the tail, move the tail, with wrap to 0
|
||||
if (events.event_log_head_index == events.event_log_tail_index) {
|
||||
if (++events.event_log_tail_index == EE_NOF_EVENT_ENTRIES) {
|
||||
events.event_log_tail_index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// The head now holds the index to the oldest event, the one we want to overwrite,
|
||||
// so calculate the absolute address
|
||||
int entry_address = EE_EVENT_ENTRY_START_ADDRESS + EE_EVENT_ENTRY_SIZE * events.event_log_head_index;
|
||||
|
||||
// Prepare an event block to write
|
||||
EVENT_LOG_ENTRY_TYPE entry = {.event = event,
|
||||
.millisrolloverCount = datalayer.system.status.millisrolloverCount,
|
||||
.timestamp = timestamp,
|
||||
.data = data};
|
||||
|
||||
// Put the event in (what I guess is) the RAM EEPROM mirror, or write buffer
|
||||
EEPROM.put(entry_address, entry);
|
||||
|
||||
// Store the new indices
|
||||
EEPROM.writeUShort(EE_EVENT_LOG_HEAD_INDEX_ADDRESS, events.event_log_head_index);
|
||||
EEPROM.writeUShort(EE_EVENT_LOG_TAIL_INDEX_ADDRESS, events.event_log_tail_index);
|
||||
//logging.println("Wrote event " + String(event) + " to " + String(entry_address));
|
||||
//logging.println("head: " + String(events.event_log_head_index) + ", tail: " + String(events.event_log_tail_index));
|
||||
|
||||
// We don't need the exact number, it's just for deciding to store or not
|
||||
events.nof_logged_events += (events.nof_logged_events < 255) ? 1 : 0;
|
||||
}
|
||||
|
||||
static void print_event_log(void) {
|
||||
// If the head actually points to the tail, the log is probably blank
|
||||
if (events.event_log_head_index == events.event_log_tail_index) {
|
||||
#ifdef DEBUG_LOG
|
||||
logging.println("No events in log");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
EVENT_LOG_ENTRY_TYPE entry;
|
||||
|
||||
for (int i = 0; i < EE_NOF_EVENT_ENTRIES; i++) {
|
||||
// Start at the oldest event, work through the log all the way the the head
|
||||
int index = ((events.event_log_tail_index + i) % EE_NOF_EVENT_ENTRIES);
|
||||
int address = EE_EVENT_ENTRY_START_ADDRESS + EE_EVENT_ENTRY_SIZE * index;
|
||||
|
||||
EEPROM.get(address, entry);
|
||||
if (entry.event == EVENT_NOF_EVENTS) {
|
||||
// The entry is a blank that has been left behind somehow
|
||||
continue;
|
||||
}
|
||||
#ifdef DEBUG_LOG
|
||||
logging.println("Event: " + String(get_event_enum_string(entry.event)) + ", data: " + String(entry.data) +
|
||||
", time: " + String(entry.timestamp));
|
||||
#endif
|
||||
if (index == events.event_log_head_index) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue