Safety Controller¶
-
group
safety-controller
This is the main module for the safety part of the firmware. It monitors analog values, error states and timeouts of timing critical sections of the firmware.
Defines
-
check_flag_persistent
(flag) ((flag)->persistence && (flag)->persistence->persistence)¶ Macro that checks if a given error_flag is persistent.
-
get_flag_weight
(flag) ((flag)->weight ? ((flag)->weight->weight) : SAFETY_FLAG_CONFIG_WEIGHT_PANIC)¶ Macro that retrieves the flag weight of a given error_flag.
If no flag weight table is present, the flag is evaluated as SAFETY_FLAG_CONFIG_WEIGHT_PANIC
Enums
-
enum
analog_monitor_status
¶ State of an analog monitor.
Values:
-
enumerator
ANALOG_MONITOR_OK
¶ Monitor set up and ok.
-
enumerator
ANALOG_MONITOR_ERROR
¶ An internal error occured.
-
enumerator
ANALOG_MONITOR_INACTIVE
¶ Monitor inactive. Reading is not valid.
-
enumerator
ANALOG_MONITOR_OVER
¶ Value too high.
-
enumerator
ANALOG_MONITOR_UNDER
¶
-
enumerator
Functions
-
void
safety_controller_init
()¶ Initialize the safety controller.
After a call to this function the controller is iniotlaized and the watchdog is set up. You have to call safety_controller_handle If this function fails, it will hang, because errors in the safety controller are not recoverable
-
int
safety_controller_handle
()¶ Handle the safety controller.
- Note
This function must be executed periodically in order to prevent the watchdog from resetting the firmware
- Return
0 if successful
-
int
safety_controller_report_error
(enum safety_flag flag)¶ Report one or multiple errors to the safety controller.
When passing multipe error glags, the flags have to be ORed together.
- Return
0 if successful.
- Parameters
flag
: Error flag to report
-
int
safety_controller_report_error_with_key
(enum safety_flag flag, uint32_t key)¶ Report one or multiple error flags with a key.
When setting a
key
on an error flag. The error flag can only be cleared, by passing the same key value to the safety_controller_ack_flag_with_key function.- Return
0 if successful
- Parameters
flag
: Error flag to reportkey
: Key
-
void
safety_controller_report_timing
(enum timing_monitor monitor)¶ Report timing to a timing monitor.
- Parameters
monitor
: Monitor to report
-
void
safety_controller_report_analog_value
(enum analog_value_monitor monitor, float value)¶ Report an analog value to an analog value monitor.
- Parameters
monitor
: Monitor to reportvalue
: Analog value
-
int
safety_controller_enable_timing_mon
(enum timing_monitor monitor, bool enable)¶ Enable or disable a timing monitor.
- Return
0 if successful.
- Parameters
monitor
: Monitor to enableenable
: State to set the monitor to.
-
enum analog_monitor_status
safety_controller_get_analog_mon_value
(enum analog_value_monitor monitor, float *value)¶ Get the value of an analog monitor.
- Return
Status of the analog monitor.
value
only valid, if return value does not indicate an internal error, or an inactive monitor.- Parameters
monitor
: Monitor to get value from[out] value
: The analog value
-
int
safety_controller_get_flag
(enum safety_flag flag, bool *status, bool try_ack)¶ Get error flag state and optionally acknowledge the flag.
If the flag is persistent, it cannot be ack’ed. In this case this function does not return an error code.
- Return
0 if successful.
- Parameters
flag
: Error flag[out] status
: state of the flag.try_ack
: Try to ack the flag. This might fail, if the flag is persistent.
-
int
safety_controller_ack_flag
(enum safety_flag flag)¶ Ack an error flag.
- Return
0 if successful, -2 if flag is persistent or keyed. All other values: Errors
- Parameters
flag
: Error flag to ack
-
int
safety_controller_ack_flag_with_key
(enum safety_flag flag, uint32_t key)¶ Acknowledge error flag with a key.
- Return
0 if successful, -2 if flag is persistent or key wrong. All other values: Errors
- Parameters
flag
: Error flagkey
: Key
-
bool
safety_controller_get_flags_by_mask
(enum safety_flag mask)¶ Get an ored status of multiple flags.
- Return
True if errors. False if no errors.
- Parameters
mask
: Flags to check
-
uint32_t
safety_controller_get_flag_count
()¶ Get the count of error flags.
- Return
Error flag count
-
uint32_t
safety_controller_get_analog_monitor_count
()¶ Get the count of analog monitors.
- Return
Analog monitor count
-
int
safety_controller_get_flag_name_by_index
(uint32_t index, char *buffer, size_t buffsize)¶ Get an error flag’s name by its index.
The name of the flag will be cropped, if the buffersize is too small. Paramter
buffsize
may not be zero.- Return
0 of successful
- Parameters
index
: 0 based index.[out] buffer
: Buffer to write the name to.buffsize
: Buffer size. This has to be big enough to hold the name and the \0-terminator
-
int
safety_controller_get_flag_by_index
(uint32_t index, bool *status, enum safety_flag *flag_enum)¶ Get the safety flag by its internal index.
- Return
0 if successful; else: negative
- Parameters
index
: 0 based index.[out] status
: Current flag state. May be NULL.[out] flag_enum
: Flag enum used in SW. May be NULL.
-
int
safety_controller_get_analog_mon_by_index
(uint32_t index, struct analog_monitor_info *info)¶ Get an analog monitor info by the monitor’s index.
- Return
0 if successful. -1001, if
index
out of range -1002, ifinfo
is NULL- Parameters
index
: 0 based index[out] info
: Info structure.
-
int
safety_controller_get_analog_mon_name_by_index
(uint32_t index, char *buffer, size_t buffsize)¶ Get the name of an analog monitor by its index.
The buffer has to be large enough to hold the name plus a null terminator. If the buffer is not large enough, The name will be cropped. Parameter
buffsize
may not be zero.- Return
- Parameters
index
: 0 based indexbuffer
: Buffer to write name tobuffsize
: Buffer size
-
int
safety_controller_get_timing_mon_by_index
(uint32_t index, struct timing_monitor_info *info)¶ Get timing monitor information by index.
- Return
0 if successful
- Parameters
index
: 0 based index[out] info
: Info
-
int
safety_controller_get_timing_mon_name_by_index
(uint32_t index, char *buffer, size_t buffsize)¶ Get the name of a timing monitor by its index.
The buffer has to be large enough to hold the name plus a null terminator. If the buffer is not large enough, The name will be cropped. Parameter
buffsize
may not be zero.- Return
0 if successful
- Parameters
index
: 0 based indexbuffer
: Buffer to write name to.buffsize
: Buffer size
-
uint32_t
safety_controller_get_timing_monitor_count
(void)¶ Get the count of timing monitors.
- Return
Timing monitor count
-
int
safety_controller_set_overtemp_limit
(float over_temperature)¶ Set the overtemperature limit and store it permanently in the EEPROM.
If no EEPROM is present, this will fail. The default value SAFETY_DEFAULT_OVERTEMP_LIMIT_DEGC will be used.
- Return
0 if successfully saved and applied, negative if error
- Parameters
over_temperature
: Over temperature to set
-
float
safety_controller_get_overtemp_limit
(void)¶ Read the current overtemperature limit.
- Return
Over temperature limit
-
void
set_overtemp_config
(float over_temperature)¶ Configure the overtemperature flag’s settings.
- Parameters
over_temperature
: Temperature to set the limit to.
-
bool
over_temperature_config_check
(void)¶
-
uint8_t
flag_enum_to_flag_no
(enum safety_flag flag)¶ Convert a flag enum to the flag number.
Flag numbers are used by the error memory to store flags. This function will fail and return 0xFF if multiple flags are ORed and passed as flag parameter.
- Return
Flag number or 0xFF in case of an error
- Parameters
flag
: Flag enum
-
enum safety_flag
flag_no_to_flag_enum
(uint8_t no)¶ Convert a safety flag’s number to its enum value.
Flag numbers are used by the error memory to store flags.
- Return
Flag enum
- Parameters
no
: The flag number.
-
int
flag_weight_table_crc_check
(void)¶ Check the CRC chacksum of the flag weight table.
- Return
0 if CRC is valid, else -1;
-
int
flag_persistence_table_crc_check
(void)¶ Check the CRC chacksum of the flag persistence table.
- Return
0 if CRC is valid, else -1.
-
struct error_flag *
find_error_flag
(enum safety_flag flag)¶ Find the error flag structure for a given safety_flag enum.
Only one flag can be given at a time. Giving multiple flags by ORing them together, will not math any flag at all.
- Return
NULL in case nothing matched. Pointer otherwise.
- Parameters
flag
: Enum defining the flag.
-
void
init_safety_flag_weight_table_from_default
(void)¶ This function copies the safety weigths from flash ro RAM and computes the CRC.
-
void
init_safety_flag_persistencies_from_default
(void)¶ Initialize the default persistence settings of all safety flags.
This function copies the default persistence settings of the safety flags defined in SAFETY_CONFIG_DEFAULT_PERSIST and computes the protection CRC over the settings.
-
void
apply_config_overrides
(void)¶ Apply the config overrrides stored in the safety memory.
The config overrides are read from the safety memory and applied. The config overrides can override the following things:
1) Safety Weights (See config_weight) 2) Flag Persistence
-
bool
error_flag_get_status
(volatile const struct error_flag *flag)¶ Get the error state of a flag.
This function takes inbto account that the error_flag::error_state and error_flag::error_state_inv fileds must never be the same value. In case they are, the flag is treated as errorneous.
- Return
The error state
- Parameters
flag
: Flag to check
-
struct analog_mon *
find_analog_mon
(enum analog_value_monitor mon)¶ Find a analog value monitor structure by its enum number.
- Return
NULL incase nothing is found, else pointer to structure.
- Parameters
mon
: Enum representing the analog monitor
-
struct timing_mon *
find_timing_mon
(enum timing_monitor mon)¶ Find a timing monitor structure by its enum number.
- Return
NULL incase nothing is found, else pointer to structure.
- Parameters
mon
: Enum representing the timing monitor
-
void
safety_controller_process_active_timing_mons
()¶ Check the active timing monitors and set the appropriate flags in case of an error.
-
void
safety_controller_process_monitor_checks
(void)¶ safety_controller_process_monitor_checks Process the analog and timing monitors and set the relevant flags in case of a monitor outside its limits. Furthermore, the PT1000 resistance is checked for overtemperature
The checking of the analog monitors will only be armed after a startup delay of 1000 ms to allow the values to stabilize.
-
int
report_error
(enum safety_flag flag, uint32_t key, bool prevent_error_mem_enty)¶ Internal function for setting an error flag.
Multiple flags can be ored together to set them in one go. The provided key will be set on all of the flags in order to prevent them from being reset by unauthorized code. If nop key shall be used, set key to zero.
- Return
0 if successful.
- Parameters
flag
: Enum of the flags to set. This can be an ORed value of multiple error flags.key
: The kex to set on the flag.prevent_error_mem_enty
: Prevent the flag from being stored in the error memory.
-
int
get_safety_flags_from_error_mem
(enum safety_flag *flags)¶ Return the flags, which are set in the error memory.
- Return
0 if ok, != 0 if error
- Parameters
flags
: Flags read from error memory
-
void
safety_controller_init_external_watchdog
()¶ Initialize the GPIOs for the external hardware watchdog.
The external harware watchdog has to be periodically reset or it will reset hte controller. Because debugging is not possible, when the watchdog is active, it is only activated, if the application is compiled in release mode. Any interruption of the main programm will then trigger the internal and/or the external watchdog.
- Note
When enabled, execute the external_watchdog_toggle function to reset the external watchdog.
-
void
safety_controller_check_stack
()¶ Check the processor’s stack.
This function checks the Stack of the application. The check consists of 2 parts:
1) Checking the remaining free space at the moment between stack pointer and top of heap. 2) Checking The CRC of the corruption detect area between heap and stack
-
void
safety_controller_handle_safety_adc
()¶ Handle the Safety ADC.
This function handles the safety ADC. If the safety ADC ius not executing a measurment and the time since the last measurement has passed SAFETY_CONTROLLER_ADC_DELAY_MS, the safety ADC is retriggered and will automatically perform a measurement on all of its channels. When called again, this function will retrieve the data from the safety ADC and converts it into the appropriate analog values for the analog value monitors.
The safety ADC is configured to perform multiple measurmeents of each physical channel. Therefore, this function fist calculated the mean value before converting them into the physical values.
The channels, the ssafety ADC will convert is defined in its header file using the define SAFETY_ADC_CHANNELS.
-
void
safety_controller_handle_memory_checks
(void)¶ Check the memory structures.
This function checks multiple memory structures.
1) The safety memory in the backup RAM is checked using safety_memory_check. In case of an error, the safety memory is reinitialized and the ERR_FLAG_SAFETY_MEM_CORRUPT flag is set. 2) The flag weight table is CRC checked. In case of an error, the ERR_FLAG_SAFETY_TAB_CORRUPT flag is set. Aditionally, the default flag weights are restored from Flash. 3) The flag persistence table is CRC checked. In case of an error, the ERR_FLAG_SAFETY_TAB_CORRUPT flag is set. Aditionally, the default values of the flag persistence is restored from Flash. 4) Check the Overtemperature flag configuration structure
-
void
safety_controller_do_systick_checking
()¶ Check if the systick is ticking.
If the systick stays constant for more than 1000 calls of this function, the ERR_FLAG_SYSTICK flag is set.
-
void
safety_controller_handle_weighted_flags
()¶ Handle weightet flags.
This functions loops over all error flags and checks the weights. If a flag is set, the appropriate action defined by the flag weight is executed.
- Note
If no flag weigth is present for a given error flag, it is treated as the most critical category (SAFETY_FLAG_CONFIG_WEIGHT_PANIC)
-
void
external_watchdog_toggle
()¶
Variables
-
struct error_flag
flags
[] = {ERR_FLAG_ENTRY(ERR_FLAG_MEAS_ADC_OFF), ERR_FLAG_ENTRY(ERR_FLAG_MEAS_ADC_WATCHDOG), ERR_FLAG_ENTRY(ERR_FLAG_MEAS_ADC_UNSTABLE), ERR_FLAG_ENTRY(ERR_FLAG_MEAS_ADC_OVERFLOW), ERR_FLAG_ENTRY(ERR_FLAG_TIMING_MEAS_ADC), ERR_FLAG_ENTRY(ERR_FLAG_TIMING_PID), ERR_FLAG_ENTRY(ERR_FLAG_AMON_UC_TEMP), ERR_FLAG_ENTRY(ERR_FLAG_AMON_VREF), ERR_FLAG_ENTRY(ERR_FLAG_STACK), ERR_FLAG_ENTRY(ERR_FLAG_SAFETY_ADC), ERR_FLAG_ENTRY(ERR_FLAG_SYSTICK), ERR_FLAG_ENTRY(ERR_FLAG_WTCHDG_FIRED), ERR_FLAG_ENTRY(ERR_FLAG_UNCAL), ERR_FLAG_ENTRY(ERR_FLAG_DEBUG), ERR_FLAG_ENTRY(ERR_FLAG_TIMING_MAIN_LOOP), ERR_FLAG_ENTRY(ERR_FLAG_SAFETY_MEM_CORRUPT), ERR_FLAG_ENTRY(ERR_FLAG_SAFETY_TAB_CORRUPT), ERR_FLAG_ENTRY(ERR_FLAG_AMON_SUPPLY_VOLT), ERR_FLAG_ENTRY(ERR_FLAG_OVERTEMP),}¶ All safety error flags.
-
struct timing_mon
timings
[] = {TIM_MON_ENTRY(ERR_TIMING_PID, 2, 5000, ERR_FLAG_TIMING_PID), TIM_MON_ENTRY(ERR_TIMING_MEAS_ADC, 0, 50, ERR_FLAG_TIMING_MEAS_ADC), TIM_MON_ENTRY(ERR_TIMING_SAFETY_ADC, 10, SAFETY_CONTROLLER_ADC_DELAY_MS + 1000, ERR_FLAG_SAFETY_ADC), TIM_MON_ENTRY(ERR_TIMING_MAIN_LOOP, 0, 1000, ERR_FLAG_TIMING_MAIN_LOOP),}¶ All timing monitors.
-
struct analog_mon
analog_mons
[] = {ANA_MON_ENTRY(ERR_AMON_VREF, SAFETY_ADC_VREF_MVOLT - SAFETY_ADC_VREF_TOL_MVOLT, SAFETY_ADC_VREF_MVOLT + SAFETY_ADC_VREF_TOL_MVOLT, ERR_FLAG_AMON_VREF), ANA_MON_ENTRY(ERR_AMON_UC_TEMP, SAFETY_ADC_TEMP_LOW_LIM, SAFETY_ADC_TEMP_HIGH_LIM, ERR_FLAG_AMON_UC_TEMP), ANA_MON_ENTRY(ERR_AMON_SUPPLY_VOLT, SAFETY_ADC_SUPPLY_MVOLT - SAFETY_ADC_SUPPLY_TOL_MVOLT, SAFETY_ADC_SUPPLY_MVOLT + SAFETY_ADC_SUPPLY_TOL_MVOLT, ERR_FLAG_AMON_SUPPLY_VOLT),}¶ All analog value monitors.
-
const struct safety_weight
default_flag_weights
[] = {SAFETY_CONFIG_DEFAULT_WEIGHTS}¶ The default flag weights, that are loaded on boot.
-
const struct safety_persistence
default_flag_persistencies
[] = {SAFETY_CONFIG_DEFAULT_PERSIST}¶ The default flag persistencies, that are loaded on boot.
-
struct safety_persistence
flag_persistencies
[COUNT_OF
(default_flag_persistencies
)]¶ The working copy of the flag persistence table. It is protected by the flag_persistencies_crc.
- Note
This is stored in CCM RAM
-
uint32_t
flag_persistencies_crc
¶ The CRC of the flag weight table flag_persistencies.
The CRC is calculated using the internal CRC module of the STM32F407 controller. See the refernece manual for the polynomial.
- Note
This is stored in CCM RAM.
-
struct safety_weight
flag_weights
[COUNT_OF
(default_flag_weights
)]¶ The working copy of the flag weight table. It is protected by the flag_weight_crc.
- Note
This is stored in CCM RAM
-
uint32_t
flag_weight_crc
¶ The CRC of the flag weight table flag_weights.
The CRC is calculated using the internal CRC module of the STM32F407 controller. See the refernece manual for the polynomial.
- Note
This is stored in CCM RAM.
-
struct overtemp_config
safety_controller_overtemp_config
¶ Configuration struct containing the overtemperature flag configuration.
-
struct
analog_monitor_info
¶ - #include <safety-controller.h>
Info structure describing an analog monitor.
Public Members
-
float
value
¶ Current analog value.
-
float
min
¶ Minumum value allowed.
-
float
max
¶ Maximum value allowed.
-
enum analog_monitor_status
status
¶ Current monitor status.
-
enum safety_flag
associated_flag
¶ Associated safety flag, that will be set, if monitor out of range.
-
uint64_t
timestamp
¶ ms timestamp when analog_monitor_info::value was taken.
-
float
-
struct
timing_monitor_info
¶ - #include <safety-controller.h>
Info structure describing a timing monitor.
-
struct
safety_weight
¶ Safety controller internal structure implementing a safety flag weight.
Public Members
-
uint32_t
start_dummy
¶ Dummy value. This seeds the CRC.
-
enum config_weight
weight
¶ The safety flag’s weight.
-
enum safety_flag
flag
¶ The enum value of the flag this weight corresponds to.
-
struct error_flag *
flag_ptr
¶ the flag, this weight corresponds to
-
uint32_t
end_dummy
¶ Dummy value. This seeds the CRC.
-
uint32_t
-
struct
safety_persistence
¶ Safety controller internal struct implementing a flag persistence entry.
Public Members
-
uint32_t
start_dummy
¶ Dummy value. This seeds the CRC.
-
bool
persistence
¶ Corresponding flag is persistent and cannot be cleared.
-
enum safety_flag
flag
¶ Corresponding safety flag’s enum value.
-
struct error_flag *
flag_ptr
¶ Corresponding safety error flag.
-
uint32_t
end_dummy
¶ Dummy value. This seeds the CRC.
-
uint32_t
-
struct
error_flag
¶ Safety controller internal struct implementing an error flag.
Public Members
-
const char *
name
¶ Name of the error flag.
-
enum safety_flag
flag
¶ Enum value of this safety flag.
-
bool
error_state
¶ The flag’s state. True is errorneous.
-
bool
error_state_inv
¶ Not the flag’s state. This always has to be inverted to error_flag::error_state.
-
struct safety_persistence *
persistence
¶ Persistence entry of this flag.
-
struct safety_weight *
weight
¶ Weight entry of this flag.
-
uint32_t
key
¶ Key needed to remove this safety flag. If key == 0, no key is set and the flag can be cleared by all code.
-
const char *
-
struct
timing_mon
¶
-
struct
analog_mon
¶
-
struct
overtemp_config
¶
-