/* basic - why RTOS? want tasks for concurrency */
#include "FreeRTOS.h"
#include "task.h"
TaskHandle_t myTask1Handle = NULL;
void myTask1 (void *p) {
while (1) {
}
}
// then in main.c
// create task
vTaskStartScheduler (); // won't return
while (1) {
}
//-------------------------------------------------
/* Task */
xTaskCreate ( myTask1, "task1", 200 /*stacksize*/, (void*)0,
tskIDLE_PRIORITY, &myTask1Handle);
vTaskSuspend ( myTask1Handle );
vTaskSuspendAll();
vTaskResume ( myTask1Handle );
curTaskHandle = xTaskGetCurrentTaskHandle();
vTaskDelete ( curTaskHandle ); // delete oneself
taskName = pcTaskGetName ( myTask2Handle );
taskHandle = xTaskGetHandle ( "dog" ); // find handle by name
eTaskState myState;
myState = eTaskGetState ( myTaskHandle ); // return enum, 1 is eReady
char myTaskList[300];
vTaskList ( myTaskList );
uxTaskGetNumberOfTasks()
xTaskGetTickCount() // do NOT use in ISR
xTaskGetTickCountFromISR() // ISR version
//-------------------------------------------------
/* prefix */
https://www.freertos.org/FreeRTOS-Coding-Standard-and-Style-Guide.html#NamingConventions
// fcns:
v void
x return code or handle // ux eg. UBaseType_t
// vars:
ul uint32_t u uint16_t uc uint8_t
c char l long s short
e Enumerated variables
pc char *
//-------------------------------------------------
/* delay */
vTaskDelay ( 1000 ); // only if at default Hz; still slightly > 1000 ms
vTaskDelay ( 1000 * configTICK_RATE_HZ / 1000 ); // independent from Hz
// precise version:
TickType_t myLastUnblock;
myLastUnblock = xTaskGetTickCount ();
vTaskDelayUntil ( &myLastUnblock, 1000 * configTICK_RATE_HZ / 1000 );
//-------------------------------------------------
/* interrupt */
void myIntTask(void *p) {
while (1) {
vTaskSuspend( NULL ); // suspend right away once started
// do work
}
}
// in default IRQ Handler
BaesType_t xYieldRequired;
xYieldRequired = xTaskResumeFromISR ( myIntTask ); // resume my int fcn
portYIELD_FROM_ISR( xYieldRequired ); // require context switch
//-------------------------------------------------
/* Queue */ LIFO - add to back(tail), get from front(head)
#include "queue.h"
QueueHandle_t myQueue;
char buf[30];
myQueue = xQeuueCreate ( /*len*/5, sizeof(txBuf) );
// task 1
xQueueSend ( myQueue, (void*) txBuf, (TickType_t) 0); // block time 0 (no block)
xQueueSendToFront (..) // reverse order
xQueueOverwrite (..) // default send not overwrite
// task 2
if( xQueueReceive ( myQueue, (void*) rxBuf, (TickType_t) 5 )) {
// "Receive" blocked to read
// xQueuePeek (..)
// ..
}
uxQueueMessageWaiting ( myQueue ); // wait until ready
uxQueueSpaceAvailable ( myQueue );
xQueueReset ( myQueue ); // dump all unread message
//-------------------------------------------------
/* Notification */
/*task1*/ xTaskNotifyGive ( myTask2Handle ); // 'Give' to increment by 1 // default 0
/*task2*/ notifiedValue = ulTaskNotifyTake ( pdFALSE,
(TickType_t) portMAX_DELAY );
// decrement if false, reset to 0 if true
// task1
xTaskNotify ( myTask2Handle, 0, eNoAction );
// eSetBits, eIncrement, eSetValueWithOverwrite, eSetValueWithoutOverwrite
// eg. xTaskNotify ( myTask2Handle, (1<<2) | (1<<1), eSetBits );
xTaskNotifyAndQuery ( myTask2Handle,
(1<<2),
eSetValueWithOverwrite,
&ulNotifiedValue ); // store last value before inc
xTaskNotifyStateClear ( myTask2Handle ); // cancel send, value remains
// task2
if ( xTaskNotifyWait(0, 0, &ulNotifiedValue, portMAX_DELAY ) == pdTRUE ) {
// ..
}
//-------------------------------------------------
/* Semaphore */
#include "semphr.h"
// same handle for mutex & semaphore, up to create fcn
SemaphoreHandle_t xMutex;
xMutex = xSemaphoreCreateMutex(); // ... here determine what type
if ( xSemaphoreTake ( xMutex, (TickType_t) 0xFFFFFFFF ) == 1 ) { // LOCK
// do work
xSemaphoreGive ( xMutex ); // UNLOCK
}
Read more »Labels: FreeRTOS