Radboud University Nijmegen

Real-time Linux (Xenomai)

Exercise #1: Getting started


Objectives

The following are the primary objectives of this exercise:


Creating a task

Starting a task

Hello World example program

The following "ex01a.c" C code illustrates the creating and start of a "demo" task which writes a message.
Note that in "main" the character array "str" is used for the name of the task. This array must be long enough to store the string used in sprintf plus an additional null character.

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

#include <alchemy/task.h>

RT_TASK hello_task;

// function to be executed by task
void helloWorld(void *arg)
{
  RT_TASK_INFO curtaskinfo;

  printf("Hello World!\n");

  // inquire current task
  rt_task_inquire(NULL,&curtaskinfo);

  // print task name
  printf("Task name : %s \n", curtaskinfo.name);
}

int main(int argc, char* argv[])
{
  char  str[10];

  printf("start task\n");
  sprintf(str,"hello");

  /* Create task
   * Arguments: &task,
   *            name,
   *            stack size (0=default),
   *            priority,
   *            mode (FPU, start suspended, ...)
   */
  rt_task_create(&hello_task, str, 0, 50, 0);

  /*  Start task
   * Arguments: &task,
   *            task function,
   *            function argument
   */
  rt_task_start(&hello_task, &helloWorld, 0);
}


Compiling a Xenomai program

To compile the program ex01.c we use the following Makefile 

XENO_CONFIG := /usr/xenomai/bin/xeno-config

CFLAGS := $(shell $(XENO_CONFIG)   --posix --alchemy --cflags)
LDFLAGS := $(shell $(XENO_CONFIG)  --posix --alchemy --ldflags)

CC := gcc   
EXECUTABLE := ex01a

all: $(EXECUTABLE)

%: %.c
	$(CC) -o $@ $< $(CFLAGS) $(LDFLAGS)

clean: 
	rm -f $(EXECUTABLE)

Then the command

> make

will build the executable ex01a which can be executed using

> ./ex01a

Printing

Note that by adding the “posix” flag in the Makefile, printf is mapped to rt_printf which puts text to be printed in a buffer. The actual printing is done by a non-real-time periodic thread.

Error handling

Xenomai uses the standard errors defined in the headers:

The Xenomai API specifies for each function is specified which specific errors are generated when an error happens. However the more general errors like passing the wrong value to a function are not specified by the API. Hence, it is possible to obtain an error code not specified in the API documentation.

The strerror function provides a convenient way to stop a program and print the error. The following example demonstrates this


#include <errno.h> ...

/* send message */
retval = rt_task_send(&task_struct[1], &task_mcb , NULL, TM_INFINITE);
if (retval < 0 )
{
printf("Sending error %d : %s\n",-retval,strerror(-retval));
} else {
printf("taskOne sent message to taskTwo\n");
}



Exercises

Exercise 1a.

Compile and run program ex01a.c as described above, using the files ex01a.c and Makefile.

Exercise 1b.

Copy file ex01a.c to ex01b.c and introduce an error by changing

rt_task_start(&hello_task, &helloWorld, 0);
into

rt_task_start(NULL, &helloWorld, 0);

Add ex01b to the EXECUTABLE list in the Makefile by

EXECUTABLE := ex01a ex01b
Next build and run this program; observe the result.

Next introduce a return value for the 'rt_task_start' call and print the error code as described above.

Rebuild and rerun the new version of the program, observe the different output.


Last Updated: 26 June 2019 (Jozef Hooman)
Created by: Harco Kuppens
h.kuppens@cs.ru.nl