Improve code and add a Flash CRC check

This commit is contained in:
2021-07-16 21:17:59 +02:00
parent 864c3fa0f2
commit 1e870972e3
10 changed files with 266 additions and 11 deletions

View File

@@ -153,6 +153,15 @@ struct overtemp_config {
uint32_t crc;
};
struct flash_crcs {
uint32_t start_magic;
uint32_t crc_section_text;
uint32_t crc_section_data;
uint32_t crc_section_ccm_data;
uint32_t crc_section_vectors;
uint32_t end_magic;
};
/**
* @brief All safety error flags.
*/
@@ -176,6 +185,8 @@ static volatile struct error_flag IN_SECTION(.ccm.data) flags[] = {
ERR_FLAG_ENTRY(ERR_FLAG_SAFETY_TAB_CORRUPT),
ERR_FLAG_ENTRY(ERR_FLAG_AMON_SUPPLY_VOLT),
ERR_FLAG_ENTRY(ERR_FLAG_OVERTEMP),
ERR_FLAG_ENTRY(ERR_FLAG_FLASH_CRC_CODE),
ERR_FLAG_ENTRY(ERR_FLAG_FLASH_CRC_DATA),
};
/**
@@ -257,7 +268,7 @@ static void set_overtemp_config(float over_temperature)
int result;
float resistance;
result = temp_convertet_convert_temp_to_resistance(over_temperature, &resistance);
result = temp_converter_convert_temp_to_resistance(over_temperature, &resistance);
/* An error in this function is really bad... */
if (result < -1)
panic_mode();
@@ -764,6 +775,7 @@ void safety_controller_init()
/* This is usually done by the safety memory already. But, since this module also uses the CRC... */
crc_unit_init();
safety_controller_trigger_flash_crc_check();
stack_check_init_corruption_detect_area();
hw_rev = get_pcb_hardware_version();
@@ -1296,4 +1308,102 @@ float safety_controller_get_overtemp_limit(void)
return safety_controller_overtemp_config.overtemp_deg_celsius;
}
extern const uint32_t __ld_vectors_start;
extern const uint32_t __ld_vectors_end;
extern const uint32_t __ld_text_start;
extern const uint32_t __ld_text_end;
extern const uint32_t __ld_sdata_ccm;
extern const uint32_t __ld_edata_ccm;
extern const uint32_t __ld_load_ccm_data;
extern const uint32_t __ld_sdata;
extern const uint32_t __ld_edata;
extern const uint32_t __ld_load_data;
int safety_controller_trigger_flash_crc_check()
{
/* This structs needs to be volatile!!
* This prevents the compiler form optimizing out the reads to the crcs which will be patched in later by
* a separate python script!
*/
static volatile const struct flash_crcs IN_SECTION(.flashcrc) crcs_in_flash =
{
.start_magic = 0xA8BE53F9UL,
.crc_section_ccm_data = 0UL,
.crc_section_text = 0UL,
.crc_section_data = 0UL,
.crc_section_vectors = 0UL,
.end_magic = 0xFFA582FFUL,
};
int ret = -1;
uint32_t len;
uint32_t crc;
/* Perform CRC check over vector table */
len = (uint32_t)((void *)&__ld_vectors_end - (void *)&__ld_vectors_start);
if (len % 4) {
safety_controller_report_error(ERR_FLAG_FLASH_CRC_CODE);
} else {
len /= 4;
crc_unit_reset();
crc_unit_input_array(&__ld_vectors_start, len);
crc = crc_unit_get_crc();
if (crc != crcs_in_flash.crc_section_vectors) {
safety_controller_report_error(ERR_FLAG_FLASH_CRC_CODE);
}
}
/* Perform CRC check over text section */
len = (uint32_t)((void *)&__ld_text_end - (void *)&__ld_text_start);
if (len % 4) {
safety_controller_report_error(ERR_FLAG_FLASH_CRC_CODE);
} else {
len /= 4;
crc_unit_reset();
crc_unit_input_array(&__ld_text_start, len);
crc = crc_unit_get_crc();
if (crc != crcs_in_flash.crc_section_text) {
safety_controller_report_error(ERR_FLAG_FLASH_CRC_CODE);
}
}
/* Perform CRC check over data section */
len = (uint32_t)((void *)&__ld_edata - (void *)&__ld_sdata);
if (len % 4) {
safety_controller_report_error(ERR_FLAG_FLASH_CRC_DATA);
} else {
len /= 4;
crc_unit_reset();
crc_unit_input_array(&__ld_load_data, len);
crc = crc_unit_get_crc();
if (crc != crcs_in_flash.crc_section_data) {
safety_controller_report_error(ERR_FLAG_FLASH_CRC_DATA);
}
}
/* Perform CRC check over ccm data section */
len = (uint32_t)((void *)&__ld_edata_ccm - (void *)&__ld_sdata_ccm);
if (len % 4) {
safety_controller_report_error(ERR_FLAG_FLASH_CRC_DATA);
} else {
len /= 4;
crc_unit_reset();
crc_unit_input_array(&__ld_load_ccm_data, len);
crc = crc_unit_get_crc();
if (crc != crcs_in_flash.crc_section_ccm_data) {
safety_controller_report_error(ERR_FLAG_FLASH_CRC_DATA);
}
}
crc_unit_reset();
crc_unit_input(0x04030201);
crc_unit_input(0xA0B0C0D0);
crc = crc_unit_get_crc();
ret = 0;
return ret;
}
/** @} */

View File

@@ -35,11 +35,11 @@ static int word_to_error_memory_entry(uint32_t entry_data, struct error_memory_e
if (!out)
return -1002;
if (entry_data == SAFETY_MEMORY_NOP_ENTRY) {
if (entry_data == SAFETY_MEMORY_NOP_ENTRY_WORD) {
out->flag_num = 0U;
out->type = SAFETY_MEMORY_ERR_ENTRY_NOP;
out->counter = 0U;
} else if ((entry_data & 0xFFU) == 0x51U) {
} else if ((entry_data & 0xFFU) == SAFETY_MEMORY_ERROR_ENTRY_MARKER) {
out->flag_num = (uint8_t)((entry_data >> 8U) & 0xFFU);
out->type = SAFETY_MEMORY_ERR_ENTRY_FLAG;
out->counter = (uint16_t)((entry_data >> 16U) & 0xFFFF);
@@ -57,10 +57,10 @@ static uint32_t error_memory_entry_to_word(const struct error_memory_entry *entr
switch (entry->type) {
case SAFETY_MEMORY_ERR_ENTRY_NOP:
word = SAFETY_MEMORY_NOP_ENTRY;
word = SAFETY_MEMORY_NOP_ENTRY_WORD;
break;
case SAFETY_MEMORY_ERR_ENTRY_FLAG:
word = 0x51UL | ((uint32_t)entry->flag_num << 8U) |
word = (uint32_t)SAFETY_MEMORY_ERROR_ENTRY_MARKER | ((uint32_t)entry->flag_num << 8U) |
((uint32_t)entry->counter << 16U);
break;
}
@@ -322,9 +322,9 @@ static int safety_memory_check_error_entries()
return -100;
/* Valid flag entry */
if ((data & 0xFF) == 0x51)
if ((data & 0xFF) == SAFETY_MEMORY_ERROR_ENTRY_MARKER)
continue;
if (data == SAFETY_MEMORY_NOP_ENTRY)
if (data == SAFETY_MEMORY_NOP_ENTRY_WORD)
continue;
ret--;