Real-Time Systems – Lab 4
Dual pulse generator with a GUI
In this assignment you will exercise programming according to the
reactive objects model of TinyTimber (start by reading the description in full),
particular, gain acquaintance with event baselines
and the AFTER
primitive. The concrete task is to implement two separate pulse generators on the AVR
Butterfly, and a Graphical User Interface (GUI) for controlling them
using the on-board joystick and display.
Our pulse generators will generate square waves; that is, periodic
signals that alternate between low and high values with a 50% duty
cycle. Output from the pulse generators could in principle be emitted
through any of the six general I/O ports on the AVR microcontroller.
However, most pins on these ports are actually already connected to
various devices on the Butterfly board, so we will have to direct pulse
generator output as follows:
See the AVR
Butterfly User's Guide
for information on the physical location of socket J405 and its pins.
- Pulse generator 1 writes its output to bit 4 of port E, which is
connected to pin 1 of socket J405.
- Pulse generator 2 writes its output to bit 6 of port E, which is
connected to pin 3 of socket J405.
The period of each pulse generator should be individually controllable
via a simple GUI on the LCD, operated by the joystick. The GUI should
display two 2-digit numbers at positions 0 and 4 (counting from the right), standing for the
current speed settings for pulse generators 1 and 2, respectively. The
numbers don't have to represent frequency according to any established
unit of measure, but they should nevertheless adhere to the following
Two arbitrary chosen segments should be used to
indicate which of the two pulse generators that is currently receiving
user input. Moving the joystick to the right or to the left should
switch between these states. Moving the joystick in the upward/downward
direction should increase/decrease the setting for the pulse generator
currently in focus. Pressing the joystick should immediately set the
frequency to zero, pressing it again should restore the setting to its
previous value. Moreover, it should be possible to hold the joystick in the up or down
position and thereby achieve the same effect as repeated input in the
corresponding direction. Convenient values for the repetition period
and a possible initial delay should be obtained by experimentation.
- Higher values mean pulses of higher frequency.
- A value of 00 means a frequency of zero; i.e. a stopped pulse
generator (emitting a constantly low output).
- The ratio between the frequencies at settings 99 and 01 should be
at least 100.
To implement the assignment you will need a copy of the TinyTimber
kernel, which is split into a header file TinyTimber.h and and implementation file TinyTimber.c.
Important note: you may need to install handlers for more than one interrupt to receive all input from the joystick. Moreover, if a method m of some object A has been installed as an interrupt handler, then all methods of this object will be executed with interrupts disabled. Do not use SYNC() and AFTER() in any method of the object A; instead, make an asynchronous call using ASYNC() to some other object and process the interrupt there.
The following generic stylistic guidelines are mandatory to your
reactive object class definition N
shall be confined to a designated pair of files called N.h and N.c. File N.h shall contain a typedef for the class (i.e. struct) N,
macro named initN(), and function headers for all
methods supported by class N.
shall contain the
function definitions for the supported methods, and nothing else. The
file main.c shall contain all object instances for the program as well
as definitions of the top-level methods.
Any remaining functionality (e.g. related to
LCD handling) should be put in separate .h and .c files at your own
discretion. No global variables whatsoever will be allowed in the
program apart from the object instances defined in main.c.
In addition, the following
- The design should contain a separate reactive object for each
pulse generator and at least one additional reactive object that
handles the GUI.
- The two pulse generator objects should be instances of a single
pulse generator class, which consequently must be parameterized with
respect to the bit number of port E it wishes to control.
- To avoid race conditions with two generators simultaneously
reading and writing port E, a dedicated object should handle the actual
writing of individual bits to this port.
It is advisable that the application be developed in steps,
concentrating on one reactive object at a time. To verify that the
pulse generator objects actually generate pulses of the correct
frequency, connect an oscilloscope between ground (pin 4) and pin 1 or
pin 3 of socket J405. If your AVR does not have pins connected to socket, ask the lab supervisor to fix that for you.
Demonstrate that the software works (using an oscilloscope) and answer the following questions (written answers are not necessary):
- Explain the principles of implementing object orientation in C.
- The TimyTimber kernel, if properly used, supports a reactive programming model with object-level concurrency. Explain these two terms.
- When using the TinyTimber kernel, why is it important to invoke all object methods via kernel primitives (SYNC, ASYNC, AFTER, BEFORE) and not directly?
- Explain the term race condition.