Table of Contents
State Diagram Editor Part IV - Traffic Lights example on MSP430
In this forth part of the step by step tutorial you get a head-start on how to use state machines to solve a practical problem using a microcontroller board (here a MSP430 from Texas Instruments). All code is easy to understand and can be simply extended. We develop a basic traffic light as you for sure know from your daily experience.
For this tutorial we use the MSP430FR2355 developers kit which is available on the TI homepage. The software is based on a simple foreground/background architecture where the MSP430 waits in low-power mode for events to be processed by our state machine.
- Code Composer Studio (CSS) from TI installed on your PC / MSP430FR2355 kit available
- Java installation
- Installation of the Sinelabore Codegen. You can download it here. We installed it on
C:\sinelaboreRT4.0If you use the same path there is no need to modify the batch file further below.
- If you want to modify the state machine yourself and for step 2 you need also Graphiz (Graph visualisation tool). We installed version 2.38 at
Step A: Getting familiar with the setup
Import our sample project
step1s.zip available here into the CSS. It is a ready made project already implementing the following boilerplate code for you:
- hardware initialisation including clock system of the MSP
- definition/initialisation of the software timer and fifo
- setup of a hardware timer that cyclically calls the software timer code
- setup of an interrupt linked to the “fault button”
- setup of a simple serial interface for debugging / tracing purposes
- Implementing a main loop that wakes up in case events are available and processes them with the help of the generated state machine.
This template project can be reused and can serve as quick start for further projects too. In the folder “state machine” just an empty state machine definition file called
tl_sm.xml is available.
For our little embedded system we also need “software timers” and “fifos” as no RTOS is in use. Therefore the lib folder contains a software timer module and a fifo module.
The imported project could already be compiled, downloaded and executed but nothing will happen because the state machine is still empty. The following picture shows the general architecture of this application and the empty state machine. Go on reading to understand how to build a more complete application based on that framework.
Step B: Fill the empty state machine with life
Typically it is an iterative process to design a state machine. Start thinking of the events that the machine has to react on. Then define the states and the state transitions triggered from the events you found. In our simple example there are just few events: timeouts from a software timers to provide timing, a button event to indicate a hardware fault and another timer event indicating the end of the start-up phase.
From the downloaded code copy file
tl_sm.xml (for traffic light state machine) into the
state machine folder overwriting the existing file. Also copy the
led.h/c files into the project (beside main.c) that allows to switch on/off the traffic lights. Finally also update the
main.c file to have all needed headers included all files from step1b folder).
Open the state machine editor by starting the
edit.bat file in a console window. There should be no error as long as the path was used (as described in the preconditions). Otherwise check the path in
codegen.config and change it according to your installation.
In case all is fine the state machine editor pops up. It is intended for not too complex diagrams and uses Graphviz for automatic layout.
The Sinelabore Codegen can process input from other powerful UML modelling tools. In practise this means you are free to define your own tool chain depending on your needs. Eventually you might want a tool that also runs on Linux or there is already a tool available in your company. You have the choice - most probably the sinelabore code generator supports these tools. The supported tools are listed here on the homepage and details on how to work with them is provided in the manual.
Don’t modify the state machine for now. Just close the tool again and execute “build.bat” in the command window to generate code from the model. The following files gets re-created:
- tm_sm.c/h These files contain the generated state machine based on nested switch/case statements.
- tm_sm_ext.h This file contains the events that can be sent to the state machine
- tm_sm_debug.h This file contains helper code for debugging purposes
- tm_sm_trace.h This file contains helper code for tracing purposes (will be used in part 2).
Compile and download the code to the target now. If you start the program you will notice that nothing happens beside 1Hz flashing of the red led on the eval board. It indicates the heart beat of our app and is only used for debugging purposes. Go on reading to understand why.
Step C: Fill in action code
Right now just the state machine enters the default state. But no triggers come in like timer timeout events nor is there any action code. This means we have to add some action code to our state machine. Action code is nothing else than code executed for example at the time when a state is entered or exited. Or when a transition was taken. Action code must be valid C-code (or any other programming language you use in your project)
tl_sm.xml (from folder step1c) that include now all action code and put it into the
generatedstate machine“ folder. Also copy the updated
main.c again into your project. In
main.c we basically added an interrupt service handler for the push-button.
Open the state machine editor by starting the “edit.bat” file in a console window again. Now you will see that some action code was added. There is code to start our software time either in single shot or repetitive mode. And there is code to switch the traffic lights on or off. Try to understand what the state-machine will do.
Don’t modify the state machine. Just close the tool again and execute
build.bat in the command window to generate code from the updated model. Compile and download the code and execute it. Now you will see that first the yellow light is blinking for a while after power on. Then the normal sequence of a traffic light starts and goes on forever. Until you press the push-button. Then the machine enters an endless yellow blinking sequence. I.e. a service technician is required to eventually fix a hardware problem in the traffic light
Maybe open the state machine editor again to understand what happens. The timing is faster than it should be in real life. This is just to make watching the machine not too boring.
Take a look in main.c line 127. You can see how to send an event from an interrupt service routine into the state machine queue. The machine simply processes event by event that is available in the fifo. This makes it very easy to understand and debug state machines designed in such a way.
Finally the result looks like this:
What have we done so far:
- used a template project using timers, fifo and an empty state machine as quick start
- modified the state machine by adding states and events
- iteratively modify the state machine by adding action code until the full functionality is available.
As you see the usually somehow teditious coding work of the actual state machine is 100% taken over from the state machine code generator. You can fully focus on the application logic and don’t need to worry about all the rest. Beside that the generator performs model checks and warns you about typical design flaws like states without exit etc.
In part two it is shown how to add trace code and monitor the state machine in action.