Improve code and add a Flash CRC check
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
@@ -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--;
|
||||
|
Reference in New Issue
Block a user