Lecture 2

Nikolaus Huber

Outline

  • Bare-metal vs RTOS
  • State machines
Bare Metal
  • Simple applications
  • No specific timing requirements
  • "Single loop applications"
  • (Purely) interrupt-based systems
RTOS
  • Multiple, independent execution threads
  • More elaborate data exchange between tasks
  • Usually needs more memory
Book cover: Making Embedded Systems by Elecia White

State machines

State machines

  • Standard software design pattern
  • [...] allow an object to alter its behaviour when its internal state changes. The object will appear to change its class.
    Design Patterns: Elements of Reusable Object-Oriented Software, Gamma et. al. 1994
  • Can be used even in C (without OOP)
  • Put simply: SM does different things depending on the current context (state)
  • Often represented as flow charts (or Finite State Automata)

Designing state machines

  • First, we must figure out the states of the system
  • What are the state change triggers?
    • Synchronous / Asynchronous / Internal / External
  • What to do with triggers we are not expecting in a particular state?
    • Maybe we can just ignore them?
    • Maybe we should generate an error?

Example

Traffic lights

Traffic light example. We have two external inputs: GO and STOP. We have three system state: GREEN, RED, and YELLOW. 
		For each state we have define what happens on each input. For example, if we are in state GREEN and we get the signal STOP, we switch to 
		state YELLOW.

State centric state machine

State centric state machine

  • Big if-else (or switch) statement
  • Each state needs to know about its sibling states
  • Easy to write
  • Difficult to maintain and update
    • Introducing a new state -> Possibly need to put a new transition into every other state

			white(1): 
				get event 

				switch(state): 
					case (green): 
						if (event is stop): 
							turn off green light 
							turn on yellow light 
							set state to yellow 
							start timer 
					
					case (yellow): 
						if (event is timeout): 
							turn off yellow light 
							turn on red light 
							set state to red 
					
					case (red): 
						if (event is go):
							turn off red light 
							turn on green light 
							set state to green 
		

Implementation

Issues with simple implementation

  • State behaviour and state transitions are mixed
  • get_event function => no debouncing
  • Continuous computation, even if there is no update

Button presses

  • Input signal at pin not clean
  • Initial bounce between LOW and HIGH levels
  • Solution => Debouncing

Hardware debouncing

Schmitt trigger

  • 2 thresholds
  • Input between levels => retain value
  • Multiple possible implementations

Software debouncing

  • Need to sense each level twice for button to count as pressed / released
  • Delay between sensing input must be chosen correctly (~ ms)

Interrupts

  • Hardware feature to react to events
    • Clock interrupts
    • Other internal interrupts: errors, ...
    • External interrupts: peripherals, pins, ...
  • When interrupt occurs, µC executes an interrupt service routine (ISR)
  • For complete list of possible interrupts => processor datasheet

Data exchange with ISR

  • Shared memory
    • Global/static variables or same heap location
    • Usually very efficient
    • Access needs to be carefully managed (race conditions)
      • Locking interrupts
      • Synchronisation primitives (pico_sync)
  • Alternative: Pico C/C++ SDK Queue

Implementation

Table driven state machine

  • Easy way to fully define a state machine
  • Rows: different states
  • Columns: states to go to for a specific event
State GO STOP TIMEOUT None

Implementation

Thanks for today!