170 likes | 176 Views
Embedded System Design Techniques™. Writing Portable and Robust Firmware in C. Class 5: Robust Firmware Concepts. September 4, 2015 Jacob Beningo, CSDP. Course Overview. Portable C Concepts Doxygen and PC-Lint Uart Driver and Stm32CubeMx Assertions and printf Robust Firmware Concepts.
E N D
Embedded System Design Techniques™ Writing Portable and Robust Firmware in C Class 5: Robust Firmware Concepts September 4, 2015Jacob Beningo, CSDP
Course Overview • Portable C Concepts • Doxygen and PC-Lint • Uart Driver and Stm32CubeMx • Assertions and printf • Robust Firmware Concepts
Session Overview • Watchdog Timers • Watchdog API • Watchdogs use • Stack Monitor • Cyclomatic Complexity • Robust application features
Watchdog Overview Characteristics of a Good Watchdog • Watchdog and subsystem being monitored should have separate clocks • Watchdog refresh should be done such that the changes of run-a-way code refreshing the watchdog are minimized • Run-away code should be detected quickly to prevent system damage • Critical control and configuration registers should have write protection so that once set they cannot be changed • Should be able to detect what has caused the time-out • Task flagging for proper operation
Watchdog Types • Internal • Timer Based • External • Heartbeat • Smart • Dumb eWatchdog HB COMMS RST MCU COMMS "A Review of Watchdog Architectures" http://www.beningo.com/category/white-papers/
Stack Monitor Design Calculating stack size can be difficult! • What is on the stack? • Creating a stack monitor / guard manually • Write known pattern into the Guard area • Monitor the Guard area for changes • Alternatively use the MPU void main(void) { uint32_t * GuardPtr = (uint32_t *) GUARD_START; for(Index = 0; Index < GUARD_SIZE; Index++) { if(*GuardPtr == 0xC0DE) {//DO NOTHING} else { //flag error! Attempt recovery } } } GUARD_SIZE = DEFINED(__guard_size__) ? __guard_size__ : 0x00000100; .guard: { . = ALIGN(8); FILL(0xC0DE); . += GUARD_SIZE - 1; BYTE(0xE) } > m_data
Cyclomatic Complexity Limiting Function Complexity • Helps to ensure readability • Bounds number of test cases • Forces breaking up into smaller more manageable pieces • Reduces bugs
Filling ROM What happens if … • Buffer overrun occurs? • Dereference a bad pointer? • System upset occurs? • What is the status of none programmed ROM? .fillsection : { FILL(0xAA55AA55); . = ORIGIN(m_text) + LENGTH(m_text) – 1; BYTE(0xAA) } > m_text
Robust Application Features • ROM Checksum and validation • RAM check performed periodically • Robust watchdog system • 1 – 3 % code are assertions • Empty ROM is filled • Validating inputs/outputs and error conditions
Additional Resources • Download Course Material for • Updated C Doxygen Templates (May 2015) • Example source code • Templates • Microcontroller API Standard • EDN Embedded Basics Articles • Embedded Bytes Newsletter From www.beningo.com under - Blog and Articles > Software Techniques > CEC Writing Portable and Robust Firmware in C
Newsletters • Embedded Bytes • http://bit.ly/1BAHYXm • Training • MicroPython • Bootloaders • Low Power Design • Real-time Software • C/C++ Embedded P.O. Box 400 Linden, Michigan 48451 www.beningo.com : jacob@beningo.com : 810-844-1522 : Jacob_Beningo : Beningo Engineering : JacobBeningo : Embedded Basics Jacob Beningo Principal Consultant