0% found this document useful (0 votes)
63 views16 pages

Real-Time Systems Lab Guide

This document describes using event flags for inter-task communication in the Micrium real-time operating system. It defines the built-in functions for creating, deleting, waiting for, and setting event flags. An example program is provided that uses event flags to synchronize four tasks, with each task waiting for a flag from the previous one before setting a flag for the next.

Uploaded by

gdharshini203
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
63 views16 pages

Real-Time Systems Lab Guide

This document describes using event flags for inter-task communication in the Micrium real-time operating system. It defines the built-in functions for creating, deleting, waiting for, and setting event flags. An example program is provided that uses event flags to synchronize four tasks, with each task waiting for a flag from the previous one before setting a flag for the next.

Uploaded by

gdharshini203
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

[Link]: 7.

A
EVENT FLAG REGISTER USING OPEN SOURCE
DATE: REAL-TIME RTX KERNEL

1. AIM:
To understand the use of inter – task communication in real – time kernel by
implementing event flag register using Keil version 4.

2. TOOLS REQUIRED:
▪ Keil µ vision 4

▪ RTX Kernel

3. EVENT FLAG :
In a real-time operating system (RTOS), an event flag is a synchronization primitive
used to facilitate communication and coordination between tasks or interrupt service routines
(ISRs). Event flags are typically implemented as a set of binary flags, each representing a
specific event or condition.

• Flag Definition: Each event or condition that tasks need to synchronize on is


assigned a unique flag or bit in the event flag set.
• Flag Setting: Tasks or ISRs set individual flags in the event flag set to indicate
that certain events or conditions have occurred.
• Flag Waiting: Tasks or ISRs can wait for specific flags to be set before
proceeding with their execution. They can choose to wait for one or more flags
to be set, depending on their synchronization requirements.
• Flag Clearing: After a task or ISR has responded to a specific event or
condition, it may clear the corresponding flag in the event flag set to indicate
that the event has been processed.

Event flags are useful for implementing complex synchronization scenarios where tasks
or ISRs need to coordinate their actions based on various events or conditions. They provide a
lightweight and efficient mechanism for inter-task communication and synchronization in real-
time systems.

The event flags management functions in CMSIS-RTOS allow you to control or wait
for event flags. Each signal has up to 31 event flags.

103
21EE61 – REAL-TIME SYSTEMS LABORATORY
A Thread

• can wait for event flags to be set (using osEventFlagsWait). Using this function, it
enters the BLOCKED state.
• may set one or more flags in any other given thread (using osEventFlagsSet).
• may clear its own signals or the signals of other threads (using osEventFlagsClear).

When a thread wakes up and resumes execution, its signal flags are automatically
cleared (unless event flags option osFlagsNoClear is specified).

Working with Events

Fig 7.1 is a simple example that shows how two threads can communicate with each other
using event flags.

Fig 7.1: Simple Event Flag Routine

104
21EE61 – REAL-TIME SYSTEMS LABORATORY
4. PROGRAM FILE :

#include <RTL.h> /* RTX kernel functions & defines*/


/* Task identifications */
OS_TID id1, id2, id3, id4;
/* Forward reference */
__task void task1(void);
__task void task2(void);
__task void task3(void);
__task void task4(void);
__task void task1(void) {
/* Obtain own system task identification number */
id1 = os_tsk_self();
/* Assign system identification number of task2 to id2 */
id2 = os_tsk_create(task2, 1);
/* Assign system identification number of task3 to id3 */
id3 = os_tsk_create(task3, 1);
/* Assign system identification number of task4 to id4 */
id4 = os_tsk_create(task4, 1);
for (;;) { /* do-this */
/* Indicate to task2 completion of do-this */
os_evt_set(0x0004, id2);
/* Wait for completion of do-that (0xffff means no time-out)*/
os_evt_wait_or(0x0004, 0xffff);
/* Wait now for 50 ms */
os_dly_wait(5);
}
}
__task void task2(void) {
for (;;) {
/* Wait for completion of do-this (0xffff means no time-out) */

105
21EE61 – REAL-TIME SYSTEMS LABORATORY
os_evt_wait_or(0x0004, 0xffff); /* do-that */
/* Pause for 20 ms until signaling event to task1 */
os_dly_wait(2);
/* Indicate to task1 completion of do-that */
os_evt_set(0x0004, id1);
}
}
__task void task3(void) {
for (;;) {
/* Wait for completion of do-this (0xffff means no time-out) */
os_evt_wait_or(0x0004, 0xffff); /* do-that */
/* Pause for 20 ms until signaling event to task2 */
os_dly_wait(2);
/* Indicate to task2 completion of do-that */
os_evt_set(0x0004, id2);
}
}
__task void task4(void) {
for (;;) {
/* Wait for completion of do-this (0xffff means no time-out) */
os_evt_wait_or(0x0004, 0xffff); /* do-that */
/* Pause for 20 ms until signaling event to task3 */
os_dly_wait(2);
/* Indicate to task3 completion of do-that */
os_evt_set(0x0004, id3);
}
}
int main(void) {
os_sys_init(task1);
}

106
21EE61 – REAL-TIME SYSTEMS LABORATORY
EXPLANATION:

In the provided RTX program, event flags are used as a means of inter-task communication
and synchronization. Here's how event flags are utilized in the context of this code:
• Task 1 (`task1`):
This task is the entry point of the program. It initializes itself and creates the other tasks
(task2, task3, and task4). Then, it enters a loop where it sets an event to task2, waits for
an event from task2, and waits for a fixed duration of 50 milliseconds.
• Task 2 (`task2`) :
This task continuously waits for an event from task1, pauses for 20 milliseconds, and
then sets an event back to task1.
• Task 3 (`task3`):
Similar to task2, this task waits for an event from task2, pauses for 20 milliseconds, and
then sets an event back to task2.
• Task 4 (`task4`):
This task functions similarly to task3, waiting for an event from task3, pausing for 20
milliseconds, and then setting an event back to task3.

In this program event flags serve as synchronization points between the two tasks. They allow
tasks to communicate and coordinate their activities. At the beginning of the program, four task
identification variables (id1, id2, id3, and id4) are declared to store the system-assigned task
identification numbers at runtime. These variables will be used to identify and communicate
with the tasks during execution.
In the main function, the RTOS system is initialized with task1 as the initial task using the
os_sys_init function.

107
21EE61 – REAL-TIME SYSTEMS LABORATORY
5. OUTPUT :

Fig 7.3: Repeating of Tasks

The output will demonstrate the synchronization and inter-task communication facilitated by
event flags for task 1 , task 2 , task 3 and task 4.

6. INFERENCE:

From this experiment, the implementation of event flag is understood. The definition and logic
built inside each of the built-in functions used in creation of event flag is been deeply

studied.

7. RESULT:
The Event flag register has been successfully implemented by using the RTX Kernel. The
output was also obtained successfully by using Keil µ vision 4.

108
21EE61 – REAL-TIME SYSTEMS LABORATORY
[Link]: 7.B EVENT FLAG REGISTER USING OPEN SOURCE
DATE: REAL-TIME RTX KERNEL ( MICRIUM OS )

1. AIM :

To understand the use of inter – task communication in real – time kernel by


implementing event flag register in Micrium operating system.

2. TOOLS REQUIRED :
▪ Text Editor (Notepad)
▪ DOS Box
▪ MICRIUM OS
▪ bc45 Borland C/C++ Compiler

3. BUILT-IN FUNCTIONS :
μC/OS-II event flags consist of two elements: a series of bits (8, 16 or 32) used to hold
the current state of the events in the group, and a list of tasks waiting for a combination of these
bits to either be set (1) or cleared (0). μC/OS-II provides six services to access semaphores,
OSFlagAccept (), OSFlagCreate (), OSFlagDel (), OSFlagPend (), OSFlagPost () and
OSFlagQuery ().
To enable μC/OS-II event flags services, you must set the configuration constants in
OS_CFG.H. Note that NONE of the event flag services are enabled when OS_FLAG_EN is
set to 0. To enable the feature simply set the configuration constant to 1.

• OSFlagCreate (OS_FLAG_GRP *p_grp, CPU_CHAR *p_name, OS_FLAGS


flags, RTOS_ERR *p_err) - This function is called to create an event flag group.
p_grp Pointer to the event flag group to create. Your application is responsible for
allocating storage for the flag group.

❖ p_name - The name of the event flag group.

❖ Flags -Contains the initial value to store in the event flag group typically 0.
• OSFlagDel (OS_FLAG_GRP *p_grp, OS_OPT opt, RTOS_ERR *p_err) -This
function deletes an event flag group and readies all tasks pending on the event flag
group.

109
21EE61 – REAL-TIME SYSTEMS LABORATORY
❖ p_grp - Pointer to the event flag group.
❖ Opt - Determines delete options as follows, OS_OPT_DEL_NO_PEND
Deletes the event flag group ONLY if no task is pending,
OS_OPT_DEL_ALWAYS Deletes the event flag group even if tasks are
waiting. In this case, all the pending tasks will be made ready.
❖ p_err- Pointer to the variable that will receive one of the following error
from the functions.
❖ Returns == 0 If no tasks were waiting on the event flag group, or upon
error.
❖ Returns > 0 If one or more tasks waiting on the event flag group are now
ready and informed.
• OSFlagPost (OS_FLAG_GRP *p_grp, OS_FLAGS flags, OS_OPT opt, RTOS_ERR
*p_err) - This function is called to set or clear some bits in an event flag group. The
bits to set or clear are specified by a bit mask.
❖ p_grp - Pointer to the event flag group.
❖ Flags - If it is OS_OPT_POST_FLAG_SET, each bit set in flags will be set
to the corresponding bit in the event flag group.
❖ If it is OS_OPT_POST_FLAG_CLR, each bit set in flags will clear the
corresponding bit in the event flag group
❖ Opt - Indicates whether the flags will be set or cleared,
OS_OPT_POST_FLAG_SET Set, OS_OPT_POST_FLAG_CLR Cleared.
❖ p_err - Pointer to the variable that will receive one of the following error from
this function RTOS_ERR_NONE.
❖ The new value of the event flags bits that are still set are returned.
• OSFlagPend (OS_FLAG_GRP *p_grp, OS_FLAGS flags, OS_TICK timeout,
OS_OPT opt, CPU_TS *p_ts, RTOS_ERR *p_err) - This function is called to wait for
a combination of bits to be set in an event flag group. Your application can wait for
either ANY bit to be set or ALL bits to be set.
❖ p_grp - Pointer to the event flag group.
❖ Flags - Bit pattern that indicates which bits to wait for. The bits you want are
specified by setting the corresponding bits in flags.

110
21EE61 – REAL-TIME SYSTEMS LABORATORY
❖ Timeout - Optional timeout in clock ticks that your task will wait for the
desired bit combination. If you specify 0, the task will wait forever at the
specified event flag group, or until a message arrives.
❖ Opt - Specifies whether you want all bits to be set or any of the bits to be set.
❖ p_ts - Pointer to a variable that receives the timestamp of when the event
flag group was posted, aborted, or deleted. If you pass a NULL pointer then
you will not get the timestamp. In other words, passing a NULL pointer is
valid and indicates that you don't need the timestamp.
❖ p_err - Pointer to the variable that will receive an error.
❖ Returns the flags in the event flag group that made the task ready or, 0 if a
timeout or an error occurred.
• OSFlagPend () - This function looks for desired events from an event flag group
without waiting. This function is quite similar to OSFlagPend () except that the caller
will not be suspended i.e. block the events not be present. The only two things that are
different are
❖ OSFlagAccept () can be called from an ISR unlike some of the other calls.
❖ If the conditions are NOT met, the call does not block and simply returns an
error code that the caller should check.
• OSFlagQuery () - allows to get the current value of the event flag group.

4. PROGRAM FILES:

To understand the concept of Event flag register an application of calculating the


capacitance and energy stored in the capacitor is considered and this application is splitted into
five tasks, task1 job is to get the value of voltage, current and time once it’s done corresponding
flag bit are made to set, purpose of task 2 is to calculate the capacitance and once it is calculated
then corresponding flag bits are made to set and task3 get started its job is to calculate the energy
and sets the corresponding event flag bits and at last task 4 job is to display the values of
capacitance and energy. Whereas task 0 job is to create the vent flag register.

111
21EE61 – REAL-TIME SYSTEMS LABORATORY
#include "includes.h"
#define TASK_STK_SIZE 1024
OS_STK TaskStk[6][TASK_STK_SIZE];
void Task0(void *pdata);
void Task1(void *pdata);
void Task2(void *pdata);
void Task3(void *pdata);
void Task4(void *pdata);
void Task5(void *pdata);
OS_FLAG_GRP *Flagsts;
int v = 0, t = 1, i = 1; // Initialize variables to prevent division by zero
float c = 0, e = 0; // Initialize variables
void main(void) {
INT8U err;
PC_VectSet(uCOS, OSCtxSw);
OSInit();
printf("\n\t\t\t Tasks 0 to 5 are created.");
OSTaskCreate(Task0, (void*)0, &TaskStk[0][TASK_STK_SIZE - 1], 10);
OSTaskCreate(Task1, (void*)1, &TaskStk[1][TASK_STK_SIZE - 1], 11);
OSTaskCreate(Task2, (void*)2, &TaskStk[2][TASK_STK_SIZE - 1], 12);
OSTaskCreate(Task3, (void*)3, &TaskStk[3][TASK_STK_SIZE - 1], 13);
OSTaskCreate(Task4, (void*)4, &TaskStk[4][TASK_STK_SIZE - 1], 14);
OSTaskCreate(Task5, (void*)5, &TaskStk[5][TASK_STK_SIZE - 1], 15);
OSStart();
}
void Task0 (void *pdata) {
INT8U err;
pdata = pdata;

112
21EE61 – REAL-TIME SYSTEMS LABORATORY
for (;;) {
printf("Task 0 is running \"Creating Event flag\"");
printf("\n\t\t\t================================");
Flagsts = OSFlagCreate(0x00, &err);
if (err == OS_NO_ERR)
printf("\n\t\t\t Event flag group was created");
else
printf("\n\t\t\t Event flag group was not created");
OSTaskSuspend(OS_PRIO_SELF);
}
}
void Task1 (void *pdata) {
INT16U val;
INT8U err;
pdata = pdata;
for (;;) {
printf("\n\t\t\t========================================");
printf("Task 1 is running: \"Getting Voltage, Current and Time\'");
printf("\n Enter the value of \"Voltage\": ");
scanf("%d", &v);
printf("\n Enter the value of\"Current\": ");
scanf("%d", &i);
printf("\n Enter the value of \"Time\" in sec: ");
scanf("%d", &t);
OSFlagPost(Flagsts, 0x3D, OS_FLAG_SET, &err);
OSTaskSuspend(OS_PRIO_SELF);
}
}

113
21EE61 – REAL-TIME SYSTEMS LABORATORY
void Task2 (void *pdata) {
INT8U err;
OS_FLAGS value;
pdata = pdata;
for (;;) {
printf("\n\t\t\t========================================");
printf("Task 2 is running: \"Calculating Capacitance Value\"");
value = (OSFlagAccept(Flagsts, 0x3E || 0X3D, OS_FLAG_WAIT_SET_ALL, &err));
switch (err) {
case OS_NO_ERR:
if (v != 0)
c = (i * t) / v;
break;
default:
printf("The Task 1 is not completed");
break;
}
OSTaskSuspend(OS_PRIO_SELF);
}
}
void Task3 (void *pdata) {
INT8U err;
OS_FLAGS value;
pdata = pdata;
for (;;) {
printf("\n\t\t\t=========================================");
printf("Task 3 is running: \"Calculating Energy of Capacitor\"");
value = (OSFlagAccept(Flagsts, 0x7E || 0X7D, OS_FLAG_WAIT_SET_ALL, &err));

114
21EE61 – REAL-TIME SYSTEMS LABORATORY
switch (err) {
case OS_NO_ERR:
e = (0.5 * c * v * v);
if (OSFlagPend(Flagsts, 0X7D, OS_FLAG_WAIT_SET_ANY, 10, &err))
OSFlagPost(Flagsts, 0x0FD, OS_FLAG_SET, &err);
if (OSFlagPend(Flagsts, 0X7E, OS_FLAG_WAIT_SET_ANY, 10, &err))
OSFlagPost(Flagsts, 0x0FE, OS_FLAG_SET, &err);
break;
default:
printf("\n\t\t\t The Task 2 is not completed");
break;
}
OSTaskSuspend(OS_PRIO_SELF);
}
}
void Task4 (void *pdata) {
INT8U err;
OS_FLAG_GRP *pgrp;
OS_FLAGS value;
pdata = pdata;
for (;;) {
printf("\n\t\t\t========================================");
printf("Task 4 running: \"Displaying Capacitance and Energy\"");
value = (OSFlagAccept(Flagsts, 0x0FE || 0X0FD, OS_FLAG_WAIT_SET_ALL,
&err));
switch (err) {
case OS_NO_ERR:
printf("\n Capacitance: %.2f", c);
printf("\n Energy stored in capacitor: %.2f", e);

115
21EE61 – REAL-TIME SYSTEMS LABORATORY
break;
default:
printf("\n The Task 3 is not completed");
break;
}
pgrp = OSFlagDel(Flagsts, OS_DEL_ALWAYS, &err);
if (pgrp == (OS_FLAG_GRP *)0) {
printf("\n\n\t\t\t The event flag was deleted.");
}
OSTaskSuspend(OS_PRIO_SELF);
}
}
void Task5 (void *pdata) {
INT8U err;
pdata = pdata;
for (;;) {
printf("\n\t\t\t========================================");
printf("Task 5 running: \"Task 5 functionality\"");
// Implement Task 5 functionality here
printf("\nTask 5: Performing periodic task or monitoring...");
OSTimeDlyHMSM(0, 0, 1, 0); // Delay for 1 second
}
}

116
21EE61 – REAL-TIME SYSTEMS LABORATORY
5. OUTPUT:
The corresponding output for the implementation of Event flag register using Micrium
OS is shown below. Fig 7.4 shows the user input part of the program and Fig 7.4 shows the
output of the program which calculates the capacitance and energy value using event flag.

Fig 7.4: User input in the console

117
21EE61 – REAL-TIME SYSTEMS LABORATORY
Fig 7.5: Final output

6. INFERENCE:

From this experiment, the implementation of event flag is understood. The definition
and logic built inside each of the built-in functions used in creation of event flag is been deeply
studied.

7. RESULT:

The Event flag register has been successfully implemented by using the Micrium
operating systems. The output was also obtained successfully by using DOS-Box.

118
21EE61 – REAL-TIME SYSTEMS LABORATORY

You might also like