0% found this document useful (0 votes)
37 views90 pages

Real-Time Operating Systems: Queue Management

Uploaded by

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

Real-Time Operating Systems: Queue Management

Uploaded by

Rana Basit
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 90

Real-time Operating Systems

Queue Management

Dr Usman Zabit

Please report any errors to


[email protected]
ALL MATERIAL (EXCEPT WHERE STATED OTHERWISE) IS FROM
MASTERING THE FREERTOS™
REAL TIME KERNEL
A HANDS-ON TUTORIAL GUIDE

By Richard Barry

Copyright © 2016
2
by Real-time Engineers Ltd
CHAPTER 4
QUEUE MANAGEMENT

3
4.1 CHAPTER INTRODUCTION AND
SCOPE
 ‘Queues’ provide a task-to-task, task-to-interrupt, and
interrupt-to-task communication mechanism.

 Scope
 This chapter aims to give readers a good understanding of:

  How to create a queue.

  How a queue manages the data it contains.

  How to send data to a queue.

  How to receive data from a queue.

  What it means to block on a queue.

4
4.1 CHAPTER INTRODUCTION AND
SCOPE
 …
  How to block on multiple queues.

  How to overwrite data in a queue.

  How to clear a queue.

  The effect of task priorities when writing to and reading


from a queue.

 Only task-to-task communication is covered in this chapter.


 Task-to-interrupt and interrupt-to-task communication is
covered in Chapter 6
5
4.2 CHARACTERISTICS OF A QUEUE
 Data Storage
 A queue can hold a finite number of fixed size data items.

 The maximum number of items a queue can hold is called its ‘length’.

 Both the length and the size of each data item are set
when the queue is created.
 Queues are normally used as First In First Out (FIFO) buffers, where
data is written to the end (tail) of the queue and removed from the front
(head) of the queue.
 Figure 31 demonstrates data being written to and read from a queue
that is being used as a FIFO.
 It is also possible to write to the front of a queue, and to overwrite data
that is already at the front of a queue.
6
AN EXAMPLE SEQUENCE OF WRITES
TO, AND READS FROM A QUEUE: 1

7
AN EXAMPLE SEQUENCE OF WRITES
TO, AND READS FROM A QUEUE: 2

8
AN EXAMPLE SEQUENCE OF WRITES
TO, AND READS FROM A QUEUE: 3

9
AN EXAMPLE SEQUENCE OF WRITES
TO, AND READS FROM A QUEUE: 4

10
AN EXAMPLE SEQUENCE OF WRITES
TO, AND READS FROM A QUEUE: 5

11
FIGURE 7 FROM “CH 2: HEAP MEMORY MANAGEMENT”

12
HOW DATA IS MOVED TO A QUEUE
 There are two ways in which queue behavior could have been
implemented:

1. Queue by copy
 Queuing by copy means the data sent to the queue is copied
byte for byte into the queue.

2. Queue by reference
 Queuing by reference means the queue only holds pointers to
the data sent to the queue, not the data itself.

13
QUEUE BY COPY METHOD
 FreeRTOS uses the queue by copy method.
 Queuing by copy is considered to be simultaneously more
powerful and simpler to use than queueing by reference because:
  Stack variable can be sent directly to a queue, even though the
variable will not exist after the function in which it is declared
has exited.
  Data can be sent to a queue without first allocating a buffer to
hold the data, and then copying the data into the allocated buffer.
  The sending task can immediately re-use the variable or buffer
that was sent to the queue.
  The sending task and the receiving task are completely de-
coupled—the application designer does not need to concern
themselves with which task ‘owns’ the data, or
14
which task is responsible for releasing the data.
QUEUE BY COPY METHOD
 …
  Queuing by copy does not prevent the queue from also being used to
queue by reference.
 For example, when the size of the data being queued makes it
impractical to copy the data into the queue, then a pointer to the data
can be copied into the queue instead.
  The RTOS takes complete responsibility for allocating the memory
used to store data.
  In a memory protected system, the RAM that a task can access will
be restricted. In that case queueing by reference could only be used if
the sending and receiving task
could both access the RAM in which the data was stored.
 Queuing by copy does not impose that restriction; the kernel always
runs with full privileges, allowing a queue to
be used to pass data across memory protection boundaries. 15
ACCESS BY MULTIPLE TASKS

 Queues are objects in their own right that can be accessed by


any task or ISR that knows of their existence.
 Any number of tasks can write to the same queue, and any
number of tasks can read from the same queue.
 In practice it is very common for a queue to have multiple
writers, but much less common for a queue to have multiple
readers.

16
BLOCKING ON QUEUE READS
 When a task attempts to read from a queue, it can optionally
specify a ‘block’ time.
 This is the time the task will be kept in the Blocked state to
wait for data to be available from the queue,
should the queue already be empty.
 A task that is in the Blocked state, waiting for data to
become available from a queue, is automatically moved to
the Ready state when another task or interrupt places data
into the queue.
 The task will also be moved automatically from the
Blocked state to the Ready state if the specified block time
expires before data becomes available.
17
BLOCKING ON QUEUE READS
 Queues can have multiple readers, so it is possible for a
single queue to have more than one task blocked on it
waiting for data.
 When this is the case, only one task will be unblocked when
data becomes available.
 The task that is unblocked will always be the highest priority
task that is waiting for data.
 If the blocked tasks have equal priority, then the task that
has been waiting for data the longest will be unblocked.

18
BLOCKING ON QUEUE WRITES
 Just as when reading from a queue, a task can optionally
specify a block time when writing to
a queue.
 In this case, the block time is the maximum time the task
should be held in the Blocked state to wait for space to
become available on the queue, should the queue already be
full.

19
BLOCKING ON QUEUE WRITES
 Queues can have multiple writers, so it is possible for a full
queue to have more than one task blocked on it waiting to
complete a send operation.
 When this is the case, only one task will be unblocked when
space on the queue becomes available.
 The task that is unblocked will always be the highest priority
task that is waiting for space.
 If the blocked tasks have equal priority, then the task that has
been waiting for space the longest will be unblocked.

20
BLOCKING ON MULTIPLE QUEUE
 Queues can be grouped into sets, allowing a task to enter the
Blocked state to wait for data to become available on any of
the queues in the set.
 Queue sets are demonstrated in section 4.6, Receiving From
Multiple Queues.

21
4.3 USING A QUEUE
 The xQueueCreate() API Function
 A queue must be explicitly created before it can be used.

 Queues are referenced by handles, which are variables of type


QueueHandle_t.
 The xQueueCreate() API function creates a queue and returns
a QueueHandle_t that references the queue it created.

22
4.3 USING A QUEUE
 The xQueueCreate() API Function

 FreeRTOS allocates RAM from the FreeRTOS heap when a


queue is created.
 The RAM is used to hold both the queue data structures and
the items that are contained in the queue.
 xQueueCreate() will return NULL if there is insufficient heap
RAM available for the queue to be created.
 Chapter 2 provides more information on the FreeRTOS heap.

23
TABLE 18: XQUEUECREATE() API FUNCTION PARAMETERS AND RETURN VALUE

xQueueCreate() parameters and


return value

24
DIFFERENT APIS FOR QUEUE MANAGEMENT

 After a queue has been created the xQueueReset() API function


can be used to return the queue to its original empty state.
 xQueueSendToBack() is used to send data to the back (tail) of
a queue.
 xQueueSendToFront() is used to send data to the front (head)
of a queue.
 xQueueSend() is equivalent to, and exactly the same as,
xQueueSendToBack().
 Note: Never call xQueueSendToFront() or
xQueueSendToBack() from an interrupt service routine (ISR).
 The interrupt-safe version xQueueSendToFrontFromISR() and
xQueueSendToBackFromISR() should be used in their place.
25
 These are described in Chapter 6.
XQUEUESENDTO… APIS

26
XQUEUESENDTO… APIS

27
XQUEUESENDTO… APIS

28
XQUEUESENDTO… APIS

29
XQUEUESENDTO… APIS

30
THE XQUEUERECEIVE() API FUNCTION
 xQueueReceive() is used to receive (read) an item from a
queue.
 The item that is received is removed from the queue.

 Note: Never call it from an ISR.


 The interrupt-safe version xQueueReceivefromISR() is
described in Chapter 6.

31
THE XQUEUERECEIVE() API FUNCTION

32
THE XQUEUERECEIVE() API FUNCTION

33
THE XQUEUERECEIVE() API FUNCTION

34
THE XQUEUERECEIVE() API FUNCTION

35
THE UXQUEUEMESSAGESWAITING() API FUNCTION

 uxQueueMessagesWaiting() is used to query the number of


items that are currently in a queue.
 Note: Never call uxQueueMessagesWaiting() from an ISR.

 The interrupt-safe version


uxQueueMessagesWaitingFromISR() should be used in its
place.

36
THE UXQUEUEMESSAGESWAITING() API FUNCTION

37
SIMPLE USE OF QUEUE B/W 2 TASKS ON ESP32

void vSenderTask(void *pvParameters)


{
int aValue = 0;
for (;;) See complete code in
the “Notes” section of
{ this slide
for(int i = 0;i<10;i++ ){
aValue += 10000; // some dummy computations
}

/* Post an item on a queue. https://www.freertos.org/a00117.html */


xQueueSend (integerQueue, &aValue, portMAX_DELAY);
} 38

}
SIMPLE USE OF QUEUE B/W 2 TASKS

void vConsumerTask(void * pvParameters) {

int valueFromQueue = 0;

for ( ; ; ) See complete code in


{ the “Notes” section of
this slide

/* Read an item from the queue */


if (xQueueReceive (integerQueue, &valueFromQueue, portMAX_DELAY) ==
pdPASS) {
Serial.println(valueFromQueue);
}
vTaskDelay(pdMS_TO_TICKS(1000)); /*Block the Task for X ms */
} 39
}
SIMPLE USE OF QUEUE B/W 2 TASKS

void vPeriodicTask (void *pvParameters)


{ See complete code in
for (;;) the “Notes” section of
this slide
{
Serial.println("Running the Periodic Task");
vTaskDelay(pdMS_TO_TICKS(5000)); /* Block the Task for X ms */
}
}

40
SIMPLE USE OF QUEUE B/W 2 TASKS
/* Declaring a global variable of type QueueHandle_t */
QueueHandle_t integerQueue;

void setup() {
Serial.begin(112500); // Initialize the serial comm
delay(1000);
See complete code in
the “Notes” section of
integerQueue = xQueueCreate (3, // Queue length
this slide
sizeof(int) // Queue item size
);
if (integerQueue != NULL) {

// Create task that consumes the queue if it was created.


xTaskCreatePinnedToCore(vConsumerTask, // Task function
"Serial", // A name just for humans
10000, // This stack size can be checked & adjusted by reading the Stack Highwater
41
NULL,
2, // Priority
See next slide for remainder of code
SIMPLE USE OF QUEUE B/W 2 TASKS
// Create task that publishes data in the queue if it was created.
xTaskCreatePinnedToCore(vSenderTask, // Task function
"SenderTask", // Task name
10000, // Stack size
NULL,
1, // Priority
NULL, See complete code in
0); // pinned to core 0 the “Notes” section of
this slide
}
xTaskCreatePinnedToCore(vPeriodicTask, // Task function
"vPeriodicTask", // Task name
10000, // Stack size
NULL,
1, // Priority
NULL ,
0); // pinned to core 0
42
}
void loop() {} // Nothing here. All is done inside the Tasks
SIMPLE USE OF QUEUE B/W 2 TASKS

See complete code in


the “Notes” section of
this slide

43
EXAMPLE 10. BLOCKING WHEN RECEIVING FROM A QUEUE

 This example demonstrates a queue being created, data


being sent to the queue from multiple
tasks, and data being received from the queue.
 The queue is created to hold data items of
type int32_t.
 The tasks that send to the queue do not specify a block time,
whereas the task that receives from the queue does.

44
EXAMPLE 10. BLOCKING WHEN RECEIVING FROM A QUEUE

 The priority of the tasks that send to the queue are lower
than the priority of the task that receives from the queue.
 This means the queue should never contain more than one
item because,
 ???

 as soon as data is sent to the queue the receiving task will


unblock, pre-empt the sending task, and remove the data—
leaving the queue empty once again.

45
EXAMPLE 10. BLOCKING WHEN RECEIVING FROM A QUEUE

 Listing 45 shows the implementation of the task that writes


to the queue.
 Two instances of this task are created, one that writes
continuously the value 100 to the queue, and another that
writes continuously the value 200 to the same queue.
 The task parameter is used to pass these values into each
task instance.

46
EXAMPLE 10. BLOCKING WHEN RECEIVING FROM A QUEUE

47
See next slide for remainder of code
EXAMPLE 10. BLOCKING WHEN RECEIVING FROM A QUEUE

48
EXAMPLE 10. BLOCKING WHEN RECEIVING FROM A QUEUE

 Listing 46 shows the implementation of the task that


receives data from the queue.
 The receiving task specifies a block time of 100
milliseconds, so will enter the Blocked state to wait for
data to become available.
 It will leave the Blocked state when either data is
available on the queue, or 100 milliseconds passes
without data becoming available.
 In this example, the 100 milliseconds timeout should
never expire,
 ???

 as there are two tasks continuously writing to the queue.


49
EXAMPLE 10. BLOCKING WHEN RECEIVING FROM A QUEUE

50
See next slide for remainder of code
EX 10. BLOCKING WHEN RECEIVING FROM A QUEUE

51
EXAMPLE 10. BLOCKING WHEN RECEIVING FROM A QUEUE

 Listing 47 contains the definition of the main() function.


 This simply creates the queue and the three tasks before starting
the scheduler.
 The queue is created to hold a maximum of five int32_t values,
even though the priorities of the tasks are set such that the
queue will never contain more than one item at a time.

52
EXAMPLE 10. BLOCKING WHEN RECEIVING FROM A QUEUE

53
See next slide for remainder of code
EXAMPLE 10. BLOCKING WHEN RECEIVING FROM A QUEUE

54
EXAMPLE 10. BLOCKING WHEN RECEIVING FROM A QUEUE

 Both tasks that send to the queue have an identical


priority.
 This causes the two sending tasks to send data to the
queue in turn.
 The output produced by Example 10 is shown in Figure
32.

55
EXAMPLE 10. BLOCKING WHEN RECEIVING FROM A QUEUE

56
EXAMPLE 10. BLOCKING WHEN RECEIVING FROM A QUEUE

57
4.4 RECEIVING DATA FROM MULTIPLE SOURCES

 It is common in FreeRTOS designs for a task to receive data


from more than one source.
 The receiving task needs to know where the data came from
to determine how the data should be
processed.
 An easy design solution is to use a single queue to transfer
structures with both the value of the data and the source of
the data contained in the structure’s fields.
 This scheme is demonstrated in Figure 34.

58
4.4 RECEIVING DATA FROM MULTIPLE SOURCES

59
4.4 RECEIVING DATA FROM MULTIPLE SOURCES

 Referring to Figure 34:

  A queue is created that holds structures of type Data_t.


 The structure members allow both a data value and an
enumerated type indicating what the data means to be sent to
the queue in one message.
  A central Controller task is used to perform the primary
system function.
 This has to react to inputs and changes to the system state
communicated to it on the queue.

60
4.4 RECEIVING DATA FROM MULTIPLE SOURCES

 Referring to Figure 34:

  A CAN bus task is used to encapsulate the CAN bus


interfacing functionality.
 When the CAN bus task has received and decoded a message,
it sends the already decoded message to the Controller task in a
Data_t structure.
 The eDataID member of the transferred structure is used to let
the Controller task know what the data is—in the depicted case
it is a motor speed value.
 The lDataValue member of the transferred structure is used to
let the Controller task know the actual motor speed value.
61
4.4 RECEIVING DATA FROM MULTIPLE SOURCES
 Referring to Figure 34:
  A Human Machine Interface (HMI) task is used to
encapsulate all the HMI functionality.
 The machine operator can probably input commands and
query values in a number of ways that have to be detected
and interpreted within the HMI task.
 When a new command is input, the HMI task sends the
command to the Controller task in a Data_t structure.
 The eDataID member of the transferred structure is used to let
the Controller task know what the data is—in the depicted
case it is a new set point value.
 The lDataValue member of the transferred structure is used to
let the Controller task know the actual set point value. 62
EX 11. BLOCKING WHEN SENDING TO A QUEUE, AND SENDING
STRUCTURES ON A QUEUE

 Example 11 is similar to Example 10, but the task priorities


are reversed, so the receiving task has a lower priority than
the sending tasks.
 Also, the queue is used to pass structures, rather
than integers.
 Listing 48 shows the definition of the structure used by
Example 11.

63
EX 11. BLOCKING WHEN SENDING TO A QUEUE, AND SENDING
STRUCTURES ON A QUEUE

64
EX 11. BLOCKING WHEN SENDING TO A QUEUE, AND SENDING
STRUCTURES ON A QUEUE

65
See next slide for remainder of code
EX 11. BLOCKING WHEN SENDING TO A QUEUE, AND SENDING
STRUCTURES ON A QUEUE

66
EX 11. BLOCKING WHEN SENDING TO A QUEUE, AND SENDING
STRUCTURES ON A QUEUE

See next slide for remainder of code 67


EX 11. BLOCKING WHEN SENDING TO A QUEUE, AND SENDING
STRUCTURES ON A QUEUE

See next slide for remainder of code 68


EX 11. BLOCKING WHEN SENDING TO A QUEUE, AND SENDING
STRUCTURES ON A QUEUE

69
EX 11. BLOCKING WHEN SENDING TO A QUEUE, AND SENDING
STRUCTURES ON A QUEUE

See next slide for remainder of code

70
EX 11. BLOCKING WHEN SENDING TO A QUEUE, AND SENDING
STRUCTURES ON A QUEUE

71
EX 11. BLOCKING WHEN SENDING TO A QUEUE, AND SENDING
STRUCTURES ON A QUEUE

 Output ???

72
EX 11. WHEN RUN ON ESP32

 Output ???

See complete code in


the “Notes” section of
this slide

73
EX 11. WHEN RUN ON ESP32
Why?
 Output ???

74
EX 11. BLOCKING WHEN SENDING TO A QUEUE, AND SENDING
STRUCTURES ON A QUEUE

75
EX 11. BLOCKING WHEN SENDING TO A QUEUE, AND SENDING
STRUCTURES ON A QUEUE

76
EX 11. BLOCKING WHEN SENDING TO A QUEUE, AND SENDING
STRUCTURES ON A QUEUE

77
STATIC KEYWORD IN C LANGUAGE
 (1) A static variable inside a function keeps its value between
invocations of this function.
 (2) A static function is "seen" only in the file it's declared in.

 (1) is the more foreign topic if you're a newbie, so here's an


example:

78

https://stackoverflow.com/questions/572547/what-does-static-mean-in-c
STATIC KEYWORD BEFORE A VARIABLE
 Example Code:

79

https://stackoverflow.com/questions/572547/what-does-static-mean-in-c
STATIC KEYWORD BEFORE A VARIABLE
 Output of example code:

80

https://stackoverflow.com/questions/572547/what-does-static-mean-in-c
STATIC KEYWORD BEFORE A VARIABLE

 Usage:
 This is useful for cases where a function needs to keep some
state between invocations, and you don't want to use global
variables.
 Beware, however, this feature should be used very sparingly -
it makes your code not thread-safe and harder to understand.

81

https://stackoverflow.com/questions/572547/what-does-static-mean-in-c
STATIC KEYWORD BEFORE A FUNCTION

 (2) is used widely as an "access control" feature.


 If you have a .c file implementing some functionality, it
usually exposes only a few "public" functions to users.
 The rest of its functions should be made static, so that the user
won't be able to access them.
 This is encapsulation, a good practice.

82

https://stackoverflow.com/questions/572547/what-does-static-mean-in-c
TYPEDEF ENUM EXPLANATION IN C
Question:

83

https://stackoverflow.com/questions/34132439/typedef-enum-explanation-in-c
TYPEDEF ENUM EXPLANATION IN C
Question (contd.):

84

https://stackoverflow.com/questions/34132439/typedef-enum-explanation-in-c
TYPEDEF ENUM EXPLANATION IN C
Answer:

85

https://stackoverflow.com/questions/34132439/typedef-enum-explanation-in-c
TYPEDEF ENUM EXPLANATION IN C
Answer (contd.):

86

https://stackoverflow.com/questions/34132439/typedef-enum-explanation-in-c
TYPEDEF ENUM EXPLANATION IN C
Answer (contd.):

87

https://stackoverflow.com/questions/34132439/typedef-enum-explanation-in-c
TYPEDEF ENUM EXPLANATION IN C
Answer 2:

88

https://stackoverflow.com/questions/34132439/typedef-enum-explanation-in-c
TYPEDEF ENUM EXPLANATION IN C
Answer 2 (contd.):

89

https://stackoverflow.com/questions/34132439/typedef-enum-explanation-in-c
TYPEDEF ENUM EXPLANATION IN C
Answer 2 (contd.):

90

https://stackoverflow.com/questions/34132439/typedef-enum-explanation-in-c

You might also like