Suggestions for "Mastering the FreeRTOS™ Real Time Kernel 1.0"

At least some previous versions of the PDF had both thumbnail and textual table of content, while this version only has the thumbnails. I am not talking about the TOC at the beginning of the document, but meta data that PDF viewers can put in a sidebar for navigation. Thumbnail navigation is pretty useless in my opinion, but the textual TOC is extremely useful, especially for large documents like this.

Can the textual TOC metadata be restored?


good point with the TOC. I found some other things and I’m thinking about posting them here if you can change the topic title to be more generic if that’s okay for you. This way we would have one single topic where all suggestions for the book can be collected :slight_smile:


1 Like

Just saw that the topic title has changed, so I put my observations so far just below…

First things first, the book is really good, many thanks for that - since I’m still a FreeRTOS beginner it’s a really valuable and helpful work.

I want to suggest that the diagrams showing which task is running at which time and priority are reworked:

  • Tasks of higher priority are always on top in descending order:
    This would make it easier to see the priority order. For example, the example #5.2 switches the priorities of the sender and receiver tasks, but the receiver task is still the uppermost one. So, for each example/diagram you’ve to keep track of the priorities by the text describing the example or the source code.
  • The time axis should use different identifiers for ticks and time spots within ticks:
    Currently the form ‘tn’ is used for both marking ticks and time spots within ticks, which can get confusing. For example, figure 4.17 marks the ticks only, and it can be seen that task switches are executed between two ticks and the tick distances are almost identical. In contrast, figure 4.18 uses ‘tn’ to denote spots in time between ticks => the descriptional text also uses the wording ‘time tn’ instead of ‘tick tn’. The suggestion is to use T/t for tick/time in the diagrams. The same for descriptional texts: use ‘tick n’ if the spot in time is at a tick boundary and ‘time n’ if it’s between two ticks, e.g. an event or interrupt.

Note that those suggestions are just from my beginners view :slight_smile:

I think I also found some small errors:
For figure #4.11, output of example #4.6, I wonder if the two first and the two last lines really reflect the (intended) behaviour of the example. There’s no main() function shown where the texts passed in by pvParameters can be seen and the mentioned lines are missing the word ‘is’. However, the text being printed between the periodic task execution does have the word ‘is’, so where comes the difference from?

Chapter #4.12.4 Prioritized Preemptive Scheduling without Time Slicing, second paragraph mentions a ‘table below’, but there’s no table. I assume the text is referring to the table right above chapter #4.12.3 Prioritized Preemptive Scheduling with Time Slicing, right?

I love this book, especially because it also mentions potential pitfalls and side effects. Really a great work.


@ericb @RA1981,

Thank you for the feedback and suggestions. We will look into them.
Also, I would like to note that the book contents are hosted in Github, and we welcome and appreciate your contributions to the book.

Thank you

Hello Keishi,

currently I’m not using GitHub, so I don’t know how to use it exactly and what’s the effort to get it up and running under Windows :frowning: I think I’ll use GH in the future to better help to improve the book, but currently I’m not able to do it this way.

For the book, I think I found a small cosmetic error: listing #10.12 seems to miss a closing curly bracket in void xUART_ReceiveISR() for the if-block which checks if there’s a task to notify.

For chapters #9.3 9.3 Event Management Using Event Groups and Chapter #9.4 Task Synchronization Using an Event Group I’m a bit confused: #9.3 uses one task writing two event bits, one interrupt writing a third event bit and one task reading the event bits. From my understanding, it’s about synchronising the reading task to either the writing one or the interrupt.
The first sentence in #9.4 is
Sometimes the design of an application requires two or more tasks to synchronize with each other. I wonder if this shouldn’t be “three or more tasks…”. The example texts are referring to more than two tasks, but listing #9.11 uses two tasks. That’s a bit confusing.
If I understand it correctly, I can synchronize two tasks by setting a dedicated flag in the event group for each task and synchronisation is done by waiting for both flags in each task. So, I would only need xEventGroupSync() for more than two tasks, right?


Thanks a lot for the suggestions and feedback. We have updated some of the changes pointed out (currently on Github) and looking into the others ( the diagrams ).
As for the confusion regarding Event Groups, please let me know if the description below makes the understanding clear.

The reading task in this example waits for an event (setting a bit from a task or an ISR) to happen and then processes the event. In the first example (xWaitForAllBits = pdFALSE), the reading task starts processing the event as soon as one event happens. In the second example (xWaitForAllBits = pdTRUE), it starts processing the events only after all of them have happened.

What is meant by synchronization is that no task will move past the synchronization point until all the tasks have reached their synchronization point. It is not possible to achieve such synchronization by using xEventGroupWaitBits even for two tasks. Consider the following example:

Task T1
xEventGroupWaitBits(T1_BIT | T2_BIT); /* Synchronization point. */
/* We want to ensure that this line (which is after the synchronization point)
 * is reached after both the tasks have reached the synchronization point
 * (i.e. xEventGroupWaitBits). */

Task T2
xEventGroupWaitBits(T1_BIT | T2_BIT); /* Synchronization point. */
/* We want to ensure that this line (which is after the synchronization point)
 * is reached after both the tasks have reached the synchronization point
 * (i.e. xEventGroupWaitBits). */
The following valid sequence of execution will not achieve synchronization:
T1 - Sets the T1 bit.
T1 - Blocks while waiting for both the bits to become set.
T2 - Sets the T2 bit.
T1 - Can now proceed even before T2 gets a chance to call xEventGroupWaitBits.

xEventGroupSync enables us to achieve such synchronization point.


@karahulx Sorry for the late reply.

Yes, I think now I understood the real difference. With xEventGroupSync all tasks including the calling one are waiting, which is not the case for xEventGroupSetBits/xEventGroupWaitBits. Using those functions is not atomic and therefore they can’t be used even for synchronization of two tasks.

Thank you.