Real-Time Operating Systems Laboratory Report

19
Real-Time Operating Systems Laboratory Report Salvatore Campione 145781 Vittorio Giovara 149374 Alberto Grand 149389 Academic Year 2008-2009

description

This is our laboratory report for our couse Real-Time Operating Systems. We prepared a complete toolchain and operating system from the RTEMS sources, created a concurrent program (readers and writers) and executed it. By Salvatore Campione, Vittorio Giovara and Alberto Grand.

Transcript of Real-Time Operating Systems Laboratory Report

Page 1: Real-Time Operating Systems Laboratory Report

Real-Time Operating Systems Laboratory Report

Salvatore Campione 145781Vittorio Giovara 149374Alberto Grand 149389

Academic Year 2008-2009

Page 2: Real-Time Operating Systems Laboratory Report

Contents

1 Introduction 2

2 First Steps 3

3 Using RTEMS 53.1 Operating System Compilation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53.2 Sample Programs and Stack Overflows . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

4 Creating Custom Programs 74.1 Makefile and Defines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74.2 Manual Activation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74.3 Analysis of execution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

A Test program – Readers and Writers 12

1

Page 3: Real-Time Operating Systems Laboratory Report

Chapter 1

Introduction

In this report we will present the workflow for configuring a simple concurrent program on an embeddedsystem.

The target architecture will be an ARM system, supported by the RTEMS operating systems; a crosstoolchain will be used for preparing the code and simulate it.

For test and simulation of the code we will use Skyeye program, while for compilation we will use across variant of the GNU Compiler Collection.

2

Page 4: Real-Time Operating Systems Laboratory Report

Chapter 2

First Steps

The first operation was to set up the correct environment for accessing the cross toolchain, installed in/opt/rtems-4.8; so we issued the following command:

export PATH="/opt/rtems-4.8/bin:$PATH"

After that we tried to compile with arm-rtems4.8-gcc a very simple C program that follows:

#include <stdio.h>

int main () {int a,b,c;

a = 2;b = 3;

c = a + b;

return 0;}

The code seemed to compile fine, but a warning was issued claiming that the START symbol wasdefaulted to 0x0008000:

/opt/rtems-4.8/lib/gcc/arm-rtems4.8/4.2.2/../../../../arm-rtems4.8/bin/ld:warning: cannot find entry symbol _start; defaulting to 00008000

If we tried to ignore this warning and simulate it, the program would not execute.So having a look at the assembly code, obtained by means of arm-rtems4.8-objdump -d,

we were hinted that the processor was starting to read the program from a location that contained onlygarbage code:

Disassembly of section .text:

00008000 <rtems_provides_crt0>:8000: e12fff1e bx lr

00008004 <malloc>:

3

Page 5: Real-Time Operating Systems Laboratory Report

8004: e3a00000 mov r0, #0 ; 0x08008: e12fff1e bx lr

[...]

In order to solve this problem we tried to force the START symbol to the location the processor wasreading from first, and thus we modified the default linker configuration with this script:

MEMORY{

ram (W) : ORIGIN = 0x00000000, LENGTH = 0x00008000}

SECTIONS{

. = 0x00000000;

.text : { *(.text) } > ram_start = 0x00000000;

}

We generated the object files only with arm-rtems4.8-gcc -o file.o file.c and sub-sequently used arm-rtems4.8-ld ldscript.ld file.o, which read the configuration fromthe ldscript.ld file. Now the compilation didn’t issue any warning, so we addressed the Skyeyeconfiguration. We initially set the configuration to the following:

cpu: arm7tdmimach: at91mem_bank: map=M, type=RW, addr=0x00000000, size=0x00008000

We ran the compilation and tried to simulate, but Skyeye seemed stuck. Therefore, we debugged bymeans of arm-rtems4.8-gdb and inferred from the following message that the system was blockedon the first instruction:

Single stepping until exit from function rtems_provides_crt0,which has no line number information.

By inspecting the disassembled code again, we saw that garbage code was still found at the executionentry point. At this stage, we realised that the startup code, which should have been provided by RTEMS,was missing: without some code for allocating memory, stacks and I/O segments the application wedeveloped would never have worked at all (on any system). This piece of code is either written by thedeveloper or is provided by the operating systems: this is why we have to configure and use RTEMS asa base for developing our programs.

4

Page 6: Real-Time Operating Systems Laboratory Report

Chapter 3

Using RTEMS

3.1 Operating System Compilation

Once we understood that some kind of operating system was nedeed for applications to work properly,our next target was to successfully compile RTEMS for our architecture, using an appropriate toolchain.

After setting up the environment and reading the provided documentation, we went to the RTEMSsource directory and first tried a default configuration; however, the code stopped compiling quite soon(as expected!), so we ran the proposed configuration:

export PREFIX=./rtems-test./configure --target=arm-rtems4.8 --disable-posix

--disable-networking --disable-cxx--enable-rtemsbsp=rtl22x --prefix=$PREFIX

but we soon found out that the board name was wrongly spelled and that the prefix installationlocation required an absolute path. So we corrected the configuration string and experienced a successfulcompilation.

export PREFIX=/opt/arm-rtems4.8./configure --target=arm-rtems4.8 --disable-posix

--disable-networking --disable-cxx--enable-rtemsbsp=rtl22xx --prefix=$PREFIX

make && make install

We noticed that in other compilation tests it was impossible to compile on a file system that didn’tsupport symbolic links and permissions (like FAT); moving the source and build directory to a file systemlike ext3 or reiserfs solves this kind of problems.

3.2 Sample Programs and Stack Overflows

Having succeeded in compiling the operating system, we were then ready to test some of the sampleprograms with Skyeye.

At first Skyeye refused to work, due to a bad configuration file; looking on the Skyeye website wefound the correct configuration for our board, which is reported below:

cpu: arm7tdmimach: lpc2210mem_bank: map=M, type=RW, addr=0x00000000, size=0x00004000

5

Page 7: Real-Time Operating Systems Laboratory Report

mem_bank: map=M, type=RW, addr=0x81000000, size=0x08000000mem_bank: map=M, type=RW, addr=0x40000000, size=0x00400000mem_bank: map=I, type=RW, addr=0xE0000000, size=0xFFFFFFFmem_bank: map=I, type=RW, addr=0xF0000000, size=0xFFFFFFF

Now we faced a very odd behavior: some of the test programs ran fine, or with minor warnings aboutI/O addressing, while many others printed random error strings or just closed with unexpected results.

Fearing some misconfigurations, we tried starting over on our computers, recompiling also the cross-toolchain from scratch, but with no avail.

So we were suggested that we should try debugging our application again with the cross GNU De-bugger (arm-rtems-4.8-gdb) and Skyeye launched in debug mode (skyeye -d). After sometinkering we were finally able to understand the problem: a stack overflow. Since our board is very sim-ple, the Memory Management Unit is disconnected and so no memory protection is used. We noticedthat many programs, after the initialization of the stack, soon filled up the reserved stack size and startedoverwriting other memory locations.

As a matter of fact we gathered this set of information by debugging:

stack type start address end address stack sizeabort mode 0x81010250 0x810102A0 80 Binterrupt mode 0x810102A0 0x810103A0 256 Bfast interrupt mode 0x810103A0 0x810103F0 80 Bsupervisor mode 0x810103F0 0x810104F0 256 B

from which we deduced that in our configuration all programs are executed in supervisor mode,having access to all available system directives, and that of the 0x100memory location of the supervisorstack, 0x64 entries are protected, leaving only 0x9C of available stack space. These values were due tothe source files given for the first compilation.

So in order to see if an actual stack overflow was generated, we set up a watchpoint in the debuggerlike the following:

watch ( $sp < 0x810103F0 )

where sp is the stack pointer of the segment. After initialization and some iterations of the program,the watchpoint was activated and reported that an actual stack overflow was present; subsequently theprogram began its random behavior.

So we thought that the size of the main stack was too small and tried increasing it by modifying thelinkcmds file of our board, where all startup symbols are defined. Setting a stack size of 0xF00 bytesand recompiling from scratch provided us with a working toolchain capable of running all the sampleprograms available.

6

Page 8: Real-Time Operating Systems Laboratory Report

Chapter 4

Creating Custom Programs

4.1 Makefile and Defines

We tried the Readers and Writers paradigm as our test program: studying the main scheme presented dur-ing lessons we created our version of the problem using RTEMS directives. The Makefile we wrote wastaken from one of the sample programs and modified accordingly; exporting the necessary environmentvariable

export RTEMS_MAKEFILE_PATH=/opt/rtems-4.8/arm-rtems/rtl22xx/

allowed us to skip inserting manually the included libraries and to invoke directly the make commandfor quick compilation.

4.2 Manual Activation

After writing our program we compiled it with no errors or warnings. However, only the main thread (or“task”, in RTEMS nomenclature) was executed while all the other tasks did not start.

We discovered that our programming procedure was not suited for embedded systems; as a matter offact, we were used to take for granted very important components like the scheduler, the counters, eventhe clock, but in real time operating systems these units must be activated manually.

In order to activate these features, some proper #define’s must be set up within the code, namely

#define CONFIGURE APPLICATION NEEDS CLOCK DRIVERactivates the clock;

#define CONFIGURE APPLICATION NEEDS CONSOLE DRIVERactivates the ticker;

#define CONFIGURE RTEMS INIT TASKS TABLEinitializes the task table;

#define CONFIGURE MAXIMUM TASKS (2*(N WRITER + N READER))sets up the number of concurrent thread.

The minimum number of tasks is overestimated, since RTEMS creates further tasks to provide times-licing and other features.

7

Page 9: Real-Time Operating Systems Laboratory Report

4.3 Analysis of execution

The next step was to simulate the code we wrote in order to verify the correct execution of the program.A first analysis with 3 Writers and 5 Readers, with a buffer of 50 slots, was executed. The following

output was obtained in response:

Your elf file is little endian.uart_mod:0, desc_in:, desc_out:, converter:start addr is set to 0x81000000 by exec file.CCCCCCCCCCERROR:io_write a non-exsiting addr:addr = fffff140, data = 810012d0

ERROR:io_write a non-exsiting addr:addr = fffff144, data = 810012d0ERROR:io_write a non-exsiting addr:addr = fffff148, data = 810012d0ERROR:io_write a non-exsiting addr:addr = fffff14c, data = 810012d0ERROR:io_write a non-exsiting addr:addr = fffff150, data = 810012d0ERROR:io_write a non-exsiting addr:addr = fffff154, data = 810012d0ERROR:io_write a non-exsiting addr:addr = fffff158, data = 810012d0ERROR:io_write a non-exsiting addr:addr = fffff15c, data = 810012d0ERROR:io_write a non-exsiting addr:addr = fffff160, data = 810012d0ERROR:io_write a non-exsiting addr:addr = fffff164, data = 810012d0ERROR:io_write a non-exsiting addr:addr = fffff168, data = 810012d0ERROR:io_write a non-exsiting addr:addr = fffff16c, data = 810012d0ERROR:io_write a non-exsiting addr:addr = e000403c, data = 0Writer 0 ha scritto: 0Writer 0 ha scritto: 3Writer 0 ha scritto: 6Writer 0 ha scritto: 9Writer 0 ha scritto: 12Writer 0 ha scritto: 15Writer 0 ha scritto: 18Writer 0 ha scritto: 21Writer 0 ha scritto: 24Writer 0 ha scritto: 27Writer 0 ha scritto: 30Writer 0 ha scritto: 33Writer 0 ha scritto: 36Writer 0 ha scritto: 39Writer 0 ha scritto: 42Writer 0 ha scritto: 45Writer 0 ha scritto: 48Writer 0 ha scritto: 51Writer 0 ha scritto: 54Writer 0 ha scritto: 57Writer 0 ha scritto: 60Writer 0 ha scritto: 63Writer 0 ha scritto: 66Writer 0 ha scritto: 69Writer 0 ha scritto: 72Writer 0 ha scritto: 75Writer 0 ha scritto: 78Writer 0 ha scritto: 81

8

Page 10: Real-Time Operating Systems Laboratory Report

Writer 0 ha scritto: 84Writer 0 ha scritto: 87Writer 0 ha scritto: 90Writer 0 ha scritto: 93Writer 0 ha scritto: 96Writer 0 ha scritto: 99Writer 0 ha scritto: 102Writer 0 ha scritto: 105Writer 0 ha scritto: 108Writer 0 ha scritto: 111Writer 0 ha scritto: 114Writer 0 ha scritto: 117Writer 0 ha scritto: 120Writer 0 ha scritto: 123Writer 0 ha scritto: 126Writer 0 ha scritto: 129Writer 0 ha scritto: 132Writer 0 ha scritto: 135Writer 0 ha scritto: 138Writer 0 ha scritto: 141Writer 0 ha scritto: 144Writer 0 ha scritto: 147Reader 1 ha letto: 0Reader 2 ha letto: 3Reader 3 ha letto: 6Reader 4 ha letto: 9Reader 0 ha letto: 12Reader 1 ha letto: 15Reader 0 ha letto: 18Reader 4 ha letto: 21Reader 3 ha letto: 24Reader 2 ha letto: 27Writer 0 ha scritto: 150Writer 1 ha scritto: 1Writer 2 ha scritto: 2Reader 1 ha letto: 30Reader 2 ha letto: 33Reader 3 ha letto: 36Reader 4 ha letto: 39Reader 0 ha letto: 42Writer 0 ha scritto: 153Writer 1 ha scritto: 4Writer 2 ha scritto: 5Reader 1 ha letto: 45Reader 0 ha letto: 48Reader 4 ha letto: 51Reader 3 ha letto: 54Reader 2 ha letto: 57Writer 0 ha scritto: 156

9

Page 11: Real-Time Operating Systems Laboratory Report

Writer 1 ha scritto: 7Writer 2 ha scritto: 8Reader 1 ha letto: 60Reader 2 ha letto: 63Reader 3 ha letto: 66Reader 4 ha letto: 69Reader 0 ha letto: 72Writer 0 ha scritto: 159Writer 1 ha scritto: 10Writer 2 ha scritto: 11Reader 1 ha letto: 75Reader 0 ha letto: 78Reader 4 ha letto: 81Reader 3 ha letto: 84Reader 2 ha letto: 87Writer 0 ha scritto: 162Writer 1 ha scritto: 13Writer 2 ha scritto: 14Reader 1 ha letto: 90Reader 2 ha letto: 93Reader 3 ha letto: 96Reader 4 ha letto: 99Reader 0 ha letto: 102Writer 0 ha scritto: 165Writer 1 ha scritto: 16Writer 2 ha scritto: 17Reader 1 ha letto: 105Reader 0 ha letto: 108Reader 4 ha letto: 111Reader 3 ha letto: 114Reader 2 ha letto: 117Writer 0 ha scritto: 168Writer 1 ha scritto: 19Writer 2 ha scritto: 20Reader 1 ha letto: 120Reader 2 ha letto: 123Reader 3 ha letto: 126Reader 4 ha letto: 129Reader 0 ha letto: 132Writer 0 ha scritto: 171Writer 1 ha scritto: 22Writer 2 ha scritto: 23Reader 1 ha letto: 135Reader 0 ha letto: 138Reader 4 ha letto: 141Reader 3 ha letto: 144Reader 2 ha letto: 147

As you can see looking at the report above, the timeslice needs some time to start; this might be dueto the fact that each task has to execute its startup code, which can be somehow big, before starting the

10

Page 12: Real-Time Operating Systems Laboratory Report

job for which it was created. In fact, after some time, timeslicing starts working.Looking at the correctness of the execution, we can observe that the written and the read sequences

in the buffer are {0 3 6 9 12 15 18 ...}, pointing out that the solution is correct; moreover,the flow of readers and writers is not constant (i.e. W0, W1, W2, R0, R1, etc.) but it depends on thetimeslicing scheduler, which can easily be noticed looking at the report.

Although our implementation of “readers and writers” appeared to work, a sequence of errors oc-curred at the beginning of the simulation with SkyEye. These errors pointed out that SkyEye was not ableto write to some specific address locations, which corresponded to I/O addresses. By reading the pro-vided documentation, we found out that only 16 vectored interrupts are initialized by RTEMS. However,the maximum number of interrupts (BSP MAX INT was set to 28 in the irq.h header file. We tried tochange this value to 16 and recompile RTEMS. To our great satisfaction, the errors now disappeared:

Your elf file is little endian.uart_mod:0, desc_in:, desc_out:, converter:start addr is set to 0x81000000 by exec file.CCCCCCCCCC

Writer 0 ha scritto: 0Writer 0 ha scritto: 3Writer 0 ha scritto: 6Writer 0 ha scritto: 9Writer 0 ha scritto: 12Writer 0 ha scritto: 15Writer 0 ha scritto: 18[...]

11

Page 13: Real-Time Operating Systems Laboratory Report

Appendix A

Test program – Readers and Writers

#include <bsp.h>#include <rtems.h>#include <stdlib.h>#include <stdio.h>#define MAXBUF 50#define N_WRITER 10#define N_READER 20

rtems_task reader(int);rtems_task writer(int);void enter_reader(void);void enter_writer(void);void exit_reader(void);void exit_writer(void);

int count = 0;int rc = 0;rtems_id mutex_id /* protects rc */, db_id /* protects buffer */,

ts_id /* avoids starvation */, empty_id /* allow writer */,full_id /* allow reader */;

int buffer[MAXBUF];int in_ptr = 0, out_ptr = 0;rtems_id readers_id[N_READER];rtems_id writers_id[N_WRITER];

rtems_task Init(rtems_task_argument ignored){

int i, flag;rtems_time_of_day time;int code;time.year = 2008;time.month = 12;time.day = 16;time.hour = 9;time.minute = 0;time.second = 0;

12

Page 14: Real-Time Operating Systems Laboratory Report

time.ticks = 0;if (rtems_clock_set(&time) != RTEMS_SUCCESSFUL){

printf("Failure upon rtems_clock_set call\n");exit(3);

}

if (rtems_semaphore_create(rtems_build_name(’m’, ’u’, ’t’, ’x’), 1,RTEMS_COUNTING_SEMAPHORE, 0, &mutex_id) != RTEMS_SUCCESSFUL)

{printf("Failure upon semaphore \"mutex\" creation\n");exit(1);

}if (rtems_semaphore_create(rtems_build_name(’d’, ’b’, ’\0’, ’\0’), 1,

RTEMS_COUNTING_SEMAPHORE, 0, &db_id) != RTEMS_SUCCESSFUL){

printf("Failure upon semaphore \"db\" creation\n");exit(1);

}if (rtems_semaphore_create(rtems_build_name(’t’, ’s’, ’\0’, ’\0’), 1,

RTEMS_COUNTING_SEMAPHORE, 0, &ts_id) != RTEMS_SUCCESSFUL){

printf("Failure upon semaphore \"ts\" creation\n");exit(1);

}if (rtems_semaphore_create(rtems_build_name(’e’, ’m’, ’p’, ’\0’), MAXBUF,

RTEMS_COUNTING_SEMAPHORE, 0, &empty_id) != RTEMS_SUCCESSFUL){

printf("Failure upon semaphore \"empty\" creation\n");exit(1);

}if (rtems_semaphore_create(rtems_build_name(’f’, ’u’, ’l’, ’\0’), 0,

RTEMS_COUNTING_SEMAPHORE, 0, &full_id) != RTEMS_SUCCESSFUL){

printf("Failure upon semaphore \"full\" creation\n");exit(1);

}

/* create reader processes */for (i = 0; i < N_READER; i++){

if (rtems_task_create(rtems_build_name(’r’, ’e’, ’0’ + i, ’\0’), 1,RTEMS_MINIMUM_STACK_SIZE *2, RTEMS_DEFAULT_MODES | RTEMS_TIMESLICE,RTEMS_DEFAULT_ATTRIBUTES, &readers_id[i]) != RTEMS_SUCCESSFUL)

{printf("Failure upon creation of reader %d\n", i);exit(2);

}}

13

Page 15: Real-Time Operating Systems Laboratory Report

/* create writer processes */for (i = 0; i < N_WRITER; i++){

if ((code = rtems_task_create(rtems_build_name(’w’, ’r’, ’0’ + i, ’\0’), 1,RTEMS_MINIMUM_STACK_SIZE *2, RTEMS_DEFAULT_MODES | RTEMS_TIMESLICE,RTEMS_DEFAULT_ATTRIBUTES, &writers_id[i])) != RTEMS_SUCCESSFUL)

{printf("Failure upon creation of writer %d, code = %d\n", i, code);exit(2);

}}

/* start processes */flag = N_READER > N_WRITER;for (i = 0; i < (!flag ? N_READER : N_WRITER); i++){

if (rtems_task_start(readers_id[i], reader, i) != RTEMS_SUCCESSFUL){

printf("Failure upon start of reader %d\n", i);exit(2);

}if (rtems_task_start(writers_id[i], writer, i) != RTEMS_SUCCESSFUL){

printf("Failure upon start of writer %d\n", i);exit(2);

}}

for (i = (!flag ? N_READER : N_WRITER); i < (flag ? N_READER : N_WRITER); i++){

if (flag){

if (rtems_task_start(readers_id[i], reader, i) != RTEMS_SUCCESSFUL){

printf("Failure upon start of reader %d\n", i);exit(2);

}} else{

if (rtems_task_start(writers_id[i], writer, i) != RTEMS_SUCCESSFUL){

printf("Failure upon start of writer %d\n", i);exit(2);

}}

}rtems_task_delete( RTEMS_SELF );

}

14

Page 16: Real-Time Operating Systems Laboratory Report

rtems_task reader(int n){

int i;while (1){

enter_reader();printf("Reader %d ha letto: %d\n", n, buffer[out_ptr]);out_ptr = (out_ptr + 1) % MAXBUF;usleep(200000);exit_reader();

}}

rtems_task writer(int n){

int d = 0, i;while (1){

enter_writer();buffer[in_ptr] = n+d;printf("Writer %d ha scritto: %d\n", n, buffer[in_ptr]);in_ptr = (in_ptr + 1) % MAXBUF;d+= N_WRITER;exit_writer();

}}

void enter_reader(void){

if (rtems_semaphore_obtain(full_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT)!= RTEMS_SUCCESSFUL)

{printf("Failure upon semaphore \"full\" acquisition\n");exit(1);

}

if (rtems_semaphore_obtain(ts_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT)!= RTEMS_SUCCESSFUL)

{printf("Failure upon semaphore \"ts\" acquisition\n");exit(1);

}if (rtems_semaphore_release(ts_id) != RTEMS_SUCCESSFUL){

printf("Failure upon semaphore \"ts\" release\n");exit(1);

15

Page 17: Real-Time Operating Systems Laboratory Report

}if (rtems_semaphore_obtain(mutex_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT)

!= RTEMS_SUCCESSFUL){

printf("Failure upon semaphore \"mutex\" acquisition\n");exit(1);

}rc++;if (rc == 1)

if (rtems_semaphore_obtain(db_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT)!= RTEMS_SUCCESSFUL){printf("Failure upon semaphore \"db\" acquisition\n");exit(1);}

if (rtems_semaphore_release(mutex_id) != RTEMS_SUCCESSFUL){

printf("Failure upon semaphore \"mutex\" release\n");exit(1);

}}

void exit_reader(void){

if (rtems_semaphore_obtain(mutex_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT)!= RTEMS_SUCCESSFUL)

{printf("Failure upon semaphore \"mutex\" acquisition\n");exit(1);

}rc--;if (rc == 0)

if (rtems_semaphore_release(db_id) != RTEMS_SUCCESSFUL){printf("Failure upon semaphore \"db\" release\n");exit(1);}

if (rtems_semaphore_release(mutex_id) != RTEMS_SUCCESSFUL){

printf("Failure upon semaphore \"mutex\" release\n");exit(1);

}if (rtems_semaphore_release(empty_id) != RTEMS_SUCCESSFUL){

printf("Failure upon semaphore \"empty\" release\n");exit(1);

}

}

16

Page 18: Real-Time Operating Systems Laboratory Report

void enter_writer(void){

if (rtems_semaphore_obtain(empty_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT)!= RTEMS_SUCCESSFUL)

{printf("Failure upon semaphore \"empty\" acquisition\n");exit(1);

}

if (rtems_semaphore_obtain(ts_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT)!= RTEMS_SUCCESSFUL)

{printf("Failure upon semaphore \"ts\" acquisition\n");exit(1);

}if (rtems_semaphore_obtain(db_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT)

!= RTEMS_SUCCESSFUL){

printf("Failure upon semaphore \"db\" acquisition\n");exit(1);

}}

void exit_writer(void){

if (rtems_semaphore_release(full_id) != RTEMS_SUCCESSFUL){

printf("Failure upon semaphore \"full\" release\n");exit(1);

}

if (rtems_semaphore_release(db_id) != RTEMS_SUCCESSFUL){

printf("Failure upon semaphore \"db\" release\n");exit(1);

}if (rtems_semaphore_release(ts_id) != RTEMS_SUCCESSFUL){

printf("Failure upon semaphore \"ts\" release\n");exit(1);

}}

/* configuration information */

#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER

17

Page 19: Real-Time Operating Systems Laboratory Report

#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER

#define CONFIGURE_RTEMS_INIT_TASKS_TABLE

#define CONFIGURE_MAXIMUM_TASKS (2*(N_WRITER + N_READER))

#define CONFIGURE_INIT

#include <rtems/confdefs.h>

/* end of file */

18