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;
}
/** @} */