Embry-Riddle Real-Time Laboratory Experiment
Experiment #8
Signals


Introduction

A signal is a software notification to a task or a process of an event. A signal is generated when the event that causes the signal occurs. A signal is delivered when a task or a process takes action based on that signal. The lifetime of a signal is the interval between its generation and its delivery. A signal that has been generated but not yet delivered is pending. There may be considerable time between signal generation and signal delivery.

VxWorks supports a software signal facility. The signals asynchronously alter the control flow of task. Any task can raise a signal for a particular task. The task being signaled immediately suspends its current thread of execution and the task specified signal handler routine is executed the next time the task is scheduled to run. The signal handler gets invoked even if the task is blocked on some action or event. The signal handler is a user supplied routine that is bound to a specific signal and performs whatever actions are necessary whenever the signal is received. Signals are most appropriate for error and exception handling, rather than general intertask communication.

The Wind kernel has both BSD 4.3 and POSIX signal interface. The POSIX interface provides a standardized interface which is more functional than BSD 4.3 interface. Your application should use only one interface and not mix the two.


Objectives

The following are the primary objectives of this experiment:


Description

The signal facility provides a set of 31 distinct signals(see VxWorks Manual). A signal can be raised by calling kill(), which is analogous to an interrupt or hardware exception. A signal is bound to a particular signal with sigaction(). While the signal handler is running, other signals are blocked from delivery. Tasks can block the occurence of certain signals with sigprocmask(); if a signal is blocked when it is raised, its handler routine will be called when the signal becomes unblocked.

Signal handlers are typically defined as:
void sigHandlerFunction(int signalNumber)
{
.............. /* signal handler code */
..............
..............
}

where signalNumber is the signal number for which sigHandlerFunction is to be invoked for.

The sigaction function installs signal handlers for a task:

A data structure of type struct sigaction holds the handler information. The sigaction call has three parameters: the signal number to be caught, a pointer to the new handler structure(of type struct sigaction), and a pointer to the old structure(also of type struct sigaction). If the program does not need the value of the old handler(*pOact), pass a NULL pointer for *pOact.

To direct a specific signal to a specific task, the kill(int, int) call is made where the first argument the task id to send signal to, and the second argument is the signal to send to the task .

1. Example:

In the example below, the "sigGenerator" function generates the SIGINT or Ctrl-C signal, and directs the signal to the "sigCatcher" task. When "sigCatcher" receives the signal, it suspends its normal execution and branches to a signal hander that it has installed(catchSIGINT function).

------------------------------------------------------------------------------------
/* includes */
#include "vxWorks.h"
#include "sigLib.h"
#include "taskLib.h"
#include "stdio.h"

/* function prototypes */
void catchSIGINT(int);
void sigCatcher(void);
 
/* globals */
#define NO_OPTIONS 0
#define ITER1 100
#define LONG_TIME 1000000
#define HIGHPRIORITY 100
#define LOWPRIORITY 101
int ownId;

void sigGenerator(void) /* task to generate the SIGINT signal */
{
int i, j, taskId;
STATUS taskAlive;

if((taskId = taskSpawn("signal",100,0x100,20000,(FUNCPTR)sigCatcher,0,0,0,0,0,0,0,
	0,0,0)) == ERROR)
	printf("taskSpawn sigCatcher failed\n");

ownId = taskIdSelf(); /* get sigGenerator's task id */

taskDelay(30); /* allow time to get sigCatcher to run */

for (i=0; i < ITER1; i++)
	{
	if ((taskAlive = taskIdVerify(taskId)) == OK)
    		{
    		printf("+++++++++++++++++++++++++++++++SIGINT sinal generated\n");
    		kill(taskId, SIGINT); /* generate signal */
    		/* lower sigGenerator priority to allow sigCatcher to run */
    		taskPrioritySet(ownId,LOWPRIORITY);  
    		}
    	else  /* sigCatcher is dead */
    		break; 
	}  
printf("\n***************sigGenerator Exited***************\n");
}

void sigCatcher(void) /* task to handle the SIGINT signal */
{
struct sigaction newAction;
int i, j;

newAction.sa_handler = catchSIGINT; /* set the new handler */
sigemptyset(&newAction.sa_mask); /* no other signals blocked */
newAction.sa_flags = NO_OPTIONS;	/* no special options */

if(sigaction(SIGINT, &newAction, NULL) == -1)
	printf("Could not install signal handler\n");

for (i=0; i < ITER1; i++)
  	{
    	for (j=0; j < LONG_TIME; j++);
    	printf("Normal processing in sigCatcher\n");
    	}	
  	
printf("\n+++++++++++++++sigCatcher Exited+++++++++++++++\n");
}

void catchSIGINT(int signal)  /* signal handler code */
{
printf("-------------------------------SIGINT signal caught\n");
/* increase sigGenerator priority to allow sigGenerator to run */
taskPrioritySet(ownId,HIGHPRIORITY); 
}

------------------------------------------------------------------------------------


Procedures

1. Copy the source code in the example and compile it.

2. Load the object file onto the target machine.

3. Run the examples by executing the main routine("sigGenerator") of the example on WindSh terminal.

Note: Make sure you have redirected I/O, otherwise you won't see the results of the printf commands.

Follow On Experiment

Experiment 1. Modify the program above so that there is no signal handler associated with "sigCatcher." What happens when the SIGINT signal is now delivered to "sigCatcher?"

Experiment 2. Modify the program above so that the SIGINT signal is blocked(i.e. "sigCatcher" is prevented from receiving the SIGINT signal).

Additional Information

Refer to VxWorks User's Manual and Reference Manual.


Return to Primary Table of Contents


Last Updated: 4 April 1997
Created by: Dan Eyassu
eyassud@db.erau.edu