|
The Easy Way
by Charles Kosina
Start ý An
Example ý State Machine Control ý Keyboard
Scanning ý Receive Serial Data ý LCD
Module ý Transmit Data ý Debugging
Techniques ý Other Options ý Sources
and PDF
About 10 years ago, I had the job of
designing a specialized communications card for a PS/2 PC (remember
PS/2?). This project had eight serial ports polling external devices
at up to 19,200 bps. The card needed to be a bus master, transferring
all data via DMA. I chose the Z180 with peripherals because it was
the chip that I was most familiar with. But, writing the firmware
looked like a formidable task.
Obviously I needed a different approach
to the somewhat ad hoc procedures I had been using until then.
I briefly investigated a multitasking kernel that was available
at the time but ruled it out because its overhead was too high
and interrupt latency far too long.
First of all, I should point out
that Iým a hardware person, and any software I use has been self-taught.
I like to keep things simple and prefer the full control, compactness,
and speed of assembler language, rather than using a higher level
compiler such as C. So, I invented (re-invented?) a top-down state
machine approach that not only made the software writing more
structured, it made debugging much easier.
The program I came up with had a
total of 17 tasks and performed well within specifications. And,
going back to the program some months later to fix a bug, I had
no trouble understanding what I had done previously.
Since then, I have used the same
approach in all my embedded programming. I mainly work with the
Z180 and 8051 class processors, but this method can also be applied
to many other micros.
Multitasking techniques traditionally
slice up the available CPU time between various tasks. The time
slice per task may be along the lines of 50 ms, but varies depending
on the priority of the task and the particular multitasking kernel
used. The kernel may be fairly complex and consume a considerable
portion of the CPU and memory resources.
The process I use has no kernel allocating
processor time. I divide a project into a number of tasks. For
each task, I draw a state machine diagram. A subroutine is written
for each state and this is accessed from a jump table. Every time
the task is called it executes only one state of the state machine.
The main control loop is reduced
to merely a series of call statements, each one giving the task
a time slice as long as the current state needs. The exception
to this is tasks that require urgent attention. These are handled
by interrupt service routines, however. Intertask communication
is via RAM locations and status bits.
There is a vast amount of literature
on state machines, much of it highly theoretical and esoteric. For
a more practical approach, check out Dave Tweedýs article "Designing
Real-Time Embedded Software Using State-Machine Concepts" (Circuit
Cellar 53). Itýll give you a good start.
NEXT
Circuit Cellar provides up-to-date information for engineers. Visit
www.circuitcellar.com for
more information and additional articles.
For subscription information, call (860) 875-2199, subscribe@circuitcellar.com
or subscribe online.
ýCircuit Cellar, the Magazine for Computer Applications. Posted with
permission. |