Assignment title: Information
DIT165 Development of Embedded system 2017-02-16
Exercises and assignments, Part 3
Page nr 1
Exercises and assignments for the course DIT165 Development of Embedded systems _ Part 3
Work package nr 6 : Event driven door automat ( for XCC users) (Total points 10 p)
(Note : !! For not XCC user see further on after this part)
In this exercises you can write control programs for the MCC12 system with a connected door unit
ML13. The unit has the base address of 0xB00. The idea is to design programs, taking care of opening
and closing of the door. You will during the exercises develop three different programs with different
principles regarding the way of reading events such as sensor (or push button), door opened and
door closed event and finally a time out event for the end of a delay function. The programs should
be developed in the XCC12 and only be tested and verified in its simulator.
If you not have access to work in Windows which is necessary for installing XCC12 there are
alternative exercises 6_1alt to 6_4alt further on after 6_4 for you to do.
Exercise nr 6_1. Time based control program (exerc_6_1.c) (2p)
First you are going to develop a time-based implementation of the automatic door. The door will
operate in the following manner:
If someone approaches the door space (button pushed) the door will open.
After the door had been open (in several seconds, controlled by a simple loop) the door should
close automatically.
If someone approaches the door space while the door is closing, it
shall immediately reopen.
The main structure of the program is described roughly by the
following flowchart:
The implementation will be done entirely in the programming language C
and in one single module (file).
Control of the door unit ML13.
The door is controlled via four different 8 bits registers which is possible
to read from or write to depending on the register. The addresses for the
registers is the unit's base address (Address 0xB00) or base address +1.
You will find details about the register and what each bit in the different
registers are controlling in the XCC12 Help>>Help on XCC12 and IO
simulator.DIT165 Development of Embedded system 2017-02-16
Exercises and assignments, Part 3
Page nr 2
In general:
Control register: Address 0xB00 (write operation), same as base address for the ML13 unit.
By bit 0 you are able to start opening the door, it will open slowly and you can follow the opening
process bay watching the LED:s going on. By bit 1 you can start closing the door. Closing and opening
of the door could be done anytime even if the door is in its opening or closing phase.
Bit 7-2, Not used.
Bit 1, CLOSE 1 = Actuate "Close Door"
Bit 0, OPEN 1 = Actuate "Open Door"
Status register : Address 0xB00 ( read operation). Each bit describes a certain state of the door. For
example door is closed, door is opened …You can by this register check the actual state of the door.
Bit 7, CLOSING. 1 = The door is closing.
Bit 6, OPENING. 1 = Door is opening
Bit 5, S2: Sense 2. 1 = Door is closed
Bit 4, Not of interest
Bit 3, S1: Sense 1. 1 = Door is wide open.
Bit 2, Not of interest
Bit 1, RIGHT: Sensor B. 1 = Sensor B is activated (Button S2)
Bit 0, LEFT: Sensor A. 1 = Sensor A is activated (Button S1)
To do:
Your task is to write an ordinary control program in C with a structure as the flowchart above views
and verify its function in the simulator. For verifying the program, you must connect the door unit
ML13 to the simulator. For controlling the door opened time in this first exercise you can use a
simple for loop.
Exercise 6_2 Event (IRQ) driven control program (exerc_6_2) (3p)
In this task you shall develop an event driven implementation of the automatic door. The door will
operate in the same manner as before but every event at the door ( push of button, door opened,
and so on …) will be indicated by a interrupt request signal from the ML13 unit instead of repeatedly
read the control register to determinate if any event had occurred. The IRQ signal is in simulator
connected to the IRQ in pin on the CPU card if you on the door unit enable IRQ in menu "Interrupt"
on the ML13 unit.
Every event in the ML13 module will generate a hardware IRQ signal which is connected to the CPU
IRQ in port. The IRQ will, if the system is initiated for allowing interrupts, call for the defined IRQ
service routine. The IRQ service routines start address shall be stored in the vector table at the
position for the hardware interrupt IRQ (Address 0x3FF2).
The IRQ service routine can then check the source for the IRQ-request (Sensor, door closed,..) in the
IRQ status register (base address+1) and by use of a global variable send information of which eventDIT165 Development of Embedded system 2017-02-16
Exercises and assignments, Part 3
Page nr 3
in ML13 unit that caused the interrupt to the main control function. (Note: An interrupt function
can´t return a value) due to the way it is called.
Besides the interrupt from events in ML13 (IRQ) we will also use the microcontrollers Real Timer
Clock unit. This clock module can be configured to periodical generate a RTI interrupt (Real Timer
Interrupt).
For doing this you shall use an assembly – file (ML13_irq_asm_dit165.s12 ) with a number of
functions that can be used by calling them by a normal call from your own C-program module as
described below. The file could be downloaded from the course homepage in GUL.
You can configure the RTC module, through some registers, to generate a timer interrupt every x
millisecond. The configuration is in our case done by the function timerSetup() in the assembly file
ML13_irq_asm_dit165.s12. .
Before calling the assembly function from your C-program module (file) you must :
Included the .s12 file into the project in the XCC12 IDE.
In your C-program declare it in the program head as : extern void timerSetup()
The you can call the function from the C-program module as a normal call by : timerSetup();.
In this case we also will using the RTC to create a setTimeout(x) function for controlling the door
opened time. By calling this function with setTimeout (x), where x is the number of second's delay
we wish to create, you start a time delay that will cause a TIME_OUT interrupt to the system after
desired time defined by x. The IRQ routine will set the value of a global integer interruptType to
TIME_OUT indicating that the door should be closed.
[ Just for information if you look through the assembly code: After the call of setTimeout (x) the RTC
will generate RTI interrupts with a periodicity depending on the configuration in timerSetup(). At
every RTI interrupt the RTI routine (ptimirq) will decrease a counter. After a number of RTI:s the
counter will be zero and the function passes the TIME_OUT value to the the global variable
(interruptType). By this the main program gets the information of that the delay time is ended and in
this case the door shall be closed.]
Below is a roughly description of the main structure of the program.
The program shall consist of at least two modules
(files) one entirely written in C for the main control
program including the ML13 interrupt service routines
and one for all regarding the timer module written in
assembly. The last module you can download from the
course home page (ML13_irq_asm_dit165.s12). For
the C-module you can download a first draft for the
program to use for further develop to a solution
ML13_irq_prog_draft.c .
Both files should be included in the project when
compiled.
ML13
configure
Wait for an
interrupt
Interrupt service
routines
RTCDIT165 Development of Embedded system 2017-02-16
Exercises and assignments, Part 3
Page nr 4
On the course homepage you find the two files to download:
ML13_irq_asm_dit165.s12
Routines in assembly for initiate the system for managing of the Real Time Clock module. You should
just include the file in your project and use the functions. This module you should just use, not
changed anything in it. It shall be included in the project. The module includes the functions:
void standby(), _timerSetup() and setTimeout (x). The function void standby() is a routin in
assembly that just stop executing of the program until next interrupt call is generated.
ML13_irq_prog_draft.c
A main program in C to be further developed to a working program for this exercise.
The control loop in the main program shall, in the beginning of the loop, call the function, standby(),
that's just stops the execution of the program and waits until an interrupt occurs. When a TIME_OUT
irq is generated the ptimirq will be executed and set the global variable to TIME_OUT. For all door
events ( Sensor A , door opened …) the system is design to call the C-function :
__interrupt void ML13_interrupt( void )
In which you need to decide the source for the interrupt (for example door closed, door opened,
right sensor pushed…) by reading the ML13_IRQ_Status register and set the value on interrupType
to a value corresponding to the interrupt source.
The main program continue then after the interrupt routines with the code after standby() and now
with a value in interruptType that will be used to determine what to do before it once again run
standby().
You should do the following:
Create a workplace and a project for this exercise. Include both files above. Continue to develop the
C-program in order to get the system working as the first program. In the simulator we just use
setTimeout(1) or setTimeout(2) otherwise it will be to long delay. The delay function will generate a
TIME_OUT interruptType ( assigning the value of TIME_OUT to the variable) after the delayed time
has fulfilled.
The best way of working is to first develop a solution without any use of the delay-function. And
when that works include a delay by use of the setTimer(x) function.
Note: Do not forget to activate interrupt mode in the ML13 unit in the simulator.
Exercise 6_3 Non Preemptive Scheduling (Note : Exercises 6_3 shall not be handed in. You do
them just to be able to solve the exercises 6_4 and 6_5)
During this part, you will be introduced to a simple real-time kernel, RTK12. The kernel could be
included to a program that is developed in the XCC12 environment. The program using RTK12 kernel
could also be simulated in XCC12 as normal programs.
You can find more information about the RTK12 kernel in the XCC12 help system about libraries.DIT165 Development of Embedded system 2017-02-16
Exercises and assignments, Part 3
Page nr 5
A process
A RTK12 process has the same appearance as a C function without parameters. However, there are
some important differences that you have to consider when programming processes:
A process is not a function in the sense that it can be called from another process (or
function).
The execution of a process can, at any time, be interrupted and later continue its executing.
Several processes can share the same features, i.e. calling the same functions read and write
to the same variables (global). Please note that the global variables that are shared by
multiple processes (or used by functions that are shared by multiple processes) generally
must be protected from inconsistent update with mutual exclusion.
A typical program for executing of several processes is build up as follows:
// RTK12 - application
// Non preemptive scheduling
#include <_rtk.h>
#define TIMESLICE 5 // 5 for simulator mode and 100 for hardware
void AtInterrupt(void); // Declaration of the function that is called at the end of
every TIMESLICE
PROCESS P1(void); // PROCESS is defined in rtk.h as void.
PROCESS P2(void); // This is a declaration of the actual processes.
// P2 is the process name
int main(void){
/* This main function will be executed just once to set up the processes and the kernel.
It must contain the following:
Initiate RTK12
Create all processes
Start the kernel RTK12 // for running in simulator or in hardware
*/
InitKernel(TIMESLICE, AtInterrupt);
if( CreateProcess("P1", P1) == -1){
printl("\nCan't create process");
exit();
}
if( CreateProcess("P2", P2) == -1){
printl("\nCan't create process");
exit();
}
StartKernelForSim(); // This ends the execution of main()
return(0);
} // End mainDIT165 Development of Embedded system 2017-02-16
Exercises and assignments, Part 3
Page nr 6
// ----------------------------- First process -------------------------------
PROCESS P1(void)
{
DO_FOREVER // DO_FOREVER defined as while(1)
// This is the process loop that normally never should end.
{
outchar('1'); // A special putchar() function in startup.asm module
}
}
// ----------------------------- Next process -----------------------------
PROCESS P2(void){
DO_FOREVER
{
_outchar('2');
}
}
//------------- Interrupt routine called at the end of each TIMESLICE .
void AtInterrupt(void){
// Calls by a IRQ –routine after each full TIMESLICE
// Decides if time_irq should suspend the running process and start the next process
// in QUE or anything else
// Doing nothing will make the previous process to continue executing
}
Exercise 6_3_1
First you should use RTK12 to perform three processes during a "non-preemptive" scheduling strategy.
The application of this exercise, consists of a main program, two processes (P1 and P2) and an
interrupt handler. The main program follows exactly the structure described above. Note in
particular that an interrupt handler must be provided even if, as in this case, nothing special is done
at interrupt. We want to illustrate the non-preemptive scheduling and write therefore two processes
to be performed sequentially. Note that in general one can't make any assumption about the order
in which processes will be started by the real-time kernel. For RTK12 however the rule is that
processes are started in the order they created.DIT165 Development of Embedded system 2017-02-16
Exercises and assignments, Part 3
Page nr 7
Processes P1 and P2 are similar, and they look as follows:
PROCESS P1(void)
{
int i;
for(i=0;i < 100;i++)
_outchar('1');
TerminateProcess(0);
}
PROCESS P2(void)
{
int i;
for(i=0;i < 100;i++)
_outchar('2');
TerminateProcess(0);
}
The interrupt handler should in this case do nothing, but must be included:
void AtInterrupt(void)
{ }
To do : Write a needed main program and the above processes and test to run it in the simulator. For
seeing anything you must connect the console to the simulator.
Exercise 6_3_2 Preemptive Scheduling , Timesharing
Write a main program setting up three processes and write the processes. Each process should be
designed to run forever as below:
PROCESS P1(void){
DO_FOREVER {
// program code;
}
}
Each process should only print out the number of the process using the special function:
_outchar('nr')
The kernel will then through its Real Time Clock generate interrupts periodical and count the system
time. For each time the time reach the end of the time period specified by TIMESLICE the kernel will
change execution to the next process if we modify the AtInterrupt() function as shown below.DIT165 Development of Embedded system 2017-02-16
Exercises and assignments, Part 3
Page nr 8
void AtInterrupt(void){
// Call of two kernel functions. For information se lecture OH nr 6_1.pdf in GUL
insert_last(Running, &ReadyQ);
Running= remque(&ReadyQ);
}
To do: Write the program and test in the simulator and see what happens.
Exercise 6_4 : Use of semaphores ( Hand in as exerc_6_4.c) (1p)
In the previous chapter we learned how to implement a parallel programming model in a timesharing system. By considering each program as a process and let a real-time kernel manage these
processes, we can, in principle build a multi-tasking system. If the system comprises of a number of
independent processes it is relatively simple to implement but this is never the case in reality. In fact,
there is usually very close dependencies between the different processes in a real-time system.
Often, these dependencies consist of shared global data and special time dependencies. To cope with
these dependencies the processes must in a way be synchronize with each other.
Process synchronization in RTK12 is done by using semaphores. In RTK12 the Semaphores are
implemented as blocking / Queue type. The maximum number of semaphores is given by the
constant MAX_SEM_ID defined in the header file rtk.h. The following operations can be performed
on a semaphore:
void initsem (int id, int count);
The first parameter is an identification number between 1 and MAX_SEM_ID. The second parameter
assigns an initial value to the semaphore. Each semaphore is initialized once by the main program,
this occurs between the execution of InitKernel () and Start Kernel () or StartKernelForSim().
void waitsem (int);
The parameter is an identification number as above defined by initsem() . The process performs the
wait semaphore specified by the parameter. The routine assumes that the semaphore is initiated by
initsem ().
void signalsem (int);
The parameter is an identification number 1-MAX_SEM_ID. The process signals on the semaphore
specified by the parameter. The routine assumes that the semaphore is initiated by initsem ().
Time synchronization of processes
The task in this exercise is to construct a chain of events of synchronized processes. Processes "P1",
"P2", "P3" and "P4" from the previous exercise shall be executed in this order and be repeated in an
unfinished chain.
The processes must be modified so that they only write one character at a time to the screen.
Tip: You can call the semaphore (waitsem (Sx)) in one process while releasing the semaphore by
(signalsem (Sx)) in another process. In this way, you can synchronize the execution order.
Modify the processes in the previous step so that the printout from the processes changed to
'1234123412341234 ... ' etc.. Synchronization is done by using semaphores.DIT165 Development of Embedded system 2017-02-16
Exercises and assignments, Part 3
Page nr 9
Exercise 6_5 controlling the door system with process synchronization (4p)
After a series of operations aimed to make you familiar with a real-time kernel and get an idea of
how it can be used, it is time for you to solve a minor task namely the controlling of the door as you
done previously but now we will split the program to several processes.
Overall description.
The control of the door ML13 will now be implemented in a C program structured in several
processes with the support of the real-time kernel RTK12. We will use semaphores for synchronize
between the processes and by that ensure that only processes that for the moment is useful for the
system due to the system status. For example if the door is closed its only of interest to check if any
pushes the sensor for open the door and no meaning of checking the sensor for opened door.
In addition to earlier demand, open and close the door, we have the following demands:
The door shall be possible to 'lock' by pushing the key 'l' on the PC keyboard and unlocked if pushing
the 'u' key. Locking/unlocking the door may be made at any time and shall be manage by a separate
process reading the keyboard. ( Tip : to read the key use the special XCC function _tstchar()) . A way
to indicating the status locked / unlocked for the door is to use a global variable (int locked).
With "locked" door it means that it can´t be opened by pressing any of the buttons on the ML13. The
door should be locked from the start.
Below you will find a proposal on how to fundamentally solve the task. You are not bound to in detail
follow these steps, however, the "execution model" (see below) should be used in some ways and
the idea of several processes shall be adopted.
Execution Model
The program will be buildup by a number of processes that are synchronized with help of
semaphores and has a structure as below figure:
In the center we have a main process that provides all control signals to the door. The main process
can be synchronized with the processes that check the status of the door unit, preferably with
semaphores. The following pseudo-code indicates a possible solution:
status-signals
from ML13
Checking
event 1
Checking
event 2
Delay
function
Main
control
process
Control signals
from
ML13
Read
keyboard
Information transferred by
use of Semaphores
Information transfer by
use of a common global
variable
Control signals
to
ML13DIT165 Development of Embedded system 2017-02-16
Exercises and assignments, Part 3
Page nr 10
PROCESS manage_door () {
systemSetup
do forever {
enable "open_door_event" -process // (release the semaphore)
wait for "open-door" signal // ( wait for the event to occur)
open the door;
enable "door_opened_event" -process
wait for "door-opened signal"
wait for 5 seconds
close the door
}
}
Note below especially how semaphores can be used to "enable-events".
The execution model above shows how a number of processes monitoring the various events that
can occur in the door unit. For example:
Sensor is activated
The door is wide open
The door is fully closed ( not necessary to use in this solution)
Such a process can be designed, for example, as follows:
begin do forever:
wait for the event monitoring is enabled by a semaphore;
begin do forever
if (sensor pushed and not locked)
signal (open_the_door_sem)
break inner loop
else
call yield() function// shift to next process
end
end
The "yield" function
Most RT operating Systems has a yield-function which when it´s called leaves rest of the calling
process TIMESLICE to next executable process in the ready queue. In RTK12 there is no such feature,
so you have to write it by yourselves. It is a rather easy function but you have to use a number of
functions from the RT Kernel so you just get it here and you can copy it to your program.DIT165 Development of Embedded system 2017-02-16
Exercises and assignments, Part 3
Page nr 11
The code for the function is as below:
void yield(int dummy)
{ // Dummy parameter is for the 'suspend' to work well
DISABLE; // can't take process switch here
insert_last(Running, &ReadyQ); // Calling Process last in Rea
suspend(Running); // Saving context for Calling process
dispatch(); // Start next process in ready que
}
The Sleep() function
To create a delay time, in our case a time during which the door is fully open, you can create a
function that waits until the RT-kernel system clock reaches a certain time. The function consists of
an infinite loop in which it tests if the clock has reached the end time. If not the function call yield()
and by that start the next process in the queue. Next time the calling process get execution time the
function again tests the time. When the time at last reach the end time the function will end and the
calling process can execute further. In our hardware the sleep function will give a delay of
(delay*100) ms but in the simulator mode it will longer delays, approximately (delay)* 1 seconds.
The following code shows a simple implementation of the "sleep" function:
void sleep(int delay){
int wakeup;
wakeup = get_rtk_time() + delay; /* sleep for delay * TIMESLICE*/
while(1){
if( wakeup > get_rtk_time() )
yield(0); /* not morning yet... */
else
return;
}
}
What to do:
You shall develop a C-program that controls the opening and closing of the door with the same
demand as in the exercise 6_2. Additional it shall be possible to, via a key on the PC keyboard, at any
time lock or unlock the possibility to open the door. The program shall follow the above described
principles of using several processes. If you think there is some missing in the description of how the
opening/closing of the door shall function feel free to decide by yourself but of course it shall be a
realistic way of function.
For alternative WP 6 exercises se next page.DIT165 Development of Embedded system 2017-02-16
Exercises and assignments, Part 3
Page nr 12
Alternative WP 6 exercises for those not using the Windows based XCC12 IDE for a MCC12 CPU.
Below is a number of exercises that could be done of you not having access to XC12 IDE.
Exercise 6_1alt (exerc 6_1alt.c) Time based control program (2p)
In this first exercise you should develop a draft for a program, possible to compile but not possible to
run or test. You should just show and explain the solution for the TA.
You shall develop a time-based implementation of the automatic door. The door will operate in the
following manner:
If someone approaches the door space (button S1 /S2 pushed) the door will open.
After the door had been open (in several seconds, controlled by a simple loop) the door should
close automatically.
If someone approaches the door space while the door is closing, it shall immediately reopen.
The main structure of the program is described roughly by the following flowchart:
The implementation will be done entirely in the programming
language C and in one single module (file).
Control of the door unit ML13.
The door is connected to the computer system and controlled via
four different 8 bits registers which is possible to read or write to
depending on the register. The addresses for the registers is the
units base address ( Address 0xB00 ) or base address +1.
In general:
Control register: Address 0xB00 (write operation).
By bit 0 you are able to start opening the door, it will open slowly
and you can follow the opening process bay watching the LED:s
going on. By bit 1 you can start closing the door. Closing and
opening of the door could be done anytime even if the door is in
its opening or closing phase.
Bit 7-2, Not used.
Bit 1, CLOSE write 1 = > Actuate "Close Door"
Bit 0, OPEN write 1 = >Actuate "Open Door"DIT165 Development of Embedded system 2017-02-16
Exercises and assignments, Part 3
Page nr 13
Status register : Address 0xB00 ( read operation). Each bit is represented the state of the door. For
example door is closed, door is opened …You can by reading the bits in this register check the actual
state of the door.
Bit 7, CLOSING. 1 = The door is closing.
Bit 6, OPENING. 1 = Door is opening
Bit 5, S2: Sense 2. 1 = Door is closed
Bit 4, Not of interest
Bit 3, S1: Sense 1. 1 = Door is wide open.
Bit 2, Not of interest
Bit 1, RIGHT: Sensor B. 1 = Sensor B is activated (Button S2)
Bit 0, LEFT: Sensor A. 1 = Sensor A is activated (Button S1)
To do:
Your task is to write a draft for a control program. Below you have a program head with some
declarations and other initiations. Try to make a draft control program that solve the problem with a
structure that the flowchart above views. The Dalay() function can be implemented as a simple for
loop with a conter.
Compile the program to ensure the syntax. You can´t test the program. The only thing you can do is
to explain the program to the TA and they will respond if it seems to be a working solution or not. If
rather good he will give you a pass code and you can hand in the solution.
#define ML13_Status 0x0B00
#define ML13_Control 0x0B00
#define read_control *((char *)ML13_Status)
#define set_control(x) *((char *)ML13_Control)=x
void main () {
… }
Exercise 6_2alt (exerc 6_2alt.c) (1p)
At GUL homepage you can find a file sortandfind_wp6_6_2.c The code contained in file performs
the following operations:
1. It creates an array of integer numbers with the given number of elements.
2. Fills such array with random integer numbers whose max value is given by the user [STEP 1].
3. Sorts such array [STEP 2].
4. Looks for a specific value given by the user using binary search [STEP 3].DIT165 Development of Embedded system 2017-02-16
Exercises and assignments, Part 3
Page nr 14
Answer the following questions:
1. How many threads (in total) are created during the execution of the program?
2. What are lines 13, 14, 16, 21 and 22 intended for?
3. How many parameters are passed to function runner?
4. How can function runner know the values for parameters that, such as max value, are not
passed to it?
5. How would the behavior of the program change if line 22 was omitted?
To do : Study the program and write your answer in a simple text document exerc6_2alt.txt and view
it for the TA and they will give you a pass code if ok. Hand it in together with the other files.
Exercise 6_3alt (exerc 6_3alt.c) (2p)
Rewrite the application contained in sortandfind_wp6_6_2.c so that each of the three main steps
(filling the array / sorting and the array / finding the value given by the user) are executed by 3
different threads. Enrich the function run by each thread with a printf( ) stating which of the 3 steps
the thread is running.
Exercise 6_4alt (exerc 6_4alt.c) (5p)
Testing synchronization of threads in C-programming
By using a library pthread.h you can create a number of theads (light weight processes) from your
program. This task for you is to test threads and some synchronization primitives (semaphores and
condition variables).
You can find related information about this at:
http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html
The main task for you is to try to develop a program demonstrating a circular buffer in which it
should be possible for threads to write in buffer ( in this case a character) and to read a character
(take out) from buffer. All writing and reading from buffer should be without losing data or getting it
out in wrong order.
The Buffer and its two index number is global
Global / Shared variables
char buffer[MAX]; // circular buffer . Test for MAX 5 and 10.
int write_pos; // index for next character to be put in buffer (put)
int read_pos; // index for next character to be read ( fetch )
int count; // the number of characters in buffer not fetched.DIT165 Development of Embedded system 2017-02-16
Exercises and assignments, Part 3
Page nr 15
For synchronization there are some function in the pthread library you can use:
pthread_mutex_init(); pthread_mutex_lock(); phtread_mutex_unlock() and
pthread_cond_signal(),pthread_cond_wait.
To compile the program you have to add the library pthread when compiled as follows:
gcc filename.c -o program -lpthread
The program should have the following structure and function.
A main program for setting up and start running two threads as described below. The main program
should after started up the threads continue in a loop as you can see in the program skeleton below.
(You find the code at the homepage in file skeleton_wp6_6_4.c)
The first thread, producer(), should create characters a,b,c…z ; a,b,c…. and store them in the buffer in
a infinitive loop. For every character stored it should call a cond_signal telling other threads that
buffer not empty. If buffer full (MAX number of characters in buffer) the thread should wait for a
cond_signal 'not full' from the other consuming thread telling that buffer is not full. The second
thread, consumer(), should fetch out the character in first position to be fetched from the buffer and
print it out in the console window. If no character in buffer it should wait for a cond_signal 'not
empty' from the producer thread that signal every time it stores a new character in buffer. The result
should be that the program prints out 'abcdef…z''abcd…z' in correct alphabetical order. Between the
letters the main() loop prints out the textstring when it is running as the picture in figure below
shows one possible example of output.
You can find additional information regarding circular buffer, pthread and so on internet