5. RTOS

Multitasking ohne RTOS

Motivation

5.1. FreeRTOS

Multitasking mit RTOS

  • FreeRTOS als freies Projekt von Richard Barry seit 15 Jahren

    https://www.freertos.org

  • Kleines Echtzeit-Betriebssystem, das viele verschiedene Entwicklungsumgebungen und CPU Architekturen unterstützt. Siehe dazu im FreeRTOS Quelltext das Verzeichnis:

    FreeRTOSv10.1.1/FreeRTOS/Source/portable/

  • Von Amazon 2017 aufgekauft, deshalb nun “Amazon FreeRTOS” im Bereich der “Amazon Web Services” (AWS).

    https://aws.amazon.com/blogs/opensource/announcing-freertos-kernel-v10/

  • MIT Lizenz

Quelltext von FreeRTOS in Cube Bibliothek

Middlewares/Third_Party/FreeRTOS/

auch enthalten: CMSIS RTOS als “Wrapper” um FreeRTOS

Siehe im Verzeichnis

Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/

die Dateien cmsis_os.c und cmsis_os.h.

Variablennamen

Präfixe

  • u - unsigned

  • p - pointer

  • uc - uint8_t

  • v - void

  • pc - pointer to char

  • pv - pointer to char

  • s - int16_t

  • l - int32_t

  • x - BaseType_t (“bester” Integer Datentyp auf Architektur)

Tasks

[BARRY], Kap. 3

Zustandsdiagramm

  • Im SUSPENDED Zustand ist die Task nicht für den Scheduler verfügbar.

  • Aus dem BLOCKED Zustand kommt man nur durch

    1. Zeitliche Events, oder

    2. Synchronisations Events

_images/taskdiagramm.png

Fig. 5.1.1 Zustandsdiagramm einer Task ([BARRY], S. 67)

Task Timing

_images/task-timing1.png

Fig. 5.1.2 Zeitdiagramm zum Taskwechsel ([BARRY], S. 62)

Task Priorität

  • 0 ist die niedrigste Priorität

  • Bereich: 0 … configMAX_PRIORITIES-1

Tasks anlegen und löschen

  • xTaskCreate()

  • vTaskDelete()

  • vTaskStartScheduler()

Beispiel:

/* Args: Ptr to C fkt, descriptive name, stack depth, task parameter void*,
         priority, ptr to task handle


   Returns PASS or FAIL. */

xTaskCreate( prvQueueReceiveTask, "Rx", configMINIMAL_STACK_SIZE, NULL,
             mainQUEUE_RECEIVE_TASK_PRIORITY, NULL );

...

/* sample task */
prvQueueReceiveTask(void *pvParameters);

Tasks steuern

  • vTaskDelay()

  • vTaskDelayUntil()

  • vTaskSuspend()

  • vTaskResume()

  • vTaskResumeFromISR()

Timer

([BARRY], Kap. 5)

“One-shot” und “Periodic timers”

Zustände: Dormant, Running

API:

  • xTimerCreate()

  • xTimerDelete()

  • xTimerStart()

  • xTimerDelete()

  • xTimerStop()

  • xTimerReset()

  • xTimerChangePeriod()

Callback Funktion: void ATimerCallback( TimerHandle_t xTimer );

Beispiel für STM32F100 mit Timer, Queue und zwei Tasks:

https://www.freertos.org/FreeRTOS-for-Cortex-M3-STM32-STM32F100-Discovery.html

Synchronisationsmittel

  • queues ([BARRY] Kap. 4 - Queues) - Mailboxen (Sonderfall einer Queue der Länge 1, [BARRY], Kap. 4.7, S. 144)

  • binary semaphores ([BARRY], Kap. 6 - Interrupt Management)

  • counting semaphores

  • mutexes ([BARRY], Kap. 7 - Resource Management)

  • recursive mutexes

  • event groups ([BARRY], Kap. 8 - Event Groups)

  • direct to task notifications ([BARRY], Kap. 9 - Task Notifications)

  • gatekeeper task ([BARRY], Kap. 7 - Resource Management)

_images/queue.png

Fig. 5.1.3 In [BARRY], Kap 4, S. 105 (Queue Management) sieht man einen Ablauf von mehreren Send/Receive Operationen.

Semaphore

([BARRY], Kap. 6 - Interrupt Management)

  • vSemaphoreCreateBinary (Queue der Länge 1)

  • vSemaphoreCreateCounting

  • vSemaphoreCreateMutex

  • vSemaphoreTake (synonym: Take, P, decrement, down)

  • vSemaphoreGive (synonym: Give, V, incr, up)

  • vSemaphoreGiveFromISR

Siehe Abb. in [BARRY], S. 194 (Synchronisieren einer Task mit einem Interrupt über eine binäre Semaphore).

Queue Management

([BARRY], Kap. 4 - Queues)

  • Queues sind FIFO buffer.

  • Daten werden in die Queue kopiert.

  • Können von mehreren Tasks aus angesprochen werden.

  • Blockierzeit beim Lesen und beim Schreiben einstellbar.

    • Mehrere Schreiber können blockieren, wenn die Queue voll ist. Wenn Platz frei ist, wird nur ein Schreiber aktiviert.

    • Falls mehrere Leser blockieren, dann wird nur ein Leser bei Datenempfang aktiviert.

  • Queues können gruppiert werden (“queue sets”).

API

  • xQueueCreate

  • xQueueSend

  • xQueueReceive

Mutex

([BARRY], Kap. 7 - Resource Management) * mutex = MUTual EXclusion

  • Spezielle Form einer binären Semaphore um auf eine Resource zuzugreifen, die von mehreren Tasks geteilt wird.

  • Beispiel: vPrintString()

  • xSemaphoreCreateMutex()

  • Abb. [BARRY], S. 245

  • Prioritätsinversion ([BARRY], S. 250)

  • Rekursive Mutexe

  • Gatekeeper Tasks

    • Gegenseitiger Ausschluss ohne Prioritätsinversion oder Deadlock

    • Dem Gatekeeper “gehört” die Resource

    • “Klienten” des Gatekeeper senden Nachricht über Queue

    • vPrintString() jetzt mit Gatekeeper

Signale

  • kommen in FreeRTOS eigentlich nicht vor, sondern in CMSIS RTOS (siehe [YIUDG], Kap. 19)

  • API: osSignalSet(), osSignalWait(), osSignalClear()

  • Siehe Beispiele

    • es2-nucl476/cube-demos/FreeRTOS_Signal()

    • es2-nucl476/cube-demos/FreeRTOS_SignalFromISR()

Heap Management

[BARRY], Kap. 2

  • pvPortMalloc()

  • vPortFree()

Verschiedene Strategien:

  • heap1: deterministisch (kein free())

  • heap2: best fit (nicht deterministisch)

  • heap3: stdlib malloc() und free()

  • heap4: first fit algo

5.2. CMSIS-RTOS

Nur ein “API”, Implementierung z.B. durch FreeRTOS oder Keil RTX.

CMSIS RTOS Dokumentation: http://www.keil.com/pack/doc/CMSIS/RTOS/html/index.html

CMSIS RTOS API: _static/cmsis-rtos-api-1.png, _static/cmsis-rtos-api-2.png, _static/cmsis-rtos-api-3.png

Vergleiche dazu FREERTOS API: _static/freertos-api.png

Beispielprogramme für Nucleo L476 sind auf gitlab:

https://r-n-d.informatik.hs-augsburg.de:8080/es2-nucl476/cube-demos

  • FreeRTOS_EXTI

  • FreeRTOS_LowPower

  • FreeRTOS_Mail

  • FreeRTOS_Mutexes

  • FreeRTOS_Queues

  • FreeRTOS_Semaphore

  • FreeRTOS_Semaphore3

  • FreeRTOS_SemaphoreFromISR

  • FreeRTOS_Signal

  • FreeRTOS_SignalFromISR

  • FreeRTOS_ThreadCreation

  • FreeRTOS_ThreadCreation2

  • FreeRTOS_Timers

Alle Beispiele sind mit CMSIS-RTOS v1 API!

Damit Sie die Beispiele besser studieren können, navigieren Sie wieder mit dem Tags Mechanismus in Vim.

Veranschaulichung durch “Bildchen”

_images/rtosimg1.png
_images/rtosimg2.png
_images/rtosimg3.png
_images/rtosimg4.png
_images/rtosimg5.png
_images/rtosimg6.png
_images/rtosimg7.png

5.3. CMSIS RTOS API Doku

Dieser Text dient als Übersicht zum CMSIS RTOS API. Dieses API wird für RTOS-Beispiele der Cube-Bibliothek verwendet. Die darunterliegende Implementierung ist mit FreeRTOS gemacht. Fast der komplette Text wurde aus der Keil CMSIS RTOS Doku entnommen, siehe 1. Wer das Thema auch noch in einem Buch nachlesen möchte, kann in 2 Kap. 9 oder[3]_ Kap. 19 schauen.

5.3.1. Liste der API Funktionen

_images/API_Structure.png

Fig. 5.3.1 API Struktur

Funktion               Aus ISR aufrufbar   Kategorie
---------------------|-------------------|-----------------

osThreadCreate         nein                Task Management
osThreadGetId          nein
osThreadSetPriority    nein
osThreadTerminate      nein
osThreadYield          nein

osSignalClear          nein                 ITC: Signale
osSignalSet            ja
osSignalWait           nein

osSemaphoreCreate      nein                 ITC: Semaphore
osSemaphoreDelete      nein
osSemaphoreWait        nein
osSemaphoreRelease     ja

osMutexCreate          nein                 ITC: Mutex
osMutexDelete          nein
osMutexWait            nein
osMutexRelease         nein

osMailAlloc            ja                   ITC: Mail
osMailCreate           nein
osMailFree             ja
osMailGet              ja
osMailPut              ja

osMessageCreate        nein                 ITC: Message Queue
osMessageGet           ja
osMessagePut           ja

osPoolCreate           nein                 Memory Pool
osPoolAlloc            ja
osPoolFree             ja

osTimerCreate          nein                 Timer
osTimerDelete          nein
osTimerStart           nein
osTimerStop            nein

osDelay                nein                  Delay
osKernelSysTick        nein

Inter-Thread Communication (ITC) and Resource Sharing

  • Signal Events Synchronize threads using signals.

  • Message Queue Exchange messages between threads in a FIFO-like operation.

  • Memory Pool Manage thread-safe fixed-size blocks of dynamic memory.

  • Mail Queue Exchange data between threads using a queue of memory blocks.

  • Mutexes Synchronize resource access using Mutual Exclusion (Mutex).

  • Semaphores Access shared resources simultaneously from different threads.

5.3.2. Threads

_images/ThreadStatus.png

Fig. 5.3.2 Thread Status

Threads als enum-Typen

typedef enum
{
       THREAD_1 = 0,
       THREAD_2
} Thread_TypeDef;

osThreadDef

  • Interessante Frage: Was ist osThreadDef eigentlich genaugenommen?

  • Argumente: name, thread, priority, instances, stack

  • Beispiel

osThreadDef(THREAD_1, LED_Thread1, osPriorityNormal, 0, configMINIMAL_STACK_SIZE);

osThreadCreate

Aus 1:

Remove the thread function from the active thread list. If the thread is currently RUNNING the execution will stop.

  • Startet die Ausführung eines Threads

  • Gegenteil: osThreadTerminate()

  • Argumente: Ptr to thread def, ptr to args

osThreadId LEDThread1Handle;

LEDThread1Handle = osThreadCreate(osThread(THREAD_1), NULL);

osKernelStart();

Kernel starten.

Thread functions

static void LED_Thread1(void const *argument);

...

static void LED_Thread1(void const *argument)
{
   ...
}

osThreadSuspend

  • Suspend thread1

    osThreadSuspend(thread_id);
    
  • Suspend own thread

    osThreadSuspend(NULL);    // osThreadYield(void)
    

osThreadResume

osThreadResume(thread_id);

5.3.3. Signal

osSignalSet

Aus 1:

Set the signal flags of an active thread. This function may be used also within interrupt service routines.

Returns previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters.


Ein Signal ist ein diesem Fall ein 32-Bit Integer (int32_t).

osSignalSet( LED1_ThreadId, BIT_0 );

osSignalClear

Clear the signal flags of an active thread.

signals = osSignalClear (thread_id, 0x01);

osSignalWait

Aus 1:

Suspend the execution of the current RUNNING thread until all specified signal flags with the parameter signals are set. When the parameter signals is 0 the current RUNNING thread is suspended until any signal is set. When these signal flags are already set, the function returns instantly. Otherwise the thread is put into the state WAITING. Signal flags that are reported as event are automatically cleared.

The argument millisec specifies how long the system waits for the specified signal flags. While the system waits the thread calling this function is put into the state WAITING. The timeout value can have the following values:

  • when millisec is 0, the function returns instantly.

  • when millisec is set to osWaitForever the function will wait for an infinite time until a specified signal is set.

  • all other values specify a time in millisecond for a timeout.

for (;;)
{
    event = osSignalWait( BIT_1 | BIT_2, osWaitForever);
    if (event.value.signals == (BIT_1 | BIT_2))
    {
           BSP_LED_Toggle(LED2);
           ...

Es gibt auch event.status:

if (evt.status == osEventSignal)  {
    // handle event status
    ...

5.3.4. Semaphore

_images/Semaphore.png

Fig. 5.3.3 Semaphore

Macro osSemaphoreDef. SEM steht für die neu zu definierende Semaphore.

osSemaphoreDef(SEM);

osSemaphoreCreate

Argumente: Ptr auf SemaphoreDef, Anzahl Resourcen

Aufgabe: Was ist osSemaphoreId? (Tags verwenden)

osSemaphoreId osSemaphore;

...

osSemaphore = osSemaphoreCreate(osSemaphore(SEM) , 1);

...

// Semaphore z.B. als Argument an osThreadCreate uebergeben
SemThread1Handle = osThreadCreate(osThread(SEM_Thread1), (void *) osSemaphore);

osSemaphoreWait

osSemaphoreWait(sema, millis);

Aus 1:

Wait until a Semaphore token becomes available. When no Semaphore token is available, the function waits for the time specified with the parameter millisec.

The argument millisec specifies how long the system waits for a Semaphore token to become available. While the system waits the thread that is calling this function is put into the state WAITING. The millisec timeout can have the following values:

  • when millisec is 0, the function returns instantly.

  • when millisec is set to osWaitForever the function will wait for an infinite time until the Semaphore token becomes available.

  • all other values specify a time in millisecond for a timeout.

The return value indicates the number of available tokens (the semaphore count value). If 0 is returned, then no semaphore was available. The value -1 is returned in case of incorrect parameters.

osSemaphoreId semaphore;
...

if (osSemaphoreWait(semaphore , 100) == osOK)
        ...

osSemaphoreRelease

Release a Semaphore token. This increments the count of available semaphore tokens.

osSemaphoreRelease(semaphore);

5.3.5. Mutex

_images/Mutex.png

Fig. 5.3.4 Mutex

Aus 1:

Synchronize resource access using Mutual Exclusion (Mutex).

Mutual exclusion (widely known as Mutex) is used in various operating systems for resource management. Many resources in a microcontroller device can be used repeatedly, but only by one thread at a time (for example communication channels, memory, and files). Mutexes are used to protect access to a shared resource. A mutex is created and then passed between the threads (they can acquire and release the mutex).

A mutex is a special version of a semaphore. Like the semaphore, it is a container for tokens. But instead of being able to have multiple tokens, a mutex can only carry one (representing the resource). Thus, a mutex token is binary and bounded. The advantage of a mutex is that it introduces thread ownership. When a thread acquires a mutex and becomes its owner, subsequent mutex acquires from that thread will succeed immediately without any latency. Thus, mutex acquires/releases can be nested.

#define mutexTWO_TICK_DELAY  ((uint32_t) 2)

static osMutexId os_mutex_id;

osMutexDef(os_mutex);

osMutexCreate

Create and initialize a Mutex object.

os_mutex_id = osMutexCreate(osMutex(os_mutex));

osMutexWait

Aus 1:

Wait until a Mutex becomes available. If no other thread has obtained the Mutex, the function instantly returns and blocks the mutex object.

The argument millisec specifies how long the system waits for a mutex. While the system waits the thread that is calling this function is put into the state WAITING. The millisec timeout can have the following values:

  • when millisec is 0, the function returns instantly.

  • when millisec is set to osWaitForever the function will wait for an infinite time until the mutex becomes available.

  • all other values specify a time in millisecond for a timeout.

if (osMutexWait(os_mutex_id, mutexTWO_TICK_DELAY) != osOK)
{
   ...

osMutexRelease

Aus 1:

Release a Mutex that was obtained with osMutexWait. Other threads that currently wait for the same mutex will be now put into the state READY.

if (osMutexRelease(os_mutex_id) != osOK)
{
    BSP_LED_Toggle(LED3);
}

osMutexDelete

Aus 1:

Delete a Mutex object. The function releases internal memory obtained for Mutex handling. After this call the mutex_id is no longer valid and cannot be used. The Mutex may be created again using the function osMutexCreate.

if (mutex_id != NULL)  {
   status = osMutexDelete(mutex_id);
   if (status != osOK)  {
      ...

5.3.6. Mail Queue

_images/MailQueue.png

Fig. 5.3.5 Mail Queue

Aus 1:

A mail queue resembles a Message Queue, but the data that is being transferred consists of memory blocks that need to be allocated (before putting data in) and freed (after taking data out). The mail queue uses a Memory Pool to create formatted memory blocks and passes pointers to these blocks in a message queue. This allows the data to stay in an allocated memory block while only a pointer is moved between the separate threads. This is an advantage over messages that can transfer only a 32-bit value or a pointer. Using the mail queue functions, you can control, send, receive, or wait for mail.

osMailQId mailId;
#define MAIL_SIZE        (uint32_t) 1

...

typedef struct  // Mail object structure
{
     uint32_t var1; // var1 is a uint32_t
     uint32_t var2; // var2 is a uint32_t
     uint8_t  var3; // var3 is a uint8_t
} Amail_TypeDef;

...

// Define Mail Queue (Macro)
osMailQDef(mail, MAIL_SIZE, Amail_TypeDef);

...

// Create Mail Queue
mailId = osMailCreate(osMailQ(mail), NULL);

osMailAlloc

Aus 1:

Allocate a memory block from the mail queue that is filled with the mail information.

The argument queue_id specifies a mail queue identifier that is obtain with osMailCreate.

The argument millisec specifies how long the system waits for a mail slot to become available. While the system waits the thread calling this function is put into the state WAITING. The millisec timeout can have the following values:

  • when millisec is 0, the function returns instantly.

  • when millisec is set to osWaitForever the function will wait for an infinite time until a mail slot can be allocated.

  • all other values specify a time in millisecond for a timeout.

pTMail = osMailAlloc(mailId, osWaitForever);
pTMail->var1 = ProducerValue1;
...

osMailPut

Aus 1:

Put the memory block specified with mail into the mail queue specified by queue.

Status and Error Codes

  • osOK: the message is put into the queue.

  • osErrorValue: mail was previously not allocated as memory slot.

  • osErrorParameter: a parameter is invalid or outside of a permitted range.

if (osMailPut(mailId, pTMail) != osOK) /* Send Mail */

osMailGet

Aus 1:

Suspend the execution of the current RUNNING thread until a mail arrives. When a mail is already in the queue, the function returns instantly with the mail information.

The argument millisec specifies how long the system waits for a mail to arrive. While the system waits the thread that is calling this function is put into the state WAITING. The millisec timeout can have the following values:

  • when millisec is 0, the function returns instantly.

  • when millisec is set to osWaitForever the function will wait for an infinite time until a mail arrives.

  • all other values specify a time in millisecond for a timeout.

event = osMailGet(mailId, osWaitForever); /* wait for mail */
if (event.status == osEventMail)
{
     pRMail = event.value.p;
     pRMail->var1 ...
     ...

osMailFree

Aus 1:

Free the memory block specified by mail and return it to the mail queue.

osMailFree(mailId, pRMail); /* free memory allocated for mail */

5.3.7. Message Queue

_images/MessageQueue.png

Fig. 5.3.6 Message Queue

Code Beispiel siehe www.keil.com/pack/doc/CMSIS/RTOS/html/group__CMSIS__RTOS__Message.html

Aus 1:

Message passing is another basic communication model between threads. In the message passing model, one thread sends data explicitly, while another thread receives it. The operation is more like some kind of I/O rather than a direct access to information to be shared. In CMSIS-RTOS, this mechanism is called s message queue. The data is passed from one thread to another in a FIFO-like operation. Using message queue functions, you can control, send, receive, or wait for messages. The data to be passed can be of integer or pointer type:

osMessageCreate

#define QUEUE_SIZE 4

osMessageQId msg_id;

typedef struct {
   float    voltage;
   float    current;
   int      counter;
} T_MEAS;

osPoolDef(mpool, QUEUE_SIZE, T_MEAS);     // Define memory pool
osPoolId  mpool;

osMessageQDef(msg, QUEUE_SIZE, &T_MEAS);
msg_id = osMessageCreate(osMessageQ(msg), NULL);
...

osMessagePut

Aus 1:

Put the message info in a message queue specified by queue_id.

When the message queue is full, the system retries for a specified time with millisec. While the system retries the thread that is calling this function is put into the state WAITING. The millisec timeout can have the following values:

  • when millisec is 0, the function returns instantly.

  • when millisec is set to osWaitForever the function will wait for an infinite time until a message queue slot becomes available.

  • all other values specify a time in millisecond for a timeout.

T_MEAS    *mptr;
mptr = osPoolAlloc(mpool);    //  also osPoolcreate() ...
...
osMessagePut(msg_id, (uint32_t)mptr, osWaitForever);

osMessageGet

T_MEAS  *rptr;
osEvent  evt;

evt = osMessageGet(msg_id, osWaitForever);  // wait for message
if (evt.status == osEventMessage) {
    rptr = evt.value.p;
    ...

5.3.8. Memory Pool

Code Beispiel siehe https://www.keil.com/pack/doc/CMSIS/RTOS/html/group__CMSIS__RTOS__PoolMgmt.html

osPoolCreate

typedef struct {
       uint32_t length;
       uint32_t width;
       uint32_t height;
       uint32_t weight;
} properties_t;


osPoolDef (object_pool, 10, properties_t);  // Declare memory pool
osPoolId  (object_pool_id);                 // Memory pool ID

object_pool_id = osPoolCreate(osPool(object_pool));

osPoolAlloc

properties_t *object_data;
object_data = (properties_t *) osPoolAlloc(object_pool_id);

object_data->length = 100;
object_data->width  = 10;
object_data->height = 23;
object_data->weight = 1000;

osPoolFree

status = osPoolFree (MemPool_Id, object_data);
if (status==osOK)  {
    // handle status code
    ...
}

5.3.9. Time, Timer

_images/Timer.png

osKernelSysTick()

uint32_t osKernelSysTick(void)

osTimerCreate

Aus 1:

Create a one-shot or periodic timer and associate it with a callback function argument. The timer is in stopped until it is started with osTimerStart.

void Timer1_Callback  (void const *arg);

osTimerDef (Timer1, Timer1_Callback);

exec1 = 1;
id1 = osTimerCreate (osTimer(Timer1), osTimerOnce, &exec1);

osTimerStart

timerDelay = 1000;
status = osTimerStart(id, timerDelay);

osTimerStop

status = osTimerStop(id1);
if (status != osOK)  {
    ...

osTimerDelete

Stop and delete timer.

status = osTimerDelete(id);
if (status != osOK)  {
   ...

5.3.10. Delays

osDelay(millis)

Führt zu einem Suspend der Task bis Delay abgelaufen ist.

Aus 1:

Wait for a specified time period in millisec.

The millisec value specifies the number of timer ticks and is therefore an upper bound. The exact time delay depends on the actual time elapsed since the last timer tick.

For a value of 1, the system waits until the next timer tick occurs. That means that the actual time delay may be up to one timer tick less.

5.3.11. Literatur

1(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18)

https://www.keil.com/pack/doc/CMSIS/RTOS

2

Trevor Martin, The Designer’s Guide to the Cortex-M Processor Family, 2nd Edition, Packt 2016.

https://learning.oreilly.com/library/view/the-designers-guide/9780081006344/

3

Joseph Yiu, The Definitive Guide to ARM® Cortex®-M3 and Cortex®-M4 Processors, 3rd Edition, Newnes 2013.

https://learning.oreilly.com/library/view/the-definitive-guide/9780124080829/

5.4. Literatur

Allgemein

  1. David Kalinsky, Von sequenziell bis preemptiv. Einführung in die Welt der Task-Scheduler, Elektronik 4/2004 (6 Seiten).

    http://hhoegl.informatik.hs-augsburg.de/es2/prog/rtos/Kalinsky/

FreeRTOS

BARRY(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19)

Mastering the FreeRTOS Real Time Kernel, 2016.

http://hhoegl.informatik.hs-augsburg.de/es2/prog/rtos/Mastering-FreeRTOS-2016.pdf

 1   The FreeRTOS distribution
 2   Heap Memory Management
 3   Task Management
 4   Queue Management
 5   Software Timer Management
 6   Interrupt Management
 7   Resource Management
 8   Event Groups
 9   Task Notifications
10   Low Power Support
11   Developer support

BARRY2

Real Time Application Design Tutorial. Using FreeRTOS in small embedded systems.

https://www.freertos.org/tutorial

lokale Kopie: http://hhoegl.informatik.hs-augsburg.de/es2/prog/rtos/freertos-designguide/freertos-designtipps.html


BROWN

Kap. 16 (Real-Time Operating Systems), S. 217-235.

http://hhoegl.informatik.hs-augsburg.de/es2/Buecher/6/brown.pdf


UM1722

Developing Applications on STM32Cube with RTOS, 26 Seiten. Erklärt auch kurz die FreeRTOS Beispiele (mit CMSIS-RTOS API!) in der CubeF4 Bibliothek.

http://hhoegl.informatik.hs-augsburg.de/es2/prog/rtos/UM1722-Cube-FreeRTOS.pdf


RTOSFUND

RTOS fundamentals (siehe die Online-Doku von FreeRTOS im Abschnitt More Advanced / How FreeRTOS Works)

https://www.freertos.org/implementation/a00002.html


AOSARTOS

The Architecture of Open-Source Applications (Volume II), FreeRTOS

https://www.aosabook.org/en/freertos.html


OSBOOKS

Allgemein zu empfehlen sind auch alle Standardwerke zu Betriebssystemen: Tanenbaum, Silberschatz, Stallings …

  • Tanenbaum, Modern Operating Systems, Kap. “Processes and Threads”.

  • Silberschatz, Operating System Concepts, Kap. 6 “Synchronization”.

  • Stallings, Operating Systems. Internals and Design Principles, Kap. 5 “Concurrency: Mutual Exclusion and Synchronization”.


[NOVIELLO], Kap. 23 (Running FreeRTOS), S. 635-703.


CMSIS-RTOS

[YIUDG], Kap. 19 (Using Embedded Operating Systems), S. 605-645. Behandelt

CMSIS-RTOS, nicht FreeRTOS.


[MARTIN], Kap. 6 (Developing with CMSIS RTOS), S. 165-216 (erste Auflage

von 2013).


ARM MBED Dokumentation, Kapitel über “CMSIS-RTOS”

https://os.mbed.com/handbook/CMSIS-RTOS


CMSIS-RTOS Homepage der Fa. Keil

http://www.keil.com/cmsis/rtos