This exercise provides a practical refresher on VxWorks 5.5 program development. You will create a simple project, interact with the target system, and use WindView to observe and measure real-time performance characteristics.
๐ ๏ธ Start a VxWorks Project #
Launch the Tornado 2.2 development environment.
Create a new downloadable project.
Name the project Simple. If youโve used Tornado before, you may reuse your existing workspace. New developers must create a workspace on the Z: drive; Tornado stores each project in its own directory inside this workspace.
Our target systems (“purpleboxes”) use Intel 80486 processors. Select the I80486gnu toolchain for all purplebox-related development.
Finish creating the project. This also creates the workspace automatically if one does not exist.
๐งฑ Create and Build the Simple Project #
Copy simple.c into the Simple project directory. In the Files tab, right-click the project and add this file.
In the Builds tab, locate I80486gnu under Simple Builds. Right-click and rebuild simple.out. When prompted to regenerate dependencies, click OK.
During the build, the Build Output window appears. Double-click any error to jump directly to its source.
A successful build produces simple.out, which you will later download to the target.
โ๏ธ Start the Target System and Target Server #
Powering up a purplebox causes it to FTP a standard VxWorks image from the development station. Therefore, start the FTP server before powering on the target.
Connect power to the AVerKey iMicro video converter. The power connectors for the converter and the purplebox look identical but provide different voltagesโthe AVerKey cable is tied down to prevent misconnection.
Power the purplebox and switch the monitor input using the middle button. You should see the BIOS and VxWorks boot ROM. After the timeout, it downloads the VxWorks image.
On the target monitor, verify that the system is ready by confirming the message: WDB: Ready.
Next, start a Target Server, which acts as a proxy between Tornado and the purplebox. Select the appropriate target based on the labels on the host and target devices. If the target list is empty, run the registry update file (Tornado22-registry-targets) located in C:\Tornado2.2.
Check the bullseye icon in the system tray: no exclamation mark means the connection succeeded. You can double-click it to confirm.
From Tornado, connect to the target server (there should be only one).
๐ฌ Interact with the Target System #
During development, you will primarily use the remote shell. Start it by clicking the shell icon.
The shell window gives you command-line access to the target. The Tornado User’s Guide documents all commands; typing help provides brief descriptions.
Right-click Simple Files and download simple.out to the target. Run the program by typing its entry function:
progStart
Any function can be invoked simply by typing its name.
๐ Gathering System Performance Data #
WindView is Tornadoโs tool for collecting detailed timing and event data from the target. Launch it from the toolbar.
WindView collects events in on-target buffers. From the Upload Mode screen, choose whether to upload data continuously or defer uploads until logging stops.
Deferred upload reduces runtime overhead but limits capture duration. You can also adjust buffer count and size in Advanced options. Use Deferred Upload for these exercises.
Control what events are logged using the Event Logging Level screen.
Open the Log Overview tab. Set refresh to 1 second, then press the green Go button to start logging.
Allow the buffers to fill or click the red Stop button to end capture manually. Upload the event log using the Upload Event Log button.
WindView will generate an event graph similar to the following:
Explore the event graph:
- What do the icons represent?
- What is the meaning of each interval?
- How do you zoom in for detail?
- Can specific event types be filtered?
- How do you measure the time between two points?
For deeper analysis, export the data to CSV. Note: If zoomed in, only the zoomed portion will be exported.
๐ Analyze the Data #
From the exported CSV:
- Calculate the average interval between executions of the simple task.
- Identify the minimum and maximum intervals.
- Plot a histogram. Does the distribution look uniform? Clustered? Sporadic?
This analysis shows how external factors, scheduling, or interrupt latency affect real-time behavior on VxWorks.
๐ ๏ธ Source code #
/* simple.c - a sample program to use as an introduction to VxWorks and Tornado */
/* $Id: simple.c,v 1.1 2007-03-12 05:47:46 se463 Exp $ */
/* includes */
#include "vxWorks.h"
#include "stdio.h"
#include "stdlib.h"
#include "semLib.h"
#include "taskLib.h"
#define DELAY_TICKS 50
#define STACK_SIZE 20000
/* run states, provides for shutdown in stages; ensures that no
routine tries to take a semaphore that no longer exists */
#define ALL_GO 0
#define SHUTDOWN 1
#define GATEKEEPER_STOP 2
#define ALL_STOP 3
/* globals */
int tidGatekeeper;
int tidSimple;
int runState; /* running state of the system */
int count; /* track number of time simple runs */
SEM_ID syncSemId; /* Controls when simple can run */
/* forward declarations */
void gatekeeper (void);
void simple (void);
void progStop (void);
/*************************************************************************
*
* progStart - start the simple program.
*
* RETURNS: OK
*/
STATUS progStart (void)
{
syncSemId = semBCreate (SEM_Q_FIFO, SEM_EMPTY);
/* get started */
runState = ALL_GO;
tidGatekeeper = taskSpawn ("tGateKeeper", 200, 0, STACK_SIZE,
(FUNCPTR) gatekeeper,0,0,0,0,0,0,0,0,0,0);
tidSimple = taskSpawn ("tSimple", 220, 0, STACK_SIZE,
(FUNCPTR) simple,0,0,0,0,0,0,0,0,0,0);
return (OK);
}
/*************************************************************************
*
* gatekeeper - routine that supplies the semaphore simple task waits on
*
*/
void gatekeeper (void)
{
while (runState == ALL_GO)
{
semGive(syncSemId);
taskDelay (DELAY_TICKS + (rand() & 0x0f) - 8);
}
runState = GATEKEEPER_STOP;
semGive (syncSemId);
}
/*************************************************************************
*
* simple - consume the semaphore and do not do much else
*
*/
void simple (void)
{
count = 0;
while (runState != GATEKEEPER_STOP)
{
semTake (syncSemId, WAIT_FOREVER); /* Wait for signal */
count++;
}
runState = ALL_STOP;
}
/*************************************************************************
*
* progStop - stops the program
*
* Call this routine to end it all.
*/
void progStop (void)
{
runState = SHUTDOWN;
/* Wait for everyone to finish up */
while (runState != ALL_STOP)
taskDelay (1);
/* clean up */
semDelete (syncSemId);
printf ("Simple executed %d times.\n",count);
}
/*
$Log: simple.c,v $
Revision 1.1 2007-03-12 05:47:46 se463
Set for the first day of class.
*/