Improve code and add a Flash CRC check
This commit is contained in:
		@@ -45,6 +45,7 @@ endif (GIT_FOUND)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
set(ELFFILE ${PROJECT_NAME}.elf)
 | 
					set(ELFFILE ${PROJECT_NAME}.elf)
 | 
				
			||||||
set(HEXFILE ${PROJECT_NAME}.hex)
 | 
					set(HEXFILE ${PROJECT_NAME}.hex)
 | 
				
			||||||
 | 
					set(MAPFILE ${PROJECT_NAME}.map)
 | 
				
			||||||
set(LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/stm32f407vet6_flash.ld)
 | 
					set(LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/stm32f407vet6_flash.ld)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
add_compile_options(-Wall -Wextra -Wold-style-declaration -Wuninitialized -Wmaybe-uninitialized -Wunused-parameter)
 | 
					add_compile_options(-Wall -Wextra -Wold-style-declaration -Wuninitialized -Wmaybe-uninitialized -Wunused-parameter)
 | 
				
			||||||
@@ -62,6 +63,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
 | 
				
			|||||||
IF(CMAKE_BUILD_TYPE STREQUAL "Debug")
 | 
					IF(CMAKE_BUILD_TYPE STREQUAL "Debug")
 | 
				
			||||||
	add_definitions(-DDEBUGBUILD)
 | 
						add_definitions(-DDEBUGBUILD)
 | 
				
			||||||
	add_compile_options(-O0 -g)
 | 
						add_compile_options(-O0 -g)
 | 
				
			||||||
 | 
						add_link_options(-Wl,-Map=${MAPFILE})
 | 
				
			||||||
ELSE()
 | 
					ELSE()
 | 
				
			||||||
	add_compile_options(-O3 -g)
 | 
						add_compile_options(-O3 -g)
 | 
				
			||||||
	add_link_options(-Wl,--gc-sections)
 | 
						add_link_options(-Wl,--gc-sections)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										113
									
								
								stm-firmware/crc-patch-elf.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										113
									
								
								stm-firmware/crc-patch-elf.py
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,113 @@
 | 
				
			|||||||
 | 
					#!/bin/python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					This script patches the CRC checksums into an existing ELF file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For this, it searches the follwoing sections:
 | 
				
			||||||
 | 
						1) .text
 | 
				
			||||||
 | 
						2) .data
 | 
				
			||||||
 | 
						3) .ccmdata
 | 
				
			||||||
 | 
						4) .vectors
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					All sections MUST be a multiple of 4 bytes long because the CRC calculation relies on whole 32 bit words.
 | 
				
			||||||
 | 
					The sections are excrated and the CRC is calculated for each section.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In the section .flashcrc, the script expects a single struct with the prototype:
 | 
				
			||||||
 | 
					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;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					It checks, if the start magic and end magic are set to the appropriate values and then patches in the CRC values of the sections.
 | 
				
			||||||
 | 
					The magic values checked for are: 0xA8BE53F9 and 0xFFA582FF
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					from elftools.elf.elffile import ELFFile
 | 
				
			||||||
 | 
					from elftools.elf.segments import Segment
 | 
				
			||||||
 | 
					import elftools.elf.constants as elf_const
 | 
				
			||||||
 | 
					import sys
 | 
				
			||||||
 | 
					import crcmod
 | 
				
			||||||
 | 
					import crcmod.predefined
 | 
				
			||||||
 | 
					import struct
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					crc_calc = crcmod.predefined.mkCrcFun('crc-32-mpeg')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if len(sys.argv) < 2:
 | 
				
			||||||
 | 
						print("Usage:", sys.argv[0], ' <elf file>')
 | 
				
			||||||
 | 
						sys.exit(-1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					filename=sys.argv[1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def section_calculate_crc(section):
 | 
				
			||||||
 | 
						data = bytearray(section.data())
 | 
				
			||||||
 | 
						be_data = bytearray([0 for k in range(0, len(data))])
 | 
				
			||||||
 | 
						# Rearrange data, because the STM controller sees it as 32 bit little endian words
 | 
				
			||||||
 | 
						for i in range(0, int(len(data)/4)):
 | 
				
			||||||
 | 
							be_data[i*4+0] = data[i*4+3]
 | 
				
			||||||
 | 
							be_data[i*4+1] = data[i*4+2]
 | 
				
			||||||
 | 
							be_data[i*4+2] = data[i*4+1]
 | 
				
			||||||
 | 
							be_data[i*4+3] = data[i*4+0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return crc_calc(be_data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					with open(filename, 'r+b') as f:
 | 
				
			||||||
 | 
						elf = ELFFile(f)
 | 
				
			||||||
 | 
						sections = {}
 | 
				
			||||||
 | 
						sections['.text'] = elf.get_section_by_name('.text')
 | 
				
			||||||
 | 
						sections['.data'] = elf.get_section_by_name('.data')
 | 
				
			||||||
 | 
						sections['.ccmdata'] = elf.get_section_by_name('.ccmdata')
 | 
				
			||||||
 | 
						sections['.vectors'] = elf.get_section_by_name('.vectors')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for key, sec in sections.items():
 | 
				
			||||||
 | 
							if sec is None:
 | 
				
			||||||
 | 
								print("Error! Section", key, "not found in ELF file!")
 | 
				
			||||||
 | 
								sys.exit(-1)
 | 
				
			||||||
 | 
							print('Found section', key, 'Size:',
 | 
				
			||||||
 | 
								  sec.data_size, 'Type:', sec['sh_type'])
 | 
				
			||||||
 | 
							if sec['sh_type'] != 'SHT_PROGBITS':
 | 
				
			||||||
 | 
								print('Error! Section must be of type SHT_PROGBITS')
 | 
				
			||||||
 | 
								sys.exit(-1)
 | 
				
			||||||
 | 
							if (sec.data_size % 4 != 0):
 | 
				
			||||||
 | 
								print("Section", key, "has wrong size. Must be a multiple of 4 bytes!")
 | 
				
			||||||
 | 
								sys.exit(-1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						text_crc = section_calculate_crc(sections['.text'])
 | 
				
			||||||
 | 
						print('CRC of .text section:', hex(text_crc))
 | 
				
			||||||
 | 
						data_crc = section_calculate_crc(sections['.data'])
 | 
				
			||||||
 | 
						print('CRC of .data section:', hex(data_crc))
 | 
				
			||||||
 | 
						ccmdata_crc = section_calculate_crc(sections['.ccmdata'])
 | 
				
			||||||
 | 
						print('CRC of .ccmdata section:', hex(ccmdata_crc))
 | 
				
			||||||
 | 
						vextors_crc = section_calculate_crc(sections['.vectors'])
 | 
				
			||||||
 | 
						print('CRC of .vectors section:', hex(vextors_crc))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# Check the flashcrc section
 | 
				
			||||||
 | 
						flashcrc_sec = elf.get_section_by_name('.flashcrc')
 | 
				
			||||||
 | 
						if flashcrc_sec is None:
 | 
				
			||||||
 | 
							print('Section for flash CRC missing!')
 | 
				
			||||||
 | 
							sys.exit(-1)
 | 
				
			||||||
 | 
						if flashcrc_sec.data_size != 6*4:
 | 
				
			||||||
 | 
							print("Warning!!! .flashcrc section has wrong size:",flashcrc_sec.data_size)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						crc_sec_data = bytearray(flashcrc_sec.data())
 | 
				
			||||||
 | 
						magic1 = struct.unpack('<I'*1, bytes(crc_sec_data[0:4]))[0]
 | 
				
			||||||
 | 
						magic2 = struct.unpack('<I'*1, bytes(crc_sec_data[-4:]))[0]
 | 
				
			||||||
 | 
						print("CRC section magic values:", hex(magic1), hex(magic2))
 | 
				
			||||||
 | 
						if magic1 != 0xA8BE53F9 or magic2 != 0xFFA582FF:
 | 
				
			||||||
 | 
							print("Wrong magics in CRC section. Data misalignment?")
 | 
				
			||||||
 | 
							sys.exit(-2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						crc_sec_offset = flashcrc_sec['sh_offset']
 | 
				
			||||||
 | 
						print('CRC section ELF file offset:', hex(crc_sec_offset))
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						crc_sec_data[4:8] = struct.pack('<I',text_crc)
 | 
				
			||||||
 | 
						crc_sec_data[8:12] = struct.pack('<I',data_crc)
 | 
				
			||||||
 | 
						crc_sec_data[12:16] = struct.pack('<I',ccmdata_crc)
 | 
				
			||||||
 | 
						crc_sec_data[16:20] = struct.pack('<I',vextors_crc)
 | 
				
			||||||
 | 
						f.seek(crc_sec_offset)
 | 
				
			||||||
 | 
						f.write(crc_sec_data)
 | 
				
			||||||
 | 
						print('CRCs patched successfully')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						
 | 
				
			||||||
@@ -56,6 +56,8 @@ enum safety_flag {
 | 
				
			|||||||
	ERR_FLAG_SAFETY_TAB_CORRUPT = (1<<16),
 | 
						ERR_FLAG_SAFETY_TAB_CORRUPT = (1<<16),
 | 
				
			||||||
	ERR_FLAG_AMON_SUPPLY_VOLT = (1<<17),
 | 
						ERR_FLAG_AMON_SUPPLY_VOLT = (1<<17),
 | 
				
			||||||
	ERR_FLAG_OVERTEMP = (1<<18),
 | 
						ERR_FLAG_OVERTEMP = (1<<18),
 | 
				
			||||||
 | 
						ERR_FLAG_FLASH_CRC_CODE = (1<<19),
 | 
				
			||||||
 | 
						ERR_FLAG_FLASH_CRC_DATA = (1<<20),
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@@ -166,6 +168,8 @@ enum analog_value_monitor {
 | 
				
			|||||||
					ERR_FLAG_PERSIST_ENTRY(ERR_FLAG_SAFETY_TAB_CORRUPT, true), \
 | 
										ERR_FLAG_PERSIST_ENTRY(ERR_FLAG_SAFETY_TAB_CORRUPT, true), \
 | 
				
			||||||
					ERR_FLAG_PERSIST_ENTRY(ERR_FLAG_AMON_SUPPLY_VOLT, false), \
 | 
										ERR_FLAG_PERSIST_ENTRY(ERR_FLAG_AMON_SUPPLY_VOLT, false), \
 | 
				
			||||||
					ERR_FLAG_PERSIST_ENTRY(ERR_FLAG_OVERTEMP, false), \
 | 
										ERR_FLAG_PERSIST_ENTRY(ERR_FLAG_OVERTEMP, false), \
 | 
				
			||||||
 | 
										ERR_FLAG_PERSIST_ENTRY(ERR_FLAG_FLASH_CRC_CODE, true), \
 | 
				
			||||||
 | 
										ERR_FLAG_PERSIST_ENTRY(ERR_FLAG_FLASH_CRC_DATA, true)
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @brief Default config weights of safety flags. These values are loaded into the safety tables on startup
 | 
					 * @brief Default config weights of safety flags. These values are loaded into the safety tables on startup
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
@@ -188,5 +192,7 @@ enum analog_value_monitor {
 | 
				
			|||||||
			ERR_FLAG_WEIGHT_ENTRY(ERR_FLAG_SAFETY_TAB_CORRUPT, SAFETY_FLAG_CONFIG_WEIGHT_PANIC), \
 | 
								ERR_FLAG_WEIGHT_ENTRY(ERR_FLAG_SAFETY_TAB_CORRUPT, SAFETY_FLAG_CONFIG_WEIGHT_PANIC), \
 | 
				
			||||||
			ERR_FLAG_WEIGHT_ENTRY(ERR_FLAG_AMON_SUPPLY_VOLT, SAFETY_FLAG_CONFIG_WEIGHT_PID), \
 | 
								ERR_FLAG_WEIGHT_ENTRY(ERR_FLAG_AMON_SUPPLY_VOLT, SAFETY_FLAG_CONFIG_WEIGHT_PID), \
 | 
				
			||||||
			ERR_FLAG_WEIGHT_ENTRY(ERR_FLAG_OVERTEMP, SAFETY_FLAG_CONFIG_WEIGHT_PID), \
 | 
								ERR_FLAG_WEIGHT_ENTRY(ERR_FLAG_OVERTEMP, SAFETY_FLAG_CONFIG_WEIGHT_PID), \
 | 
				
			||||||
 | 
								ERR_FLAG_WEIGHT_ENTRY(ERR_FLAG_FLASH_CRC_CODE, SAFETY_FLAG_CONFIG_WEIGHT_NONE), \
 | 
				
			||||||
 | 
								ERR_FLAG_WEIGHT_ENTRY(ERR_FLAG_FLASH_CRC_DATA, SAFETY_FLAG_CONFIG_WEIGHT_NONE), \
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __SAFETY_CONFIG_H__ */
 | 
					#endif /* __SAFETY_CONFIG_H__ */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -267,6 +267,13 @@ int safety_controller_set_overtemp_limit(float over_temperature);
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
float safety_controller_get_overtemp_limit(void);
 | 
					float safety_controller_get_overtemp_limit(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Perform a CRC check of the flash memory and set appropriate flags
 | 
				
			||||||
 | 
					 * @return negative if internal error occured. Otherwise (independent from CRC check result) 0.
 | 
				
			||||||
 | 
					 * @note This function requires the safety controller to be set up before!
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int safety_controller_trigger_flash_crc_check(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __SAFETY_CONTROLLER_H__ */
 | 
					#endif /* __SAFETY_CONTROLLER_H__ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** @} */
 | 
					/** @} */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,9 +35,14 @@
 | 
				
			|||||||
#define SAFETY_MEMORY_MAGIC 0x12AA5CB7
 | 
					#define SAFETY_MEMORY_MAGIC 0x12AA5CB7
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @brief Error memory NOP entry
 | 
					 * @brief Error memory NOP entry word written to the memory
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
#define SAFETY_MEMORY_NOP_ENTRY 0xC1AA1222
 | 
					#define SAFETY_MEMORY_NOP_ENTRY_WORD 0xC1AA1222UL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Low Byte (byte 0) of error memory entry
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define SAFETY_MEMORY_ERROR_ENTRY_MARKER 0x51U
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @brief Offset address for the safety_memory_header.
 | 
					 * @brief Offset address for the safety_memory_header.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -36,6 +36,6 @@ int temp_converter_convert_resistance_to_temp(float resistance, float *temp_out)
 | 
				
			|||||||
 * @return 0 if ok, -1 if tmeperature is below the lookup table, 1 if value is above the lookup table, -1000 in case of a pointer error,
 | 
					 * @return 0 if ok, -1 if tmeperature is below the lookup table, 1 if value is above the lookup table, -1000 in case of a pointer error,
 | 
				
			||||||
 *	   -100 if an internal error occured. This should never happen, if the lookup table is correct
 | 
					 *	   -100 if an internal error occured. This should never happen, if the lookup table is correct
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
int temp_convertet_convert_temp_to_resistance(float temp, float *resistance_out);
 | 
					int temp_converter_convert_temp_to_resistance(float temp, float *resistance_out);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __TEMP_CONVERTER_H__ */
 | 
					#endif /* __TEMP_CONVERTER_H__ */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -153,6 +153,15 @@ struct overtemp_config {
 | 
				
			|||||||
	uint32_t crc;
 | 
						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.
 | 
					 * @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_SAFETY_TAB_CORRUPT),
 | 
				
			||||||
	ERR_FLAG_ENTRY(ERR_FLAG_AMON_SUPPLY_VOLT),
 | 
						ERR_FLAG_ENTRY(ERR_FLAG_AMON_SUPPLY_VOLT),
 | 
				
			||||||
	ERR_FLAG_ENTRY(ERR_FLAG_OVERTEMP),
 | 
						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;
 | 
						int result;
 | 
				
			||||||
	float resistance;
 | 
						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... */
 | 
						/* An error in this function is really bad... */
 | 
				
			||||||
	if (result < -1)
 | 
						if (result < -1)
 | 
				
			||||||
		panic_mode();
 | 
							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... */
 | 
						/* This is usually done by the safety memory already. But, since this module also uses the CRC... */
 | 
				
			||||||
	crc_unit_init();
 | 
						crc_unit_init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						safety_controller_trigger_flash_crc_check();
 | 
				
			||||||
	stack_check_init_corruption_detect_area();
 | 
						stack_check_init_corruption_detect_area();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hw_rev = get_pcb_hardware_version();
 | 
						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;
 | 
						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)
 | 
						if (!out)
 | 
				
			||||||
		return -1002;
 | 
							return -1002;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (entry_data == SAFETY_MEMORY_NOP_ENTRY) {
 | 
						if (entry_data == SAFETY_MEMORY_NOP_ENTRY_WORD) {
 | 
				
			||||||
		out->flag_num = 0U;
 | 
							out->flag_num = 0U;
 | 
				
			||||||
		out->type = SAFETY_MEMORY_ERR_ENTRY_NOP;
 | 
							out->type = SAFETY_MEMORY_ERR_ENTRY_NOP;
 | 
				
			||||||
		out->counter = 0U;
 | 
							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->flag_num = (uint8_t)((entry_data >> 8U) & 0xFFU);
 | 
				
			||||||
		out->type = SAFETY_MEMORY_ERR_ENTRY_FLAG;
 | 
							out->type = SAFETY_MEMORY_ERR_ENTRY_FLAG;
 | 
				
			||||||
		out->counter = (uint16_t)((entry_data >> 16U) & 0xFFFF);
 | 
							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) {
 | 
						switch (entry->type) {
 | 
				
			||||||
	case SAFETY_MEMORY_ERR_ENTRY_NOP:
 | 
						case SAFETY_MEMORY_ERR_ENTRY_NOP:
 | 
				
			||||||
		word = SAFETY_MEMORY_NOP_ENTRY;
 | 
							word = SAFETY_MEMORY_NOP_ENTRY_WORD;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case SAFETY_MEMORY_ERR_ENTRY_FLAG:
 | 
						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);
 | 
									((uint32_t)entry->counter << 16U);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -322,9 +322,9 @@ static int safety_memory_check_error_entries()
 | 
				
			|||||||
			return -100;
 | 
								return -100;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Valid flag entry */
 | 
							/* Valid flag entry */
 | 
				
			||||||
		if ((data & 0xFF) == 0x51)
 | 
							if ((data & 0xFF) == SAFETY_MEMORY_ERROR_ENTRY_MARKER)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		if (data == SAFETY_MEMORY_NOP_ENTRY)
 | 
							if (data == SAFETY_MEMORY_NOP_ENTRY_WORD)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ret--;
 | 
							ret--;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -44,12 +44,15 @@ SECTIONS
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	.vectors : ALIGN(4)
 | 
						.vectors : ALIGN(4)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
							__ld_vectors_start = .;
 | 
				
			||||||
		KEEP(*(.vectors))
 | 
							KEEP(*(.vectors))
 | 
				
			||||||
		. = ALIGN(4);
 | 
							. = ALIGN(4);
 | 
				
			||||||
 | 
							__ld_vectors_end = .;
 | 
				
			||||||
	} >FLASH =0xFF
 | 
						} >FLASH =0xFF
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	.text : ALIGN(4)
 | 
						.text : ALIGN(4)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
							__ld_text_start = .;
 | 
				
			||||||
		*(.text)           /* .text sections (code) */
 | 
							*(.text)           /* .text sections (code) */
 | 
				
			||||||
    		*(.text*)          /* .text* sections (code) */
 | 
					    		*(.text*)          /* .text* sections (code) */
 | 
				
			||||||
    		*(.rodata)         /* .rodata sections (constants, strings, etc.) */
 | 
					    		*(.rodata)         /* .rodata sections (constants, strings, etc.) */
 | 
				
			||||||
@@ -59,6 +62,8 @@ SECTIONS
 | 
				
			|||||||
		*(.eh_frame)
 | 
							*(.eh_frame)
 | 
				
			||||||
		KEEP(*(.init))	   /* Constructors */
 | 
							KEEP(*(.init))	   /* Constructors */
 | 
				
			||||||
		KEEP(*(.fini))     /* Destructors  */
 | 
							KEEP(*(.fini))     /* Destructors  */
 | 
				
			||||||
 | 
							. = ALIGN(4);
 | 
				
			||||||
 | 
							__ld_text_end = .;
 | 
				
			||||||
	} >FLASH =0xFF
 | 
						} >FLASH =0xFF
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	.ARM.extab : ALIGN(4)
 | 
						.ARM.extab : ALIGN(4)
 | 
				
			||||||
@@ -98,6 +103,13 @@ SECTIONS
 | 
				
			|||||||
    		/* Ensure LMA of ram data is at 32 bit word address in Flash */
 | 
					    		/* Ensure LMA of ram data is at 32 bit word address in Flash */
 | 
				
			||||||
    		. = ALIGN(4);
 | 
					    		. = ALIGN(4);
 | 
				
			||||||
  	} >FLASH =0xFF
 | 
					  	} >FLASH =0xFF
 | 
				
			||||||
 | 
					  	
 | 
				
			||||||
 | 
					  	.flashcrc : ALIGN(4)
 | 
				
			||||||
 | 
					  	{
 | 
				
			||||||
 | 
					  		KEEP(*(.flashcrc))
 | 
				
			||||||
 | 
					  		KEEP(*(.flashcrc.*))
 | 
				
			||||||
 | 
					  		. = ALIGN(4);
 | 
				
			||||||
 | 
					  	} >FLASH =0xFF
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Initialized CCM data */
 | 
						/* Initialized CCM data */
 | 
				
			||||||
	__ld_load_ccm_data = LOADADDR(.ccmdata);
 | 
						__ld_load_ccm_data = LOADADDR(.ccmdata);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -75,7 +75,7 @@ return_ret_val:
 | 
				
			|||||||
	return ret_val;
 | 
						return ret_val;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int temp_convertet_convert_temp_to_resistance(float temp, float *resistance_out)
 | 
					int temp_converter_convert_temp_to_resistance(float temp, float *resistance_out)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int retcode = 0;
 | 
						int retcode = 0;
 | 
				
			||||||
	unsigned int i;
 | 
						unsigned int i;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user