Description
If an ECU triggers ErrorHandler()
or encounters a HardFault
, it is very hard to know what happened. These are errors that are at a much lower level than things like a motor communication error or accumulator startup, so we can't just send an alert over CAN.
Currently, the LEDs on FrontController and LV Controller blink at 5Hz to show that the program is running, so we can tell IF the program has stalled, but not WHY.
We could add more patterns to the LED to show which fault occurred, something like
LED Pattern | Status |
---|---|
Toggling | Firmware Running |
2 blinks, delay | Error Handler |
3 blinks, delay | Hard Fault |
4 blinks, delay | RTOS Stack overflow |
We could also add sub-codes for more granularity. Maybe the RTOS overflow could indicate which task failed by
4 blinks - short pause - X blinks - long pause
where X is task dependent
Implementation
CubeMX generates empty error handling methods which just stall the program by entering an infinite while loop.
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
/**
* @brief This function handles Hard fault interrupt.
*/
void HardFault_Handler(void)
{
/* USER CODE BEGIN HardFault_IRQn 0 */
/* USER CODE END HardFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
/* USER CODE END W1_HardFault_IRQn 0 */
}
}
We should rewrite these methods to blink the LED.
Considerations
- Interrupts must remain disabled in the interrupt handler as otherwise you could escape the error state. Regular timers, and thus
Hal_Delay(milliseconds)
rely on interrupts, so the LED blink timing must be achieved some other way - How can we be sure that our error handling methods will not themselves throw errors?
- How can we share the same LED codes across multiple projects?