From d0cf95db49b5fcbd03d67b4077646fbdc3aaee87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Sat, 5 Sep 2020 20:06:13 +0200 Subject: [PATCH] Issue #18: further iomplementation of safety memory --- .../reflow-controller/safety/safety-memory.h | 1 + stm-firmware/safety/safety-memory.c | 95 ++++++++++++++++++- 2 files changed, 92 insertions(+), 4 deletions(-) diff --git a/stm-firmware/include/reflow-controller/safety/safety-memory.h b/stm-firmware/include/reflow-controller/safety/safety-memory.h index 2d3bce9..18946ac 100644 --- a/stm-firmware/include/reflow-controller/safety/safety-memory.h +++ b/stm-firmware/include/reflow-controller/safety/safety-memory.h @@ -95,6 +95,7 @@ enum safety_memory_error_entry_type { struct error_memory_entry { enum safety_memory_error_entry_type type; uint8_t flag_num; + uint16_t counter; }; enum config_override_entry_type { diff --git a/stm-firmware/safety/safety-memory.c b/stm-firmware/safety/safety-memory.c index a1915b4..864a8e2 100644 --- a/stm-firmware/safety/safety-memory.c +++ b/stm-firmware/safety/safety-memory.c @@ -24,6 +24,46 @@ #define wordsize_of(x) ((sizeof(x) / 4U) / ((sizeof(x) % 4U) ? 0U : 1U)) +static int word_to_error_memory_entry(uint32_t entry_data, struct error_memory_entry *out) +{ + int ret = 0; + + if (!out) + return -1002; + + if (entry_data == SAFETY_MEMORY_ERR_ENTRY_NOP) { + out->flag_num = 0U; + out->type = SAFETY_MEMORY_ERR_ENTRY_NOP; + out->counter = 0U; + } else if ((entry_data & 0xFFU) == 0x51U) { + out->flag_num = (uint8_t)((entry_data >> 8U) & 0xFFU); + out->type = SAFETY_MEMORY_ERR_ENTRY_FLAG; + out->counter = (uint16_t)((entry_data >> 16U) & 0xFFFF); + } else { + /* Invalid entry */ + ret = -1; + } + + return ret; +} + +static uint32_t error_memory_entry_to_word(const struct error_memory_entry *entry) +{ + uint32_t word = 0; + + switch (entry->type) { + case SAFETY_MEMORY_ERR_ENTRY_NOP: + word = SAFETY_MEMORY_NOP_ENTRY; + break; + case SAFETY_MEMORY_ERR_ENTRY_FLAG: + word = 0x51UL | ((uint32_t)entry->flag_num << 8U) | + ((uint32_t)entry->counter << 16U); + break; + } + + return word; +} + static enum safety_memory_state safety_memory_get_header(struct safety_memory_header *header) { @@ -156,8 +196,8 @@ int safety_memory_reinit(enum safety_memory_state *found_state) switch (*found_state) { case SAFETY_MEMORY_INIT_VALID_MEMORY: - /* Valid memory detected. Check CRC */ - res = safety_memory_check_crc(); + /* Valid memory detected. Check CRC and error entries */ + res = safety_memory_check(); if (res) *found_state = SAFETY_MEMORY_INIT_CORRUPTED; break; @@ -268,7 +308,21 @@ static int safety_memory_check_error_entries() return ret; } -int safety_memory_get_error_entry_count(uint32_t *count); +int safety_memory_get_error_entry_count(uint32_t *count) +{ + struct safety_memory_header header; + + if (!count) + return -1001; + + if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY) { + return -2000; + } + + *count = header.err_memory_end - header.err_memory_offset; + + return 0; +} int safety_memory_check(void) { @@ -282,7 +336,40 @@ int safety_memory_check(void) return -!!res; } -int safety_memory_get_error_entry(uint32_t idx, struct error_memory_entry *entry); +int safety_memory_get_error_entry(uint32_t idx, struct error_memory_entry *entry) +{ + struct safety_memory_header header; + uint32_t err_mem_count; + int ret = -1; + int res; + uint32_t data; + + if (!entry) + return -1001; + + if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY) { + return -2000; + } + + err_mem_count = header.err_memory_end - header.err_memory_offset; + if (idx < err_mem_count && err_mem_count > 0) { + res = backup_ram_get_data(header.err_memory_offset + idx, &data, 1UL); + if (res) + goto return_value; + + res = word_to_error_memory_entry(data, entry); + if (res) + goto return_value; + ret = 0; + + } else { + /* out of range */ + ret = -1001; + } + +return_value: + return ret; +} int safety_memory_insert_error_entry(struct error_memory_entry *entry);