Compare commits
1 Commits
starter
...
freertos-c
Author | SHA1 | Date |
---|---|---|
mpabi | fefa01e4f8 |
32
.gdb_history
32
.gdb_history
|
@ -1,19 +1,3 @@
|
||||||
withExternalMhartid = false,
|
|
||||||
mhartidWidth = 0,
|
|
||||||
pipelineCsrRead = false,
|
|
||||||
pipelinedInterrupt = false,
|
|
||||||
csrOhDecoder = false,
|
|
||||||
deterministicInteruptionEntry = false,
|
|
||||||
wfiOutput = false,
|
|
||||||
exportPrivilege = false,
|
|
||||||
withPrivilegedDebug = false,
|
|
||||||
debugTriggers = 0
|
|
||||||
)
|
|
||||||
),
|
|
||||||
load
|
|
||||||
c
|
|
||||||
load
|
|
||||||
si
|
|
||||||
load
|
load
|
||||||
load
|
load
|
||||||
load
|
load
|
||||||
|
@ -254,3 +238,19 @@ load
|
||||||
c
|
c
|
||||||
n
|
n
|
||||||
n
|
n
|
||||||
|
target extended-remote :3333
|
||||||
|
dashboard -layout registers stack memory expressions variables
|
||||||
|
file Demo/Common/bin/freeRTOS_demo.elf
|
||||||
|
load
|
||||||
|
si
|
||||||
|
si
|
||||||
|
si
|
||||||
|
del
|
||||||
|
b main
|
||||||
|
c
|
||||||
|
n
|
||||||
|
n
|
||||||
|
c
|
||||||
|
c
|
||||||
|
c
|
||||||
|
:q!
|
||||||
|
|
|
@ -0,0 +1,156 @@
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "queue.h"
|
||||||
|
#include "timers.h"
|
||||||
|
#include "murax.h"
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
|
||||||
|
#define mainTIMER_PERIOD_MS (1 / portTICK_PERIOD_MS) // Ustawienie okresu timera na 1 sekundę
|
||||||
|
#define QUEUE_LENGTH 5
|
||||||
|
#define QUEUE_ITEM_SIZE sizeof(uint32_t)
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
void vApplicationMallocFailedHook(void);
|
||||||
|
void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
// Deklaracja funkcji dla zadania i callbacku timera
|
||||||
|
static void hungryTask(void *pvParameters);
|
||||||
|
static void timerCallback(TimerHandle_t xTimer);
|
||||||
|
|
||||||
|
// Globalna kolejka
|
||||||
|
static QueueHandle_t xQueue;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <include/FreeRTOS/Task.hpp>
|
||||||
|
|
||||||
|
class MyTask : public FreeRTOS::Task {
|
||||||
|
public:
|
||||||
|
MyTask(const UBaseType_t priority, const char* name)
|
||||||
|
: FreeRTOS::Task(priority, configMINIMAL_STACK_SIZE, name) {}
|
||||||
|
void taskFunction() final;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Task to be created.
|
||||||
|
void MyTask::taskFunction() {
|
||||||
|
for (;;) {
|
||||||
|
// Task code goes here.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Function that creates a task.
|
||||||
|
void aFunction() {
|
||||||
|
// Create the task.
|
||||||
|
MyTask task((tskIDLE_PRIORITY + 1), "NAME");
|
||||||
|
|
||||||
|
// Check that the task was created successfully.
|
||||||
|
if (task.isValid()) {
|
||||||
|
// Start the scheduler.
|
||||||
|
FreeRTOS::Kernel::startScheduler();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Task will be destroyed when the scheduler is stopped and this function
|
||||||
|
// returns.
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
#include "include/Timer.hpp"
|
||||||
|
|
||||||
|
const Timer_Reg* TimeR::ptr = reinterpret_cast<const Timer_Reg*>(0xF0020040);
|
||||||
|
|
||||||
|
void print(const char*str){
|
||||||
|
while(*str){
|
||||||
|
uart_write(UART,*str);
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void println(const char*str){
|
||||||
|
print(str);
|
||||||
|
uart_write(UART,'\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "X.hpp"
|
||||||
|
|
||||||
|
#include "SimpleOStream.hpp"
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
|
||||||
|
// Definicja globalnego obiektu strumienia wyjściowego
|
||||||
|
SimpleOStream simpleCout;
|
||||||
|
|
||||||
|
|
||||||
|
X var {7};
|
||||||
|
|
||||||
|
//afunction();
|
||||||
|
|
||||||
|
println("hello world arty a7 v1");
|
||||||
|
|
||||||
|
|
||||||
|
xQueue = xQueueCreate(QUEUE_LENGTH, QUEUE_ITEM_SIZE); // Tworzenie kolejki
|
||||||
|
if (xQueue == NULL) {
|
||||||
|
return -1; // Błąd podczas tworzenia kolejki
|
||||||
|
}
|
||||||
|
|
||||||
|
TimerHandle_t xCheckTimer = NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Inicjalizacja timera
|
||||||
|
xCheckTimer = xTimerCreate("CheckTimer",
|
||||||
|
mainTIMER_PERIOD_MS,
|
||||||
|
pdTRUE,
|
||||||
|
(void *)0,
|
||||||
|
timerCallback);
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Start timera
|
||||||
|
if (xCheckTimer != NULL) {
|
||||||
|
xTimerStart(xCheckTimer, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tworzenie zadania hungryTask
|
||||||
|
xTaskCreate(hungryTask, "Hungry Task", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL);
|
||||||
|
|
||||||
|
// Uruchomienie planisty
|
||||||
|
vTaskStartScheduler();
|
||||||
|
|
||||||
|
// Teoretycznie nigdy nie powinniśmy tu dotrzeć
|
||||||
|
for (;;);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
// Definicja funkcji callback timera
|
||||||
|
static void timerCallback(TimerHandle_t xTimer) {
|
||||||
|
uint32_t ulValueToSend = 1; // Przykładowa wartość do wysłania
|
||||||
|
xQueueSendFromISR(xQueue, &ulValueToSend, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Definicja zadania
|
||||||
|
static void hungryTask(void *pvParameters) {
|
||||||
|
uint32_t ulReceivedValue;
|
||||||
|
for (;;) {
|
||||||
|
// if (xQueueReceive(xQueue, &ulReceivedValue, portMAX_DELAY) == pdPASS) {
|
||||||
|
//printf("hungry\n"); // Drukowanie, gdy odbierzemy wartość z kolejki
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vApplicationMallocFailedHook(void) {
|
||||||
|
for (;;);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vApplicationIdleHook(void) {
|
||||||
|
// Można tu umieścić kod wykonywany w stanie bezczynności
|
||||||
|
}
|
||||||
|
|
||||||
|
void vApplicationStackOverflowHook(TaskHandle_t pxTask, char *pcTaskName) {
|
||||||
|
for (;;);
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
#ifndef FREERTOSSTREAMBUF_HPP
|
||||||
|
#define FREERTOSSTREAMBUF_HPP
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <streambuf>
|
||||||
|
#include "murax.h"
|
||||||
|
|
||||||
|
// Klasa dziedzicząca z std::streambuf, przesyłająca dane do putchar
|
||||||
|
class FreeRTOSStreamBuf : public std::streambuf {
|
||||||
|
protected:
|
||||||
|
// Ta funkcja jest wywoływana, gdy bufor jest pełny lub napotkano std::endl
|
||||||
|
virtual int overflow(int c) override {
|
||||||
|
if (c != EOF) {
|
||||||
|
//putchar(c); // Wysyłanie znaku do putchar
|
||||||
|
uart_write(UART,c);
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Funkcja konfiguracyjna przekierowująca std::cout do FreeRTOSStreamBuf
|
||||||
|
void redirectCoutToPutchar() {
|
||||||
|
static FreeRTOSStreamBuf freertos_streambuf; // Globalny obiekt bufora
|
||||||
|
std::cout.rdbuf(&freertos_streambuf); // Ustawienie bufora jako wyjściowego dla std::cout
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FREERTOSSTREAMBUF_HPP
|
||||||
|
|
|
@ -10,10 +10,10 @@ PRINT_ENABLE ?= yes
|
||||||
|
|
||||||
TARGET=riscv32-unknown-${RISCV_LIB}
|
TARGET=riscv32-unknown-${RISCV_LIB}
|
||||||
GCC_PACK ?= yes
|
GCC_PACK ?= yes
|
||||||
RISCV_NAME ?= riscv32-unknown-elf
|
RISCV_NAME ?= riscv64-unknown-elf
|
||||||
|
|
||||||
ifeq ($(GCC_PACK),yes)
|
ifeq ($(GCC_PACK),yes)
|
||||||
RISCV_PATH ?= /home/user/riscv/opt/rv32im/
|
RISCV_PATH ?= /home/user/riscv/opt/rv32i_zicsr/
|
||||||
endif
|
endif
|
||||||
|
|
||||||
MABI = ilp32
|
MABI = ilp32
|
||||||
|
@ -33,13 +33,14 @@ INCLUDES = \
|
||||||
-I./include \
|
-I./include \
|
||||||
-I$(FREERTOS_SOURCE_DIR)/include \
|
-I$(FREERTOS_SOURCE_DIR)/include \
|
||||||
-I../Common/include \
|
-I../Common/include \
|
||||||
|
-I../Common/include/FreeRTOS \
|
||||||
-I$(FREERTOS_SOURCE_DIR)/portable/GCC/RISCV
|
-I$(FREERTOS_SOURCE_DIR)/portable/GCC/RISCV
|
||||||
|
|
||||||
CFLAGS = \
|
CFLAGS = \
|
||||||
$(WARNINGS) $(INCLUDES) \
|
$(WARNINGS) $(INCLUDES) \
|
||||||
-fomit-frame-pointer -fno-strict-aliasing -fno-builtin \
|
-fomit-frame-pointer -fno-strict-aliasing -fno-builtin \
|
||||||
-D__gracefulExit -mcmodel=medany \
|
-D__gracefulExit -mcmodel=medany \
|
||||||
-march=$(ARCH) -mabi=$(MABI) -ggdb3 -${OPT}
|
-march=$(ARCH) -mabi=$(MABI) -ggdb3 -gdwarf-3 -${OPT}
|
||||||
|
|
||||||
CXXFLAGS += -march=$(ARCH) \
|
CXXFLAGS += -march=$(ARCH) \
|
||||||
-mabi=$(MABI) \
|
-mabi=$(MABI) \
|
||||||
|
@ -48,7 +49,8 @@ CXXFLAGS += -march=$(ARCH) \
|
||||||
-MD \
|
-MD \
|
||||||
-fstrict-volatile-bitfields \
|
-fstrict-volatile-bitfields \
|
||||||
-fno-strict-aliasing \
|
-fno-strict-aliasing \
|
||||||
-std=c++11 \
|
-fno-exceptions \
|
||||||
|
-std=c++17 \
|
||||||
-ggdb3 -gdwarf-3 \
|
-ggdb3 -gdwarf-3 \
|
||||||
$(INCLUDES)
|
$(INCLUDES)
|
||||||
|
|
||||||
|
@ -57,11 +59,16 @@ ifeq ($(PRINT_ENABLE),yes)
|
||||||
CXXFLAGS += -DPRINT_ENABLE
|
CXXFLAGS += -DPRINT_ENABLE
|
||||||
endif
|
endif
|
||||||
|
|
||||||
LDFLAGS = -g -T ../arch/link.ld -nostartfiles -static -march=$(ARCH)
|
LDFLAGS = -g -T ../arch/link.ld \
|
||||||
|
-nostartfiles \
|
||||||
|
-static \
|
||||||
|
-fno-exceptions \
|
||||||
|
-march=$(ARCH) -mabi=$(MABI) -ggdb3 -gdwarf-3
|
||||||
|
|
||||||
LIBS = -L$(RISCV_PATH)/lib/gcc/$(TARGET)/$(GCCVER) \
|
LIBS = -L$(RISCV_PATH)/lib/gcc/$(TARGET)/$(GCCVER) \
|
||||||
-L$(RISCV_PATH)/$(TARGET)/lib \
|
-L$(RISCV_PATH)/$(TARGET)/lib \
|
||||||
-lc -lgcc -lstdc++\
|
-fno-exceptions \
|
||||||
-I/home/user/opt/include
|
-lc -lgcc -lstdc++
|
||||||
|
|
||||||
RISCV_OBJCOPY = $(RISCV_PATH)/bin/$(RISCV_NAME)-objcopy
|
RISCV_OBJCOPY = $(RISCV_PATH)/bin/$(RISCV_NAME)-objcopy
|
||||||
RISCV_OBJDUMP = $(RISCV_PATH)/bin/$(RISCV_NAME)-objdump
|
RISCV_OBJDUMP = $(RISCV_PATH)/bin/$(RISCV_NAME)-objdump
|
||||||
|
@ -74,13 +81,14 @@ SRCS = $(wildcard ../arch/*.c) \
|
||||||
$(wildcard ../Common/*.c) \
|
$(wildcard ../Common/*.c) \
|
||||||
$(wildcard ../Common/*.cpp) \
|
$(wildcard ../Common/*.cpp) \
|
||||||
$(wildcard ../Common/*.S) \
|
$(wildcard ../Common/*.S) \
|
||||||
|
$(wildcard ../Common/lib/*.c) \
|
||||||
$(FREERTOS_SOURCE_DIR)/croutine.c \
|
$(FREERTOS_SOURCE_DIR)/croutine.c \
|
||||||
$(FREERTOS_SOURCE_DIR)/list.c \
|
$(FREERTOS_SOURCE_DIR)/list.c \
|
||||||
$(FREERTOS_SOURCE_DIR)/queue.c \
|
$(FREERTOS_SOURCE_DIR)/queue.c \
|
||||||
$(FREERTOS_SOURCE_DIR)/tasks.c \
|
$(FREERTOS_SOURCE_DIR)/tasks.c \
|
||||||
$(FREERTOS_SOURCE_DIR)/timers.c \
|
$(FREERTOS_SOURCE_DIR)/timers.c \
|
||||||
$(FREERTOS_SOURCE_DIR)/event_groups.c \
|
$(FREERTOS_SOURCE_DIR)/event_groups.c \
|
||||||
$(FREERTOS_SOURCE_DIR)/portable/MemMang/heap_2.c \
|
$(FREERTOS_SOURCE_DIR)/portable/MemMang/heap_3.c \
|
||||||
$(FREERTOS_SOURCE_DIR)/string.c \
|
$(FREERTOS_SOURCE_DIR)/string.c \
|
||||||
$(FREERTOS_SOURCE_DIR)/portable/GCC/RISCV/port.c \
|
$(FREERTOS_SOURCE_DIR)/portable/GCC/RISCV/port.c \
|
||||||
$(FREERTOS_SOURCE_DIR)/portable/GCC/RISCV/portasm.S \
|
$(FREERTOS_SOURCE_DIR)/portable/GCC/RISCV/portasm.S \
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
#ifndef SIMPLEOSTREAM_HPP
|
||||||
|
#define SIMPLEOSTREAM_HPP
|
||||||
|
|
||||||
|
#include <cstdio> // dla putchar
|
||||||
|
|
||||||
|
class SimpleOStream {
|
||||||
|
public:
|
||||||
|
SimpleOStream& operator<<(const char* str) {
|
||||||
|
while (*str) {
|
||||||
|
putchar(*str++);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleOStream& operator<<(char c) {
|
||||||
|
putchar(c);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleOStream& operator<<(int num) {
|
||||||
|
char buffer[12]; // wystarczająco duży, aby pomieścić liczbę int
|
||||||
|
snprintf(buffer, sizeof(buffer), "%d", num);
|
||||||
|
return *this << buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleOStream& operator<<(unsigned int num) {
|
||||||
|
char buffer[12];
|
||||||
|
snprintf(buffer, sizeof(buffer), "%u", num);
|
||||||
|
return *this << buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleOStream& operator<<(long num) {
|
||||||
|
char buffer[20]; // wystarczająco duży, aby pomieścić liczbę long
|
||||||
|
snprintf(buffer, sizeof(buffer), "%ld", num);
|
||||||
|
return *this << buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleOStream& operator<<(unsigned long num) {
|
||||||
|
char buffer[20];
|
||||||
|
snprintf(buffer, sizeof(buffer), "%lu", num);
|
||||||
|
return *this << buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleOStream& operator<<(double num) {
|
||||||
|
char buffer[64]; // wystarczająco duży, aby pomieścić liczbę double
|
||||||
|
snprintf(buffer, sizeof(buffer), "%f", num);
|
||||||
|
return *this << buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleOStream& operator<<(void* ptr) {
|
||||||
|
char buffer[20];
|
||||||
|
snprintf(buffer, sizeof(buffer), "%p", ptr);
|
||||||
|
return *this << buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Użyj tego operatora do manipulacji takimi jak std::endl
|
||||||
|
SimpleOStream& operator<<(SimpleOStream& (*manip)(SimpleOStream&)) {
|
||||||
|
return manip(*this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Manipulator std::endl
|
||||||
|
SimpleOStream& endl(SimpleOStream& os) {
|
||||||
|
os << '\n';
|
||||||
|
fflush(stdout);
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Globalny obiekt dla strumienia wyjściowego
|
||||||
|
extern SimpleOStream simpleCout;
|
||||||
|
|
||||||
|
#endif // SIMPLEOSTREAM_HPP
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
#include "X.hpp"
|
||||||
|
|
||||||
|
X::X(int i) : m{i} {
|
||||||
|
// constructor body (if needed)
|
||||||
|
}
|
||||||
|
|
||||||
|
int X::mf(int i) {
|
||||||
|
int old = m;
|
||||||
|
m = i; // set a new value
|
||||||
|
return old; // return the old value
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
#ifndef X_HPP
|
||||||
|
#define X_HPP
|
||||||
|
|
||||||
|
class X {
|
||||||
|
private:
|
||||||
|
int m; // the representation (implementation) is private
|
||||||
|
|
||||||
|
public:
|
||||||
|
// the user interface is public
|
||||||
|
X(int i = 0); // constructor (initialize the data member m)
|
||||||
|
|
||||||
|
int mf(int i); // a member function
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // X_HPP
|
||||||
|
|
|
@ -0,0 +1,503 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS-Cpp
|
||||||
|
* Copyright (C) 2021 Jon Enz. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://github.com/jonenz/FreeRTOS-Cpp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FREERTOS_EVENTGROUPS_HPP
|
||||||
|
#define FREERTOS_EVENTGROUPS_HPP
|
||||||
|
|
||||||
|
#include <bitset>
|
||||||
|
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "event_groups.h"
|
||||||
|
|
||||||
|
namespace FreeRTOS {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class EventGroupBase EventGroupBase.hpp <FreeRTOS/EventGroups.hpp>
|
||||||
|
*
|
||||||
|
* @brief Base class that provides the standard event group interface to
|
||||||
|
* FreeRTOS::EventGroup and FreeRTOS::StaticEventGroup.
|
||||||
|
*
|
||||||
|
* @note This class is not intended to be instantiated by the user. Use
|
||||||
|
* FreeRTOS::EventGroup or FreeRTOS::StaticEventGroup.
|
||||||
|
*/
|
||||||
|
class EventGroupBase {
|
||||||
|
public:
|
||||||
|
friend class EventGroup;
|
||||||
|
friend class StaticEventGroup;
|
||||||
|
|
||||||
|
EventGroupBase(const EventGroupBase&) = delete;
|
||||||
|
EventGroupBase& operator=(const EventGroupBase&) = delete;
|
||||||
|
|
||||||
|
static void* operator new(size_t, void* ptr) { return ptr; }
|
||||||
|
static void* operator new[](size_t, void* ptr) { return ptr; }
|
||||||
|
static void* operator new(size_t) = delete;
|
||||||
|
static void* operator new[](size_t) = delete;
|
||||||
|
|
||||||
|
// NOLINTNEXTLINE
|
||||||
|
using EventBits = std::bitset<((configUSE_16_BIT_TICKS == 1) ? 8 : 24)>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EventGroups.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that checks if the underlying event group handle is not
|
||||||
|
* NULL. This should be used to ensure an event group has been created
|
||||||
|
* correctly.
|
||||||
|
*
|
||||||
|
* @retval true the handle is not NULL.
|
||||||
|
* @retval false the handle is NULL.
|
||||||
|
*/
|
||||||
|
inline bool isValid() const { return (handle != NULL); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EventGroups.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>EventBits_t xEventGroupWaitBits( const
|
||||||
|
* EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const
|
||||||
|
* BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t
|
||||||
|
* xTicksToWait )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xEventGroupWaitBits.html>
|
||||||
|
*
|
||||||
|
* Read bits within an RTOS event group, optionally entering the Blocked state
|
||||||
|
* (with a timeout) to wait for a bit or group of bits to become set.
|
||||||
|
*
|
||||||
|
* @warning This function cannot be called from an interrupt.
|
||||||
|
*
|
||||||
|
* @param bitsToWaitFor A bitwise value that indicates the bit or bits to test
|
||||||
|
* inside the event group. bitsToWaitFor must not be set to 0.
|
||||||
|
* @param clearOnExit If clearOnExit is set to true then any bits set in the
|
||||||
|
* value passed as the bitsToWaitFor parameter will be cleared in the event
|
||||||
|
* group before wait() returns if wait() returns for any reason other than a
|
||||||
|
* timeout. The timeout value is set by the ticksToWait parameter. If
|
||||||
|
* clearOnExit is set to false then the bits set in the event group are not
|
||||||
|
* altered when the call to wait() returns.
|
||||||
|
* @param waitForAllBits waitForAllBits is used to create either a logical AND
|
||||||
|
* test (where all bits must be set) or a logical OR test (where one or more
|
||||||
|
* bits must be set) as follows: If waitForAllBits is set to true then wait()
|
||||||
|
* will return when either all the bits set in the value passed as the
|
||||||
|
* bitsToWaitFor parameter are set in the event group or the specified block
|
||||||
|
* time expires. If waitForAllBits is set to false then wait() will return
|
||||||
|
* when any of the bits set in the value passed as the bitsToWaitFor parameter
|
||||||
|
* are set in the event group or the specified block time expires.
|
||||||
|
* @param ticksToWait The maximum amount of time (specified in 'ticks') to
|
||||||
|
* wait for one/all (depending on the waitForAllBits value) of the bits
|
||||||
|
* specified by bitsToWaitFor to become set.
|
||||||
|
* @return EventBits The value of the event group at the time either the event
|
||||||
|
* bits being waited for became set, or the block time expired. The current
|
||||||
|
* value of the event bits in an event group will be different to the returned
|
||||||
|
* value if a higher priority task or interrupt changed the value of an event
|
||||||
|
* bit between the calling task leaving the Blocked state and exiting the
|
||||||
|
* wait() function. Test the return value to know which bits were set. If
|
||||||
|
* wait() returned because its timeout expired then not all the bits being
|
||||||
|
* waited for will be set. If wait() returned because the bits it was waiting
|
||||||
|
* for were set then the returned value is the event group value before any
|
||||||
|
* bits were automatically cleared because the clearOnExit parameter was set
|
||||||
|
* to true.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include EventGroups/wait.cpp
|
||||||
|
*/
|
||||||
|
inline EventBits wait(const EventBits& bitsToWaitFor = 0,
|
||||||
|
const bool clearOnExit = false,
|
||||||
|
const bool waitForAllBits = false,
|
||||||
|
const TickType_t ticksToWait = portMAX_DELAY) const {
|
||||||
|
return EventBits(xEventGroupWaitBits(
|
||||||
|
handle, bitsToWaitFor.to_ulong(), (clearOnExit ? pdTRUE : pdFALSE),
|
||||||
|
(waitForAllBits ? pdTRUE : pdFALSE), ticksToWait));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EventGroups.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>EventBits_t xEventGroupSetBits(
|
||||||
|
* EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xEventGroupSetBits.html>
|
||||||
|
*
|
||||||
|
* Set bits (flags) within an RTOS event group. This function cannot be called
|
||||||
|
* from an interrupt. setFromISR() is a version that can be called from an
|
||||||
|
* interrupt.
|
||||||
|
*
|
||||||
|
* Setting bits in an event group will automatically unblock tasks that are
|
||||||
|
* blocked waiting for the bits.
|
||||||
|
*
|
||||||
|
* @param bitsToSet A bitwise value that indicates the bit or bits to set in
|
||||||
|
* the event group.
|
||||||
|
* @return EventBits The value of the event group at the time the call to
|
||||||
|
* set() returns. There are two reasons why the returned value might have the
|
||||||
|
* bits specified by the uxBitsToSet parameter cleared:
|
||||||
|
* 1. If setting a bit results in a task that was waiting for the bit leaving
|
||||||
|
* the blocked state then it is possible the bit will have been cleared
|
||||||
|
* automatically (see the clearOnExit parameter of wait()).
|
||||||
|
* 2. Any unblocked (or otherwise Ready state) task that has a priority above
|
||||||
|
* that of the task that called set() will execute and may change the event
|
||||||
|
* group value before the call to set() returns.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include EventGroups/set.cpp
|
||||||
|
*/
|
||||||
|
inline EventBits set(const EventBits& bitsToSet) const {
|
||||||
|
return EventBits(xEventGroupSetBits(handle, bitsToSet.to_ulong()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EventGroups.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>BaseType_t xEventGroupSetBitsFromISR(
|
||||||
|
* EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t
|
||||||
|
* *pxHigherPriorityTaskWoken )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xEventGroupSetBitsFromISR.html>
|
||||||
|
*
|
||||||
|
* Set bits (flags) within an RTOS event group. A version of set() that can be
|
||||||
|
* called from an interrupt service routine (ISR).
|
||||||
|
*
|
||||||
|
* Setting bits in an event group will automatically unblock tasks that are
|
||||||
|
* blocked waiting for the bits.
|
||||||
|
*
|
||||||
|
* Setting bits in an event group is not a deterministic operation because
|
||||||
|
* there are an unknown number of tasks that may be waiting for the bit or
|
||||||
|
* bits being set. FreeRTOS does not allow non-deterministic operations to be
|
||||||
|
* performed in interrupts or from critical sections. Therefore
|
||||||
|
* xEventGroupSetBitFromISR() sends a message to the RTOS daemon task to have
|
||||||
|
* the set operation performed in the context of the daemon task - where a
|
||||||
|
* scheduler lock is used in place of a critical section.
|
||||||
|
*
|
||||||
|
* @note As mentioned in the paragraph above, setting bits from an ISR will
|
||||||
|
* defer the set operation to the RTOS daemon task (also known as the timer
|
||||||
|
* service task). The RTOS daemon task is scheduled according to its priority,
|
||||||
|
* just like any other RTOS task. Therefore, if it is essential the set
|
||||||
|
* operation completes immediately (before a task created by the application
|
||||||
|
* executes) then the priority of the RTOS daemon task must be higher than the
|
||||||
|
* priority of any application task that uses the event group. The priority of
|
||||||
|
* the RTOS daemon task is set by the configTIMER_TASK_PRIORITY definition in
|
||||||
|
* FreeRTOSConfig.h.
|
||||||
|
*
|
||||||
|
* @param higherPriorityTaskWoken As mentioned above, calling this function
|
||||||
|
* will result in a message being sent to the RTOS daemon task. If the
|
||||||
|
* priority of the daemon task is higher than the priority of the currently
|
||||||
|
* running task (the task the interrupt interrupted) then
|
||||||
|
* higherPriorityTaskWoken will be set to true by setFromISR(), indicating
|
||||||
|
* that a context switch should be requested before the interrupt exits. For
|
||||||
|
* that reason higherPriorityTaskWoken must be initialised to false. See the
|
||||||
|
* example code below.
|
||||||
|
* @param bitsToSet A bitwise value that indicates the bit or bits to set in
|
||||||
|
* the event group.
|
||||||
|
* @retval true If the message was sent to the RTOS daemon task.
|
||||||
|
* @retval false Otherwise or if the timer service queue was full
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include EventGroups/setFromISR.cpp
|
||||||
|
*/
|
||||||
|
inline bool setFromISR(bool& higherPriorityTaskWoken,
|
||||||
|
const EventBits& bitsToSet) const {
|
||||||
|
BaseType_t taskWoken = pdFALSE;
|
||||||
|
bool result = (xEventGroupSetBitsFromISR(handle, bitsToSet.to_ulong(),
|
||||||
|
&taskWoken) == pdPASS);
|
||||||
|
if (taskWoken == pdTRUE) {
|
||||||
|
higherPriorityTaskWoken = true;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EventGroups.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>BaseType_t xEventGroupSetBitsFromISR(
|
||||||
|
* EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t
|
||||||
|
* *pxHigherPriorityTaskWoken )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xEventGroupSetBitsFromISR.html>
|
||||||
|
*
|
||||||
|
* @overload
|
||||||
|
*/
|
||||||
|
inline bool setFromISR(const EventBits& bitsToSet) const {
|
||||||
|
return (xEventGroupSetBitsFromISR(handle, bitsToSet.to_ulong(), NULL) ==
|
||||||
|
pdPASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EventGroups.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>EventBits_t xEventGroupClearBits(
|
||||||
|
* EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xEventGroupClearBits.html>
|
||||||
|
*
|
||||||
|
* Clear bits (flags) within an RTOS event group. This function cannot be
|
||||||
|
* called from an interrupt. See clearFromISR() for a version that can be
|
||||||
|
* called from an interrupt.
|
||||||
|
*
|
||||||
|
* @param bitsToClear A bitwise value that indicates the bit or bits to clear
|
||||||
|
* in the event group.
|
||||||
|
* @return EventBits The value of the event group before the specified bits
|
||||||
|
* were cleared.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include EventGroups/clear.cpp
|
||||||
|
*/
|
||||||
|
inline EventBits clear(const EventBits& bitsToClear) const {
|
||||||
|
return EventBits(xEventGroupClearBits(handle, bitsToClear.to_ulong()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EventGroups.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>BaseType_t xEventGroupClearBitsFromISR(
|
||||||
|
* EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xEventGroupClearBitsFromISR.html>
|
||||||
|
*
|
||||||
|
* A version of clear() that can be called from an interrupt. The clear
|
||||||
|
* operation is deferred to the RTOS daemon task which is also known as the
|
||||||
|
* timer service task. The priority of the daemon task is set by the
|
||||||
|
* configTIMER_TASK_PRIORITY setting in FreeRTOSConfig.h.
|
||||||
|
*
|
||||||
|
* @param bitsToClear A bitwise value that indicates the bit or bits to clear
|
||||||
|
* in the event group.
|
||||||
|
* @return true If the operation was successfully deferred to the RTOS daemon
|
||||||
|
* task.
|
||||||
|
* @return false If the timer command queue is full.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include EventGroups/clearFromISR.cpp
|
||||||
|
*/
|
||||||
|
inline bool clearFromISR(const EventBits& bitsToClear) const {
|
||||||
|
return (xEventGroupClearBitsFromISR(handle, bitsToClear.to_ulong()) ==
|
||||||
|
pdPASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EventGroups.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>EventBits_t xEventGroupGetBits(
|
||||||
|
* EventGroupHandle_t xEventGroup )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xEventGroupGetBits.html>
|
||||||
|
*
|
||||||
|
* Returns the current value of the event bits (event flags) in an RTOS event
|
||||||
|
* group. This function cannot be used from an interrupt. See getFromISR() for
|
||||||
|
* a version that can be used in an interrupt.
|
||||||
|
*
|
||||||
|
* @return EventBits The value of the event bits in the event group at the
|
||||||
|
* time get() was called.
|
||||||
|
*/
|
||||||
|
inline EventBits get() const { return EventBits(xEventGroupGetBits(handle)); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EventGroups.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>EventBits_t xEventGroupGetBitsFromISR(
|
||||||
|
* EventGroupHandle_t xEventGroup )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xEventGroupGetBitsFromISR.html>
|
||||||
|
*
|
||||||
|
* A version of get() that can be called from an interrupt.
|
||||||
|
*
|
||||||
|
* @return EventBits The value of the event bits in the event group at the
|
||||||
|
* time getFromISR() was called.
|
||||||
|
*/
|
||||||
|
inline EventBits getFromISR() const {
|
||||||
|
return EventBits(xEventGroupGetBitsFromISR(handle));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EventGroups.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>EventBits_t xEventGroupSync(
|
||||||
|
* EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const
|
||||||
|
* EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xEventGroupSync.html>
|
||||||
|
*
|
||||||
|
* Atomically set bits (flags) within an RTOS event group, then wait for a
|
||||||
|
* combination of bits to be set within the same event group. This
|
||||||
|
* functionality is typically used to synchronize multiple tasks (often called
|
||||||
|
* a task rendezvous), where each task has to wait for the other tasks to
|
||||||
|
* reach a synchronization point before proceeding.
|
||||||
|
*
|
||||||
|
* This function cannot be used from an interrupt.
|
||||||
|
*
|
||||||
|
* The function will return before its block time expires if the bits
|
||||||
|
* specified by the bitsToWait parameter are set, or become set within that
|
||||||
|
* time. In this case all the bits specified by bitsToWait will be
|
||||||
|
* automatically cleared before the function returns.
|
||||||
|
*
|
||||||
|
* @param bitsToSet The bit or bits to set in the event group before
|
||||||
|
* determining if (and possibly waiting for), all the bits specified by the
|
||||||
|
* bitsToWait parameter are set.
|
||||||
|
* @param bitsToWaitFor A bitwise value that indicates the bit or bits to test
|
||||||
|
* inside the event group.
|
||||||
|
* @param ticksToWait The maximum amount of time (specified in 'ticks') to
|
||||||
|
* wait for all the bits specified by the uxBitsToWaitFor parameter value to
|
||||||
|
* become set.
|
||||||
|
* @return EventBits
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include EventGroups/sync.cpp
|
||||||
|
*/
|
||||||
|
inline EventBits sync(const EventBits& bitsToSet = 0,
|
||||||
|
const EventBits& bitsToWaitFor = 0,
|
||||||
|
const TickType_t ticksToWait = portMAX_DELAY) const {
|
||||||
|
return EventBits(xEventGroupSync(handle, bitsToSet.to_ulong(),
|
||||||
|
bitsToWaitFor.to_ulong(), ticksToWait));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* EventGroups.hpp
|
||||||
|
*
|
||||||
|
* @brief Construct a new EventGroupBase object.
|
||||||
|
*
|
||||||
|
* @note Default constructor is deliberately private as this class is not
|
||||||
|
* intended to be instantiated or derived from by the user. Use
|
||||||
|
* FreeRTOS::EventGroup or FreeRTOS::StaticEventGroup.
|
||||||
|
*/
|
||||||
|
EventGroupBase() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EventGroup.hpp
|
||||||
|
*
|
||||||
|
* @brief Destroy the EventGroupBase object by calling <tt>void
|
||||||
|
* vEventGroupDelete( EventGroupHandle_t xEventGroup )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/vEventGroupDelete.html>
|
||||||
|
*
|
||||||
|
* Delete an event group.
|
||||||
|
*
|
||||||
|
* Tasks that are blocked on the event group being deleted will be unblocked,
|
||||||
|
* and report an event group value of 0.
|
||||||
|
*/
|
||||||
|
~EventGroupBase() { vEventGroupDelete(this->handle); };
|
||||||
|
|
||||||
|
EventGroupBase(EventGroupBase&&) noexcept = default;
|
||||||
|
EventGroupBase& operator=(EventGroupBase&&) noexcept = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Handle used to refer to the event group when using the FreeRTOS
|
||||||
|
* interface.
|
||||||
|
*/
|
||||||
|
EventGroupHandle_t handle = NULL;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class EventGroup EventGroups.hpp <FreeRTOS/EventGroups.hpp>
|
||||||
|
*
|
||||||
|
* @brief Class that encapsulates the functionality of a FreeRTOS event group.
|
||||||
|
*
|
||||||
|
* Each event group requires a [very] small amount of RAM that is used to hold
|
||||||
|
* the event group's state. If an event group is created using this class then
|
||||||
|
* the required RAM is automatically allocated from the FreeRTOS heap. If an
|
||||||
|
* event group is created using FreeRTOS::StaticEventGroup then the RAM is
|
||||||
|
* provided by the application writer, which requires an additional parameter,
|
||||||
|
* but allows the RAM to be statically allocated at compile time. See the Static
|
||||||
|
* Vs Dynamic allocation page for more information.
|
||||||
|
*/
|
||||||
|
class EventGroup : public EventGroupBase {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* EventGroup.hpp
|
||||||
|
*
|
||||||
|
* @brief Construct a new EventGroup object by calling <tt>EventGroupHandle_t
|
||||||
|
* xEventGroupCreate( void )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xEventGroupCreate.html>
|
||||||
|
*
|
||||||
|
* @warning The user should call isValid() on this object to verify that the
|
||||||
|
* queue was created successfully in case the memory required to create the
|
||||||
|
* queue could not be allocated.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include EventGroups/eventGroup.cpp
|
||||||
|
*/
|
||||||
|
EventGroup() { this->handle = xEventGroupCreate(); }
|
||||||
|
~EventGroup() = default;
|
||||||
|
|
||||||
|
EventGroup(const EventGroup&) = delete;
|
||||||
|
EventGroup& operator=(const EventGroup&) = delete;
|
||||||
|
|
||||||
|
EventGroup(EventGroup&&) noexcept = default;
|
||||||
|
EventGroup& operator=(EventGroup&&) noexcept = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||||
|
|
||||||
|
#if (configSUPPORT_STATIC_ALLOCATION == 1)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class StaticEventGroup EventGroups.hpp <FreeRTOS/EventGroups.hpp>
|
||||||
|
*
|
||||||
|
* @brief Class that encapsulates the functionality of a FreeRTOS event group.
|
||||||
|
*
|
||||||
|
* Each event group requires a [very] small amount of RAM that is used to hold
|
||||||
|
* the event group's state. If an event group is created using
|
||||||
|
* FreeRTOS::EventGroup then the required RAM is automatically allocated from
|
||||||
|
* the FreeRTOS heap. If an event group is created using this class then the RAM
|
||||||
|
* is provided by the application writer, which requires an additional
|
||||||
|
* parameter, but allows the RAM to be statically allocated at compile time. See
|
||||||
|
* the Static Vs Dynamic allocation page for more information.
|
||||||
|
*/
|
||||||
|
class StaticEventGroup : public EventGroupBase {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* EventGroups.hpp
|
||||||
|
*
|
||||||
|
* @brief Construct a new StaticEventGroup object by calling
|
||||||
|
* <tt>EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t
|
||||||
|
* *pxEventGroupBuffer )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xEventGroupCreateStatic.html>
|
||||||
|
*
|
||||||
|
* @warning This class contains the storage buffer for the event group, so the
|
||||||
|
* user should create this object as a global object or with the static
|
||||||
|
* storage specifier so that the object instance is not on the stack.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include EventGroups/staticEventGroup.cpp
|
||||||
|
*/
|
||||||
|
StaticEventGroup() {
|
||||||
|
this->handle = xEventGroupCreateStatic(&staticEventGroup);
|
||||||
|
}
|
||||||
|
~StaticEventGroup() = default;
|
||||||
|
|
||||||
|
StaticEventGroup(const StaticEventGroup&) = delete;
|
||||||
|
StaticEventGroup& operator=(const StaticEventGroup&) = delete;
|
||||||
|
|
||||||
|
StaticEventGroup(StaticEventGroup&&) noexcept = default;
|
||||||
|
StaticEventGroup& operator=(StaticEventGroup&&) noexcept = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
StaticEventGroup_t staticEventGroup;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||||
|
|
||||||
|
} // namespace FreeRTOS
|
||||||
|
|
||||||
|
#endif // FREERTOS_EVENTGROUPS_HPP
|
|
@ -0,0 +1,409 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS-Cpp
|
||||||
|
* Copyright (C) 2021 Jon Enz. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://github.com/jonenz/FreeRTOS-Cpp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FREERTOS_KERNEL_HPP
|
||||||
|
#define FREERTOS_KERNEL_HPP
|
||||||
|
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
namespace FreeRTOS {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Kernel namespace that provides an interface to kernel functions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
namespace Kernel {
|
||||||
|
enum class SchedulerState : BaseType_t {
|
||||||
|
Suspended = taskSCHEDULER_SUSPENDED,
|
||||||
|
NotStarted = taskSCHEDULER_NOT_STARTED,
|
||||||
|
Running = taskSCHEDULER_RUNNING,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief If versionNumber ends with + it represents the version in development
|
||||||
|
* after the numbered release.
|
||||||
|
*/
|
||||||
|
inline constexpr char versionNumber[] = tskKERNEL_VERSION_NUMBER;
|
||||||
|
inline constexpr BaseType_t versionMajor = tskKERNEL_VERSION_MAJOR;
|
||||||
|
inline constexpr BaseType_t versionMinor = tskKERNEL_VERSION_MINOR;
|
||||||
|
inline constexpr BaseType_t versionBuild = tskKERNEL_VERSION_BUILD;
|
||||||
|
|
||||||
|
#if (INCLUDE_xTaskGetSchedulerState == 1)
|
||||||
|
/**
|
||||||
|
* Kernel.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>xTaskGetSchedulerState()</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/a00021.html#xTaskGetSchedulerState>
|
||||||
|
*
|
||||||
|
* @retval SchedulerState Returns the scheduler state as Running, NotStarted, or
|
||||||
|
* Suspended.
|
||||||
|
*/
|
||||||
|
inline SchedulerState getSchedulerState() {
|
||||||
|
return static_cast<SchedulerState>(xTaskGetSchedulerState());
|
||||||
|
}
|
||||||
|
#endif /* INCLUDE_xTaskGetSchedulerState */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kernel.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>uxTaskGetNumberOfTasks()</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/a00021.html#usTaskGetNumberOfTasks>
|
||||||
|
*
|
||||||
|
* @retval UBaseType_t The number of tasks that the real time kernel is
|
||||||
|
* currently managing. This includes all ready, blocked and suspended tasks. A
|
||||||
|
* task that has been deleted but not yet freed by the idle task will also be
|
||||||
|
* included in the count.
|
||||||
|
*/
|
||||||
|
inline UBaseType_t getNumberOfTasks() { return uxTaskGetNumberOfTasks(); }
|
||||||
|
|
||||||
|
#if (INCLUDE_xTaskGetIdleTaskHandle == 1 && configGENERATE_RUN_TIME_STATS == 1)
|
||||||
|
/**
|
||||||
|
* Kernel.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>xTaskGetIdleRunTimeCounter()</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/a00021.html#vTaskGetIdleRunTimeCounter>
|
||||||
|
*
|
||||||
|
* @retval TickType_t The run-time counter for the Idle task.
|
||||||
|
*
|
||||||
|
* This function can be used to determine how much CPU time the idle task
|
||||||
|
* receives. See the Run Time Stats page for a full description of the
|
||||||
|
* run-time-stats feature.
|
||||||
|
*
|
||||||
|
* configGENERATE_RUN_TIME_STATS and INCLUDE_xTaskGetIdleTaskHandle must both be
|
||||||
|
* defined as 1 for this function to be available. The application must also
|
||||||
|
* then provide definitions for portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and
|
||||||
|
* portGET_RUN_TIME_COUNTER_VALUE to configure a peripheral timer/counter and
|
||||||
|
* return the timer's current count value respectively. It is recommended to
|
||||||
|
* make the timer at least 10 times the frequency of the tick count.
|
||||||
|
*/
|
||||||
|
inline TickType_t getIdleRunTimeCounter() {
|
||||||
|
return xTaskGetIdleRunTimeCounter();
|
||||||
|
}
|
||||||
|
#endif /* INCLUDE_xTaskGetIdleTaskHandle && configGENERATE_RUN_TIME_STATS*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kernel.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>xTaskGetTickCount()</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/a00021.html#xTaskGetTickCount>
|
||||||
|
*
|
||||||
|
* @retval TickType_t The count of ticks since
|
||||||
|
* FreeRTOS::Kernel::startScheduler() was called.
|
||||||
|
*/
|
||||||
|
inline TickType_t getTickCount() { return xTaskGetTickCount(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kernel.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>xTaskGetTickCountFromISR()</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/a00021.html#xTaskGetTickCountFromISR>
|
||||||
|
*
|
||||||
|
* @retval TickType_t The count of ticks since
|
||||||
|
* FreeRTOS::Kernel::startScheduler() was called.
|
||||||
|
*
|
||||||
|
* This is a version of FreeRTOS::Kernel::getTickCount() that is safe to be
|
||||||
|
* called from an ISR - provided that TickType_t is the natural word size of the
|
||||||
|
* microcontroller being used or interrupt nesting is either not supported or
|
||||||
|
* not being used.
|
||||||
|
*/
|
||||||
|
inline TickType_t getTickCountFromISR() { return xTaskGetTickCountFromISR(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Kernel.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>taskYIELD()</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/a00020.html#taskYIELD>
|
||||||
|
*
|
||||||
|
* FreeRTOS::Kernel::yield() is used to request a context switch to another
|
||||||
|
*task. However, if there are no other tasks at a higher or equal priority to
|
||||||
|
*the task that calls FreeRTOS::Kernel::yield() then the RTOS scheduler will
|
||||||
|
*simply select the task that called FreeRTOS::Kernel::yield() to run again.
|
||||||
|
*/
|
||||||
|
inline void yield() { taskYIELD(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kernel.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>taskENTER_CRITICAL()</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/taskENTER_CRITICAL_taskEXIT_CRITICAL.html>
|
||||||
|
*
|
||||||
|
* Function to mark the start of a critical code region. Preemptive context
|
||||||
|
* switches cannot occur when in a critical region.
|
||||||
|
*
|
||||||
|
* @note This may alter the stack (depending on the portable implementation) so
|
||||||
|
* must be used with care!
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Kernel/enterExitCritical.cpp
|
||||||
|
*/
|
||||||
|
inline void enterCritical() { taskENTER_CRITICAL(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kernel.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>taskENTER_CRITICAL_FROM_ISR()</tt>
|
||||||
|
*
|
||||||
|
* @see
|
||||||
|
* <https://www.freertos.org/taskENTER_CRITICAL_FROM_ISR_taskEXIT_CRITICAL_FROM_ISR.html>
|
||||||
|
*
|
||||||
|
* @retval uint32_t the interrupt mask state as it was before the macro was
|
||||||
|
* called. The value returned by FreeRTOS::Kernel::enterCriticalFromISR() must
|
||||||
|
* be used as the interruptStatus parameter in the matching call to
|
||||||
|
* FreeRTOS::Kernel::exitCriticalFromISR().
|
||||||
|
*
|
||||||
|
* Function to mark the start of a critical code region. Preemptive context
|
||||||
|
* switches cannot occur when in a critical region.
|
||||||
|
*
|
||||||
|
* @note This may alter the stack (depending on the portable implementation) so
|
||||||
|
* must be used with care!
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Kernel/enterExitCriticalFromISR.cpp
|
||||||
|
*/
|
||||||
|
inline uint32_t enterCriticalFromISR() { return taskENTER_CRITICAL_FROM_ISR(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kernel.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>taskEXIT_CRITICAL()</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/taskENTER_CRITICAL_taskEXIT_CRITICAL.html>
|
||||||
|
*
|
||||||
|
* Function to mark the end of a critical code region. Preemptive context
|
||||||
|
* switches cannot occur when in a critical region.
|
||||||
|
*
|
||||||
|
* @note This may alter the stack (depending on the portable implementation) so
|
||||||
|
* must be used with care!
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Kernel/enterExitCritical.cpp
|
||||||
|
*/
|
||||||
|
inline void exitCritical() { taskEXIT_CRITICAL(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kernel.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>taskEXIT_CRITICAL_FROM_ISR()</tt>
|
||||||
|
*
|
||||||
|
* @see
|
||||||
|
* <https://www.freertos.org/taskENTER_CRITICAL_FROM_ISR_taskEXIT_CRITICAL_FROM_ISR.html>
|
||||||
|
*
|
||||||
|
* @param interruptStatus The value used as the interruptStatus parameter must
|
||||||
|
* be the value returned from the matching call to
|
||||||
|
* FreeRTOS::Kernel::enterCriticalFromISR().
|
||||||
|
*
|
||||||
|
* Function to mark the end of a critical code region. Preemptive context
|
||||||
|
* switches cannot occur when in a critical region.
|
||||||
|
*
|
||||||
|
* @note This may alter the stack (depending on the portable implementation) so
|
||||||
|
* must be used with care!
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Kernel/enterExitCriticalFromISR.cpp
|
||||||
|
*/
|
||||||
|
inline void exitCriticalFromISR(const uint32_t interruptStatus) {
|
||||||
|
taskEXIT_CRITICAL_FROM_ISR(interruptStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kernel.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>taskDISABLE_INTERRUPTS()</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/a00020.html#taskDISABLE_INTERRUPTS>
|
||||||
|
*
|
||||||
|
* Function to disable all maskable interrupts.
|
||||||
|
*/
|
||||||
|
inline void disableInterrupts() { taskDISABLE_INTERRUPTS(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kernel.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>taskENABLE_INTERRUPTS()</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/a00020.html#taskENABLE_INTERRUPTS>
|
||||||
|
*
|
||||||
|
* Function to enable microcontroller interrupts.
|
||||||
|
*/
|
||||||
|
inline void enableInterrupts() { taskENABLE_INTERRUPTS(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kernel.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>vTaskStartScheduler()</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/a00132.html>
|
||||||
|
*
|
||||||
|
* Starts the real time kernel tick processing. After calling the kernel has
|
||||||
|
* control over which tasks are executed and when.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Kernel/startScheduler.cpp
|
||||||
|
*/
|
||||||
|
inline void startScheduler() { vTaskStartScheduler(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kernel.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>vTaskEndScheduler()</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/a00133.html>
|
||||||
|
*
|
||||||
|
* @note At the time of writing only the x86 real mode port, which runs on a PC
|
||||||
|
* in place of DOS, implements this function.
|
||||||
|
*
|
||||||
|
* Stops the real time kernel tick. All created tasks will be automatically
|
||||||
|
* deleted and multitasking (either preemptive or cooperative) will stop.
|
||||||
|
* Execution then resumes from the point where
|
||||||
|
* FreeRTOS::Kernel::startScheduler() was called, as if
|
||||||
|
* FreeRTOS::Kernel::startScheduler() had just returned.
|
||||||
|
*
|
||||||
|
* See the demo application file main. c in the demo/PC directory for an example
|
||||||
|
* that uses FreeRTOS::Kernel::endScheduler().
|
||||||
|
*
|
||||||
|
* FreeRTOS::Kernel::endScheduler() requires an exit function to be defined
|
||||||
|
* within the portable layer (see vPortEndScheduler () in port. c for the PC
|
||||||
|
* port). This performs hardware specific operations such as stopping the
|
||||||
|
* kernel tick.
|
||||||
|
*
|
||||||
|
* FreeRTOS::Kernel::endScheduler() will cause all of the resources allocated by
|
||||||
|
* the kernel to be freed - but will not free resources allocated by application
|
||||||
|
* tasks.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Kernel/endScheduler.cpp
|
||||||
|
*/
|
||||||
|
inline void endScheduler() { vTaskEndScheduler(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kernel.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>vTaskSuspendAll()</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/a00134.html>
|
||||||
|
*
|
||||||
|
* Suspends the scheduler without disabling interrupts. Context switches will
|
||||||
|
* not occur while the scheduler is suspended.
|
||||||
|
*
|
||||||
|
* After calling FreeRTOS::Kernel::suspendAll() the calling task will continue
|
||||||
|
* to execute without risk of being swapped out until a call to
|
||||||
|
* FreeRTOS::Kernel::resumeAll() has been made.
|
||||||
|
*
|
||||||
|
* API functions that have the potential to cause a context switch (for example,
|
||||||
|
* FreeRTOS::Task::delayUntil(), FreeRTOS::Queue::send(), etc.) must not be
|
||||||
|
* called while the scheduler is suspended.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Kernel/suspendAll.cpp
|
||||||
|
*/
|
||||||
|
inline void suspendAll() { vTaskSuspendAll(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kernel.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>xTaskResumeAll()</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/a00135.html>
|
||||||
|
*
|
||||||
|
* Resumes scheduler activity after it was suspended by a call to
|
||||||
|
* FreeRTOS::Kernel::suspendAll().
|
||||||
|
*
|
||||||
|
* FreeRTOS::Kernel::resumeAll() only resumes the scheduler. It does not
|
||||||
|
* unsuspend tasks that were previously suspended by a call to
|
||||||
|
* FreeRTOS::Task::suspend().
|
||||||
|
*
|
||||||
|
* @retval true If resuming the scheduler caused a context switch.
|
||||||
|
* @retval false Otherwise.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Kernel/resumeAll.cpp
|
||||||
|
*/
|
||||||
|
inline bool resumeAll() { return (xTaskResumeAll() == pdTRUE); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kernel.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>vTaskStepTick( const TickType_t xTicksToJump
|
||||||
|
* )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/vTaskStepTick.html>
|
||||||
|
*
|
||||||
|
* Only available when configUSE_TICKLESS_IDLE is set to 1. If tickless mode is
|
||||||
|
* being used, or a low power mode is implemented, then the tick interrupt will
|
||||||
|
* not execute during idle periods. When this is the case, the tick count value
|
||||||
|
* maintained by the scheduler needs to be kept up to date with the actual
|
||||||
|
* execution time by being skipped forward by a time equal to the idle period.
|
||||||
|
*
|
||||||
|
* @param ticksToJump The number of RTOS ticks that have passed since the tick
|
||||||
|
* interrupt was stopped.
|
||||||
|
*/
|
||||||
|
inline void stepTick(const TickType_t ticksToJump) {
|
||||||
|
//vTaskStepTick(ticksToJump);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kernel.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>xTaskCatchUpTicks( TickType_t xTicksToCatchUp
|
||||||
|
* )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/vTaskStepTick.html>
|
||||||
|
*
|
||||||
|
* This function corrects the tick count value after the application code has
|
||||||
|
* held interrupts disabled for an extended period resulting in tick interrupts
|
||||||
|
* having been missed.
|
||||||
|
*
|
||||||
|
* This function is similar to FreeRTOS::Kernel::stepTick(), however, unlike
|
||||||
|
* FreeRTOS::Kernel::stepTick(), FreeRTOS::Kernel::catchUpTicks() may move the
|
||||||
|
* tick count forward past a time at which a task should be removed from the
|
||||||
|
* blocked state. That means tasks may have to be removed from the blocked
|
||||||
|
* state as the tick count is moved.
|
||||||
|
*
|
||||||
|
* @param ticksToCatchUp The number of tick interrupts that have been missed due
|
||||||
|
* to interrupts being disabled. Its value is not computed automatically, so
|
||||||
|
* must be computed by the application writer.
|
||||||
|
*
|
||||||
|
* @retval true If moving the tick count forward resulted in a task leaving the
|
||||||
|
* blocked state and a context switch being performed.
|
||||||
|
* @retval false Otherwise.
|
||||||
|
*/
|
||||||
|
inline bool catchUpTicks(const TickType_t ticksToCatchUp) {
|
||||||
|
return (xTaskCatchUpTicks(ticksToCatchUp) == pdTRUE);
|
||||||
|
}
|
||||||
|
} // namespace Kernel
|
||||||
|
|
||||||
|
} // namespace FreeRTOS
|
||||||
|
|
||||||
|
#endif // FREERTOS_KERNEL_HPP
|
|
@ -0,0 +1,518 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS-Cpp
|
||||||
|
* Copyright (C) 2021 Jon Enz. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://github.com/jonenz/FreeRTOS-Cpp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FREERTOS_MESSAGEBUFFER_HPP
|
||||||
|
#define FREERTOS_MESSAGEBUFFER_HPP
|
||||||
|
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "message_buffer.h"
|
||||||
|
|
||||||
|
namespace FreeRTOS {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class MessageBufferBase MessageBuffer.hpp <FreeRTOS/MessageBuffer.hpp>
|
||||||
|
*
|
||||||
|
* @brief Base class that provides the standard message buffer interface to
|
||||||
|
* FreeRTOS::MessageBuffer and FreeRTOS::StaticMessageBuffer.
|
||||||
|
*
|
||||||
|
* @note This class is not intended to be instantiated by the user. Use
|
||||||
|
* FreeRTOS::MessageBuffer or FreeRTOS::StaticMessageBuffer.
|
||||||
|
*
|
||||||
|
* @warning Uniquely among FreeRTOS objects, the stream buffer implementation
|
||||||
|
* (so also the message buffer implementation, as message buffers are built on
|
||||||
|
* top of stream buffers) assumes there is only one task or interrupt that will
|
||||||
|
* write to the buffer (the writer), and only one task or interrupt that will
|
||||||
|
* read from the buffer (the reader). It is safe for the writer and reader to
|
||||||
|
* be different tasks or interrupts, but, unlike other FreeRTOS objects, it is
|
||||||
|
* not safe to have multiple different writers or multiple different readers. If
|
||||||
|
* there are to be multiple different writers then the application writer must
|
||||||
|
* place each call to a writing API function (such as send()) inside a critical
|
||||||
|
* section and set the send block time to 0. Likewise, if there are to be
|
||||||
|
* multiple different readers then the application writer must place each call
|
||||||
|
* to a reading API function (such as read()) inside a critical section and set
|
||||||
|
* the receive block time to 0.
|
||||||
|
*/
|
||||||
|
class MessageBufferBase {
|
||||||
|
public:
|
||||||
|
friend class MessageBuffer;
|
||||||
|
template <size_t>
|
||||||
|
friend class StaticMessageBuffer;
|
||||||
|
|
||||||
|
MessageBufferBase(const MessageBufferBase&) = delete;
|
||||||
|
MessageBufferBase& operator=(const MessageBufferBase&) = delete;
|
||||||
|
|
||||||
|
static void* operator new(size_t, void* ptr) { return ptr; }
|
||||||
|
static void* operator new[](size_t, void* ptr) { return ptr; }
|
||||||
|
static void* operator new(size_t) = delete;
|
||||||
|
static void* operator new[](size_t) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MessageBuffer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that checks if the underlying message buffer handle is not
|
||||||
|
* NULL. This should be used to ensure a message buffer has been created
|
||||||
|
* correctly.
|
||||||
|
*
|
||||||
|
* @retval true If the handle is not NULL.
|
||||||
|
* @retval false If the handle is NULL.
|
||||||
|
*/
|
||||||
|
inline bool isValid() const { return (handle != NULL); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MessageBuffer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>size_t xMessageBufferSend(
|
||||||
|
* MessageBufferHandle_t xMessageBuffer, const void *pvTxData, size_t
|
||||||
|
* xDataLengthBytes, TickType_t xTicksToWait )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xMessageBufferSend.html>
|
||||||
|
*
|
||||||
|
* Sends a discrete message to the message buffer. The message can be any
|
||||||
|
* length that fits within the buffer's free space, and is copied into the
|
||||||
|
* buffer.
|
||||||
|
*
|
||||||
|
* Use send() to write to a message buffer from a task. Use sendFromISR() to
|
||||||
|
* write to a message buffer from an interrupt service routine (ISR).
|
||||||
|
*
|
||||||
|
* @param data A pointer to the message that is to be copied into the message
|
||||||
|
* buffer.
|
||||||
|
* @param length The length of the message. That is, the number of bytes to
|
||||||
|
* copy from data into the message buffer. When a message is written to the
|
||||||
|
* message buffer an additional sizeof( size_t ) bytes are also written to
|
||||||
|
* store the message's length. sizeof( size_t ) is typically 4 bytes on a
|
||||||
|
* 32-bit architecture, so on most 32-bit architecture setting length to 20
|
||||||
|
* will reduce the free space in the message buffer by 24 bytes (20 bytes of
|
||||||
|
* message data and 4 bytes to hold the message length).
|
||||||
|
* @param ticksToWait The maximum amount of time the calling task should
|
||||||
|
* remain in the Blocked state to wait for enough space to become available in
|
||||||
|
* the message buffer, should the message buffer have insufficient space when
|
||||||
|
* send() is called. The calling task will never block if ticksToWait is
|
||||||
|
* zero. The block time is specified in tick periods, so the absolute time it
|
||||||
|
* represents is dependent on the tick frequency. The macro pdMS_TO_TICKS()
|
||||||
|
* can be used to convert a time specified in milliseconds into a time
|
||||||
|
* specified in ticks. Setting ticksToWait to portMAX_DELAY will cause the
|
||||||
|
* task to wait indefinitely (without timing out), provided
|
||||||
|
* INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. Tasks do not use any
|
||||||
|
* CPU time when they are in the Blocked state.
|
||||||
|
* @return size_t The number of bytes written to the message buffer. If the
|
||||||
|
* call to send() times out before there was enough space to write the message
|
||||||
|
* into the message buffer then zero is returned. If the call did not time
|
||||||
|
* out then length is returned.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include MessageBuffer/send.cpp
|
||||||
|
*/
|
||||||
|
inline size_t send(const void* data, const size_t length,
|
||||||
|
const TickType_t ticksToWait = portMAX_DELAY) const {
|
||||||
|
return xMessageBufferSend(handle, data, length, ticksToWait);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MessageBuffer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>size_t xMessageBufferSendFromISR(
|
||||||
|
* MessageBufferHandle_t xMessageBuffer, const void *pvTxData, size_t
|
||||||
|
* xDataLengthBytes, BaseType_t *pxHigherPriorityTaskWoken )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xMessageBufferSendFromISR.html>
|
||||||
|
*
|
||||||
|
* Interrupt safe version of the API function that sends a discrete message to
|
||||||
|
* the message buffer. The message can be any length that fits within the
|
||||||
|
* buffer's free space, and is copied into the buffer.
|
||||||
|
*
|
||||||
|
* Use send() to write to a message buffer from a task. Use sendFromISR() to
|
||||||
|
* write to a message buffer from an interrupt service routine (ISR).
|
||||||
|
*
|
||||||
|
* @param higherPriorityTaskWoken It is possible that a message buffer will
|
||||||
|
* have a task blocked on it waiting for data. Calling sendFromISR() can make
|
||||||
|
* data available, and so cause a task that was waiting for data to leave the
|
||||||
|
* Blocked state. If calling sendFromISR() causes a task to leave the Blocked
|
||||||
|
* state, and the unblocked task has a priority higher than the currently
|
||||||
|
* executing task (the task that was interrupted), then, internally,
|
||||||
|
* sendFromISR() will set higherPriorityTaskWoken to true. If sendFromISR()
|
||||||
|
* sets this value to true, then normally a context switch should be performed
|
||||||
|
* before the interrupt is exited. This will ensure that the interrupt returns
|
||||||
|
* directly to the highest priority Ready state task. higherPriorityTaskWoken
|
||||||
|
* should be set to false before it is passed into the function. See the code
|
||||||
|
* example below for an example.
|
||||||
|
* @param data A pointer to the message that is to be copied into the message
|
||||||
|
* buffer.
|
||||||
|
* @param length The length of the message. That is, the number of bytes to
|
||||||
|
* copy from data into the message buffer. When a message is written to the
|
||||||
|
* message buffer an additional sizeof( size_t ) bytes are also written to
|
||||||
|
* store the message's length. sizeof( size_t ) is typically 4 bytes on a
|
||||||
|
* 32-bit architecture, so on most 32-bit architecture setting length to 20
|
||||||
|
* will reduce the free space in the message buffer by 24 bytes (20 bytes of
|
||||||
|
* message data and 4 bytes to hold the message length).
|
||||||
|
* @return size_t The number of bytes actually written to the message buffer.
|
||||||
|
* If the message buffer didn't have enough free space for the message to be
|
||||||
|
* stored then 0 is returned, otherwise length is returned.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include MessageBuffer/sendFromISR.cpp
|
||||||
|
*/
|
||||||
|
inline size_t sendFromISR(bool& higherPriorityTaskWoken, const void* data,
|
||||||
|
const size_t length) const {
|
||||||
|
BaseType_t taskWoken = pdFALSE;
|
||||||
|
size_t result = xMessageBufferSendFromISR(handle, data, length, &taskWoken);
|
||||||
|
if (taskWoken == pdTRUE) {
|
||||||
|
higherPriorityTaskWoken = true;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MessageBuffer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>size_t xMessageBufferSendFromISR(
|
||||||
|
* MessageBufferHandle_t xMessageBuffer, const void *pvTxData, size_t
|
||||||
|
* xDataLengthBytes, BaseType_t *pxHigherPriorityTaskWoken )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xMessageBufferSendFromISR.html>
|
||||||
|
*
|
||||||
|
* @overload
|
||||||
|
*/
|
||||||
|
inline size_t sendFromISR(const void* data, const size_t length) const {
|
||||||
|
return xMessageBufferSendFromISR(handle, data, length, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MessageBuffer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>size_t xMessageBufferReceive(
|
||||||
|
* MessageBufferHandle_t xMessageBuffer, void *pvRxData, size_t
|
||||||
|
* xBufferLengthBytes, TickType_t xTicksToWait )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xMessageBufferReceive.html>
|
||||||
|
*
|
||||||
|
* Use receive() to read from a message buffer from a task.
|
||||||
|
* UsereceiveFromISR() to read from a message buffer from an interrupt service
|
||||||
|
* routine (ISR).
|
||||||
|
*
|
||||||
|
* @param buffer A pointer to the buffer into which the received message is to
|
||||||
|
* be copied.
|
||||||
|
* @param bufferLength The length of the buffer pointed to by the buffer
|
||||||
|
* parameter. This sets the maximum length of the message that can be
|
||||||
|
* received. If bufferLength is too small to hold the next message then the
|
||||||
|
* message will be left in the message buffer and 0 will be returned.
|
||||||
|
* @param ticksToWait The maximum amount of time the task should remain in the
|
||||||
|
* Blocked state to wait for a message, should the message buffer be empty.
|
||||||
|
* receive() will return immediately if ticksToWait is zero and the message
|
||||||
|
* buffer is empty. The block time is specified in tick periods, so the
|
||||||
|
* absolute time it represents is dependent on the tick frequency. The macro
|
||||||
|
* pdMS_TO_TICKS() can be used to convert a time specified in milliseconds
|
||||||
|
* into a time specified in ticks. Setting ticksToWait to portMAX_DELAY will
|
||||||
|
* cause the task to wait indefinitely (without timing out), provided
|
||||||
|
* INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. Tasks do not use any
|
||||||
|
* CPU time when they are in the Blocked state.
|
||||||
|
* @return size_t The length, in bytes, of the message read from the message
|
||||||
|
* buffer, if any. If receive() times out before a message became available
|
||||||
|
* then zero is returned. If the length of the message is greater than
|
||||||
|
* bufferLength then the message will be left in the message buffer and zero
|
||||||
|
* is returned.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include MessageBuffer/receive.cpp
|
||||||
|
*/
|
||||||
|
inline size_t receive(void* buffer, const size_t bufferLength,
|
||||||
|
const TickType_t ticksToWait = portMAX_DELAY) const {
|
||||||
|
return xMessageBufferReceive(handle, buffer, bufferLength, ticksToWait);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MessageBuffer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>size_t xMessageBufferReceiveFromISR(
|
||||||
|
* MessageBufferHandle_t xMessageBuffer, void *pvRxData, size_t
|
||||||
|
* xBufferLengthBytes, BaseType_t *pxHigherPriorityTaskWoken )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xMessageBufferReceiveFromISR.html>
|
||||||
|
*
|
||||||
|
* Use receive() to read from a message buffer from a task.
|
||||||
|
* UsereceiveFromISR() to read from a message buffer from an interrupt service
|
||||||
|
* routine (ISR).
|
||||||
|
*
|
||||||
|
* @param higherPriorityTaskWoken It is possible that a message buffer will
|
||||||
|
* have a task blocked on it waiting for space to become available. Calling
|
||||||
|
* receiveFromISR() can make space available, and so cause a task that is
|
||||||
|
* waiting for space to leave the Blocked state. If calling receiveFromISR()
|
||||||
|
* causes a task to leave the Blocked state, and the unblocked task has a
|
||||||
|
* priority higher than the currently executing task (the task that was
|
||||||
|
* interrupted), then, internally, receiveFromISR() will set
|
||||||
|
* higherPriorityTaskWoken to true. If receiveFromISR() sets this value to
|
||||||
|
* true, then normally a context switch should be performed before the
|
||||||
|
* interrupt is exited. That will ensure the interrupt returns directly to the
|
||||||
|
* highest priority Ready state task. higherPriorityTaskWoken should be set
|
||||||
|
* to false before it is passed into the function. See the code example below
|
||||||
|
* for an example.
|
||||||
|
* @param buffer A pointer to the buffer into which the received message is to
|
||||||
|
* be copied.
|
||||||
|
* @param bufferLength The length of the buffer pointed to by the buffer
|
||||||
|
* parameter. This sets the maximum length of the message that can be
|
||||||
|
* received. If bufferLength is too small to hold the next message then the
|
||||||
|
* message will be left in the message buffer and 0 will be returned.
|
||||||
|
* @return size_t The length, in bytes, of the message read from the message
|
||||||
|
* buffer, if any.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include MessageBuffer/receiveFromISR.cpp
|
||||||
|
*/
|
||||||
|
inline size_t receiveFromISR(bool& higherPriorityTaskWoken, void* buffer,
|
||||||
|
const size_t bufferLength) const {
|
||||||
|
BaseType_t taskWoken = pdFALSE;
|
||||||
|
size_t result =
|
||||||
|
xMessageBufferReceiveFromISR(handle, buffer, bufferLength, &taskWoken);
|
||||||
|
if (taskWoken == pdTRUE) {
|
||||||
|
higherPriorityTaskWoken = true;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MessageBuffer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>size_t xMessageBufferReceiveFromISR(
|
||||||
|
* MessageBufferHandle_t xMessageBuffer, void *pvRxData, size_t
|
||||||
|
* xBufferLengthBytes, BaseType_t *pxHigherPriorityTaskWoken )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xMessageBufferReceiveFromISR.html>
|
||||||
|
*
|
||||||
|
* @overload
|
||||||
|
*/
|
||||||
|
inline size_t receiveFromISR(void* buffer, const size_t bufferLength) const {
|
||||||
|
return xMessageBufferReceiveFromISR(handle, buffer, bufferLength, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MessageBuffer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>size_t xMessageBufferSpacesAvailable(
|
||||||
|
* MessageBufferHandle_t xMessageBuffer )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xMessageBufferSpacesAvailable.html>
|
||||||
|
*
|
||||||
|
* Queries a message buffer to see how much free space it contains, which is
|
||||||
|
* equal to the amount of data that can be sent to the message buffer before
|
||||||
|
* it is full. The returned value is 4 bytes larger than the maximum message
|
||||||
|
* size that can be sent to the message buffer.
|
||||||
|
*
|
||||||
|
* @return size_t The number of bytes that can be written to the message
|
||||||
|
* buffer before the message buffer would be full. When a message is written
|
||||||
|
* to the message buffer an additional sizeof( size_t ) bytes are also written
|
||||||
|
* to store the message's length. sizeof( size_t ) is typically 4 bytes on a
|
||||||
|
* 32-bit architecture, so if spacesAvailable() returns 10, then the size of
|
||||||
|
* the largest message that can be written to the message buffer is 6 bytes.
|
||||||
|
*/
|
||||||
|
inline size_t spacesAvailable() const {
|
||||||
|
return xMessageBufferSpacesAvailable(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MessageBuffer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>BaseType_t xMessageBufferReset(
|
||||||
|
* MessageBufferHandle_t xMessageBuffer )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xMessageBufferReset.html>
|
||||||
|
*
|
||||||
|
* Resets a message buffer to its initial, empty, state. Any data that was in
|
||||||
|
* the message buffer is discarded. A message buffer can only be reset if
|
||||||
|
* there are no tasks blocked waiting to either send to or receive from the
|
||||||
|
* message buffer.
|
||||||
|
*
|
||||||
|
* @retval true If the message buffer is reset.
|
||||||
|
* @retval false If there was a task blocked waiting to send to or read from
|
||||||
|
* the message buffer then the message buffer will not be reset.
|
||||||
|
*/
|
||||||
|
inline bool reset() const { return (xMessageBufferReset(handle) == pdPASS); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MessageBuffer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>BaseType_t xMessageBufferIsEmpty(
|
||||||
|
* MessageBufferHandle_t xMessageBuffer )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xMessageBufferIsEmpty.html>
|
||||||
|
*
|
||||||
|
* Queries a message buffer to see if it is empty. A message buffer is empty
|
||||||
|
* if it does not contain any messages.
|
||||||
|
*
|
||||||
|
* @retval true If the message buffer is empty.
|
||||||
|
* @retval false Otherwise.
|
||||||
|
*/
|
||||||
|
inline bool isEmpty() const {
|
||||||
|
return (xMessageBufferIsEmpty(handle) == pdTRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MessageBuffer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>BaseType_t xMessageBufferIsFull(
|
||||||
|
* MessageBufferHandle_t xMessageBuffer )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xMessageBufferIsFull.html>
|
||||||
|
*
|
||||||
|
* Queries a message buffer to see if it is full. A message buffer is full if
|
||||||
|
* it cannot accept any more messages, of any size, until space is made
|
||||||
|
* available by a message being removed from the message buffer.
|
||||||
|
*
|
||||||
|
* @retval true If the message buffer is full.
|
||||||
|
* @retval false Otherwise.
|
||||||
|
*/
|
||||||
|
inline bool isFull() const {
|
||||||
|
return (xMessageBufferIsFull(handle) == pdTRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
MessageBufferBase() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MessageBuffer.hpp
|
||||||
|
*
|
||||||
|
* @brief Destroy the MessageBufferBase object by calling <tt>void
|
||||||
|
* vMessageBufferDelete( MessageBufferHandle_t xMessageBuffer )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/vMessageBufferDelete.html>
|
||||||
|
*
|
||||||
|
* Delete a queue - freeing all the memory allocated for storing of items
|
||||||
|
* placed on the queue.
|
||||||
|
*/
|
||||||
|
~MessageBufferBase() { vMessageBufferDelete(this->handle); }
|
||||||
|
|
||||||
|
MessageBufferBase(MessageBufferBase&&) noexcept = default;
|
||||||
|
MessageBufferBase& operator=(MessageBufferBase&&) noexcept = default;
|
||||||
|
|
||||||
|
MessageBufferHandle_t handle = NULL;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class MessageBuffer MessageBuffer.hpp <FreeRTOS/MessageBuffer.hpp>
|
||||||
|
*
|
||||||
|
* @brief Class that encapsulates the functionality of a FreeRTOS message
|
||||||
|
* buffer.
|
||||||
|
*
|
||||||
|
* A message buffer using dynamically allocated memory from the FreeRTOS heap.
|
||||||
|
* See FreeRTOS::StaticMessageBuffer for a version that uses statically
|
||||||
|
* allocated memory (memory that is allocated at compile time).
|
||||||
|
*/
|
||||||
|
class MessageBuffer : public MessageBufferBase {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* MessageBuffer.hpp
|
||||||
|
*
|
||||||
|
* @brief Construct a new MessageBuffer object by calling
|
||||||
|
* <tt>MessageBufferHandle_t xMessageBufferCreate( size_t xBufferSizeBytes
|
||||||
|
* )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xMessageBufferCreate.html>
|
||||||
|
*
|
||||||
|
* @warning The user should call isValid() on this object to verify that the
|
||||||
|
* message buffer was created successfully in case the memory required to
|
||||||
|
* create the message buffer could not be allocated.
|
||||||
|
*
|
||||||
|
* @param size The total number of bytes (not messages) the message buffer
|
||||||
|
* will be able to hold at any one time. When a message is written to the
|
||||||
|
* message buffer an additional sizeof( size_t ) bytes are also written to
|
||||||
|
* store the message's length. sizeof( size_t ) is typically 4 bytes on a
|
||||||
|
* 32-bit architecture, so on most 32-bit architectures a 10 byte message will
|
||||||
|
* take up 14 bytes of message buffer space.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include MessageBuffer/messageBuffer.cpp
|
||||||
|
*/
|
||||||
|
explicit MessageBuffer(size_t size) {
|
||||||
|
this->handle = xMessageBufferCreate(size);
|
||||||
|
}
|
||||||
|
~MessageBuffer() = default;
|
||||||
|
|
||||||
|
MessageBuffer(const MessageBuffer&) = delete;
|
||||||
|
MessageBuffer& operator=(const MessageBuffer&) = delete;
|
||||||
|
|
||||||
|
MessageBuffer(MessageBuffer&&) noexcept = default;
|
||||||
|
MessageBuffer& operator=(MessageBuffer&&) noexcept = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||||
|
|
||||||
|
#if (configSUPPORT_STATIC_ALLOCATION == 1)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class StaticMessageBuffer MessageBuffer.hpp <FreeRTOS/MessageBuffer.hpp>
|
||||||
|
*
|
||||||
|
* @brief Class that encapsulates the functionality of a FreeRTOS message
|
||||||
|
* buffer.
|
||||||
|
*
|
||||||
|
* If a message buffer is created using this class then the RAM is provided by
|
||||||
|
* the application writer as part of the object instance and allows the RAM to
|
||||||
|
* be statically allocated at compile time.
|
||||||
|
*
|
||||||
|
* @tparam N The size, in bytes, of the storage for the message buffer.
|
||||||
|
*/
|
||||||
|
template <size_t N>
|
||||||
|
class StaticMessageBuffer : public MessageBufferBase {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* MessageBuffer.hpp
|
||||||
|
*
|
||||||
|
* @brief Construct a new StaticMessageBuffer object by calling
|
||||||
|
* <tt>MessageBufferHandle_t xMessageBufferCreateStatic( size_t
|
||||||
|
* xBufferSizeBytes, uint8_t *pucMessageBufferStorageArea,
|
||||||
|
* StaticMessageBuffer_t *pxStaticMessageBuffer )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xMessageBufferCreateStatic.html>
|
||||||
|
*
|
||||||
|
* @warning This class contains the storage buffer for the message buffer, so
|
||||||
|
* the user should create this object as a global object or with the static
|
||||||
|
* storage specifier so that the object instance is not on the stack.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include MessageBuffer/staticMessageBuffer.cpp
|
||||||
|
*/
|
||||||
|
StaticMessageBuffer() : MessageBufferBase() {
|
||||||
|
this->handle = xMessageBufferCreateStatic(sizeof(storage), storage,
|
||||||
|
&staticMessageBuffer);
|
||||||
|
}
|
||||||
|
~StaticMessageBuffer() = default;
|
||||||
|
|
||||||
|
StaticMessageBuffer(const StaticMessageBuffer&) = delete;
|
||||||
|
StaticMessageBuffer& operator=(const StaticMessageBuffer&) = delete;
|
||||||
|
|
||||||
|
StaticMessageBuffer(StaticMessageBuffer&&) noexcept = default;
|
||||||
|
StaticMessageBuffer& operator=(StaticMessageBuffer&&) noexcept = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
StaticMessageBuffer_t staticMessageBuffer;
|
||||||
|
uint8_t storage[N] = {0};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||||
|
|
||||||
|
} // namespace FreeRTOS
|
||||||
|
|
||||||
|
#endif // FREERTOS_MESSAGEBUFFER_HPP
|
|
@ -0,0 +1,495 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS-Cpp
|
||||||
|
* Copyright (C) 2021 Jon Enz. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://github.com/jonenz/FreeRTOS-Cpp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FREERTOS_MUTEX_HPP
|
||||||
|
#define FREERTOS_MUTEX_HPP
|
||||||
|
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "semphr.h"
|
||||||
|
|
||||||
|
namespace FreeRTOS {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class MutexBase Mutex.hpp <FreeRTOS/Mutex.hpp>
|
||||||
|
*
|
||||||
|
* @brief Base class that provides the standard mutex interface to
|
||||||
|
* FreeRTOS::Mutex, FreeRTOS::StaticMutex, FreeRTOS::RecursiveMutex, and
|
||||||
|
* FreeRTOS::StaticRecursiveMutex.
|
||||||
|
*
|
||||||
|
* @note This class is not intended to be instantiated by the user. Use
|
||||||
|
* FreeRTOS::Mutex, FreeRTOS::StaticMutex, FreeRTOS::RecursiveMutex, and
|
||||||
|
* FreeRTOS::StaticRecursiveMutex.
|
||||||
|
*/
|
||||||
|
class MutexBase {
|
||||||
|
public:
|
||||||
|
friend class Mutex;
|
||||||
|
friend class StaticMutex;
|
||||||
|
friend class RecursiveMutexBase;
|
||||||
|
friend class RecursiveMutex;
|
||||||
|
friend class StaticRecursiveMutex;
|
||||||
|
|
||||||
|
MutexBase(const MutexBase&) = delete;
|
||||||
|
MutexBase& operator=(const MutexBase&) = delete;
|
||||||
|
|
||||||
|
static void* operator new(size_t, void* ptr) { return ptr; }
|
||||||
|
static void* operator new[](size_t, void* ptr) { return ptr; }
|
||||||
|
static void* operator new(size_t) = delete;
|
||||||
|
static void* operator new[](size_t) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mutex.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that checks if the underlying semaphore handle is not NULL.
|
||||||
|
* This should be used to ensure a semaphore has been created correctly.
|
||||||
|
*
|
||||||
|
* @retval true the handle is not NULL.
|
||||||
|
* @retval false the handle is NULL.
|
||||||
|
*/
|
||||||
|
inline bool isValid() const { return (handle != NULL); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mutex.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>xSemaphoreTake( SemaphoreHandle_t
|
||||||
|
* xSemaphore, TickType_t xTicksToWait )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/a00122.html>
|
||||||
|
*
|
||||||
|
* @param ticksToWait The time in ticks to wait for the mutex to become
|
||||||
|
* available. The macro portTICK_PERIOD_MS can be used to convert this to a
|
||||||
|
* real time. A block time of zero can be used to poll the mutex.
|
||||||
|
* @retval true If the mutex was locked.
|
||||||
|
* @retval false If ticksToWait expired without the mutex becoming available.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Mutex/lock.cpp
|
||||||
|
*/
|
||||||
|
inline bool lock(const TickType_t ticksToWait = portMAX_DELAY) const {
|
||||||
|
return (xSemaphoreTake(handle, ticksToWait) == pdTRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mutex.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>xSemaphoreTakeFromISR ( SemaphoreHandle_t
|
||||||
|
* xSemaphore, signed BaseType_t *pxHigherPriorityTaskWoken )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xSemaphoreTakeFromISR.html>
|
||||||
|
*
|
||||||
|
* @param higherPriorityTaskWoken It is possible (although unlikely, and
|
||||||
|
* dependent on the semaphore type) that a mutex will have one or more tasks
|
||||||
|
* blocked on it waiting to give the mutex. Calling lockFromISR() will make a
|
||||||
|
* task that was blocked waiting to give the mutex leave the Blocked state. If
|
||||||
|
* calling the API function causes a task to leave the Blocked state, and the
|
||||||
|
* unblocked task has a priority equal to or higher than the currently
|
||||||
|
* executing task (the task that was interrupted), then, internally, the API
|
||||||
|
* function will set higherPriorityTaskWoken to true.
|
||||||
|
* @return true If the mutex was successfully locked.
|
||||||
|
* @return false If the mutex was not successfully locked because it was not
|
||||||
|
* available.
|
||||||
|
*/
|
||||||
|
inline bool lockFromISR(bool& higherPriorityTaskWoken) const {
|
||||||
|
BaseType_t taskWoken = pdFALSE;
|
||||||
|
bool result = (xSemaphoreTakeFromISR(handle, &taskWoken) == pdTRUE);
|
||||||
|
if (taskWoken == pdTRUE) {
|
||||||
|
higherPriorityTaskWoken = true;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mutex.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>xSemaphoreTakeFromISR ( SemaphoreHandle_t
|
||||||
|
* xSemaphore, signed BaseType_t *pxHigherPriorityTaskWoken )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xSemaphoreTakeFromISR.html>
|
||||||
|
*
|
||||||
|
* @overload
|
||||||
|
*/
|
||||||
|
inline bool lockFromISR() const {
|
||||||
|
return (xSemaphoreTakeFromISR(handle, NULL) == pdTRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mutex.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>xSemaphoreGive( SemaphoreHandle_t xSemaphore
|
||||||
|
* )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/a00123.html>
|
||||||
|
*
|
||||||
|
* @warning This must not be used from an ISR.
|
||||||
|
*
|
||||||
|
* @return true If the mutex was unlocked.
|
||||||
|
* @return false If an error occurred. Mutexes (semaphores) are implemented
|
||||||
|
* using queues. An error can occur if there is no space on the queue to post
|
||||||
|
* a message indicating that the mutex was not first locked correctly.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Mutex/unlock.cpp
|
||||||
|
*/
|
||||||
|
inline bool unlock() const { return (xSemaphoreGive(handle) == pdTRUE); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
MutexBase() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mutex.hpp
|
||||||
|
*
|
||||||
|
* @brief Destroy the MutexBase object by calling <tt>void vSemaphoreDelete(
|
||||||
|
* SemaphoreHandle_t xSemaphore )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/a00113.html#vSemaphoreDelete>
|
||||||
|
*
|
||||||
|
* @note Do not delete a mutex that has tasks blocked on it (tasks that are in
|
||||||
|
* the Blocked state waiting for the mutex to become available).
|
||||||
|
*/
|
||||||
|
~MutexBase() { vSemaphoreDelete(this->handle); }
|
||||||
|
|
||||||
|
MutexBase(MutexBase&&) noexcept = default;
|
||||||
|
MutexBase& operator=(MutexBase&&) noexcept = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Handle used to refer to the semaphore when using the FreeRTOS
|
||||||
|
* interface.
|
||||||
|
*/
|
||||||
|
SemaphoreHandle_t handle = NULL;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class RecursiveMutexBase Mutex.hpp <FreeRTOS/Mutex.hpp>
|
||||||
|
*
|
||||||
|
* @brief Base class that provides the recursive mutex interface to
|
||||||
|
* FreeRTOS::RecursiveMutex and FreeRTOS::StaticRecursiveMutex. This class
|
||||||
|
* exists to override the lock() and unlock() functions which require different
|
||||||
|
* underlying functions from what is used in FreeRTOS::MutexBase.
|
||||||
|
*
|
||||||
|
* @note This class is not intended to be instantiated by the user. Use
|
||||||
|
* FreeRTOS::RecursiveMutex or FreeRTOS::StaticRecursiveMutex.
|
||||||
|
*/
|
||||||
|
class RecursiveMutexBase : public MutexBase {
|
||||||
|
public:
|
||||||
|
friend class RecursiveMutex;
|
||||||
|
friend class StaticRecursiveMutex;
|
||||||
|
|
||||||
|
RecursiveMutexBase(const RecursiveMutexBase&) = delete;
|
||||||
|
RecursiveMutexBase& operator=(const RecursiveMutexBase&) = delete;
|
||||||
|
|
||||||
|
static void* operator new(size_t, void*);
|
||||||
|
static void* operator new[](size_t, void*);
|
||||||
|
static void* operator new(size_t) = delete;
|
||||||
|
static void* operator new[](size_t) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mutex.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>xSemaphoreTakeRecursive( SemaphoreHandle_t
|
||||||
|
* xMutex, TickType_t xTicksToWait )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xSemaphoreTakeRecursive.html>
|
||||||
|
*
|
||||||
|
* @param ticksToWait The time in ticks to wait for the mutex to become
|
||||||
|
* available. The macro portTICK_PERIOD_MS can be used to convert this to a
|
||||||
|
* real time. A block time of zero can be used to poll the mutex. If the task
|
||||||
|
* already owns the mutex then take() will return immediately no matter what
|
||||||
|
* the value of ticksToWait.
|
||||||
|
* @retval true If the mutex was locked.
|
||||||
|
* @retval false If ticksToWait expired without the mutex becoming available.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Mutex/recursiveLock.cpp
|
||||||
|
*/
|
||||||
|
inline bool lock(const TickType_t ticksToWait = portMAX_DELAY) const {
|
||||||
|
return (xSemaphoreTakeRecursive(handle, ticksToWait) == pdTRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mutex.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>xSemaphoreGiveRecursive( SemaphoreHandle_t
|
||||||
|
* xSemaphore )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xSemaphoreGiveRecursive.html>
|
||||||
|
*
|
||||||
|
* A mutex used recursively can be locked repeatedly by the owner. The mutex
|
||||||
|
* doesn't become available again until the owner has called unlock() for each
|
||||||
|
* successful lock request. For example, if a task successfully locks the
|
||||||
|
* same mutex 5 times then the mutex will not be available to any other task
|
||||||
|
* until it has also unlocked the mutex back exactly five times.
|
||||||
|
*
|
||||||
|
* @return true If the mutex was unlocked.
|
||||||
|
* @return false Otherwise.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Mutex/recursiveLock.cpp
|
||||||
|
*/
|
||||||
|
inline bool unlock() const {
|
||||||
|
return (xSemaphoreGiveRecursive(handle) == pdTRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
RecursiveMutexBase() = default;
|
||||||
|
~RecursiveMutexBase() = default;
|
||||||
|
|
||||||
|
RecursiveMutexBase(RecursiveMutexBase&&) noexcept = default;
|
||||||
|
RecursiveMutexBase& operator=(RecursiveMutexBase&&) noexcept = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class Mutex Mutex.hpp <FreeRTOS/Mutex.hpp>
|
||||||
|
*
|
||||||
|
* @brief Class that encapsulates the functionality of a FreeRTOS mutex.
|
||||||
|
*
|
||||||
|
* Each mutex require a small amount of RAM that is used to hold the mutex's
|
||||||
|
* state. If a mutex is created using FreeRTOS::Mutex then the required RAM is
|
||||||
|
* automatically allocated from the FreeRTOS heap. If a mutex is created using
|
||||||
|
* FreeRTOS::StaticMutex then the RAM is provided by the application writer and
|
||||||
|
* allows the RAM to be statically allocated at compile time. See the Static Vs
|
||||||
|
* Dynamic allocation page for more information.
|
||||||
|
*
|
||||||
|
* Mutexes and binary semaphores are very similar but have some subtle
|
||||||
|
* differences: Mutexes include a priority inheritance mechanism, binary
|
||||||
|
* semaphores do not. This makes binary semaphores the better choice for
|
||||||
|
* implementing synchronisation (between tasks or between tasks and an
|
||||||
|
* interrupt), and mutexes the better choice for implementing simple mutual
|
||||||
|
* exclusion.
|
||||||
|
*
|
||||||
|
* The priority of a task that locks a mutex will be temporarily raised if
|
||||||
|
* another task of higher priority attempts to obtain the same mutex. The task
|
||||||
|
* that owns the mutex 'inherits' the priority of the task attempting to lock
|
||||||
|
* the same mutex. This means the mutex must always be unlocked back otherwise
|
||||||
|
* the higher priority task will never be able to lock the mutex, and the lower
|
||||||
|
* priority task will never 'disinherit' the priority.
|
||||||
|
*/
|
||||||
|
class Mutex : public MutexBase {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Mutex.hpp
|
||||||
|
*
|
||||||
|
* @brief Construct a new Mutex object by calling <tt>SemaphoreHandle_t
|
||||||
|
* xSemaphoreCreateMutex( void )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/CreateMutex.html>
|
||||||
|
*
|
||||||
|
* @warning The user should call isValid() on this object to verify that the
|
||||||
|
* mutex was created successfully in case the memory required to create the
|
||||||
|
* queue could not be allocated.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Mutex/mutex.cpp
|
||||||
|
*/
|
||||||
|
Mutex() { this->handle = xSemaphoreCreateMutex(); }
|
||||||
|
~Mutex() = default;
|
||||||
|
|
||||||
|
Mutex(const Mutex&) = delete;
|
||||||
|
Mutex& operator=(const Mutex&) = delete;
|
||||||
|
|
||||||
|
Mutex(Mutex&&) noexcept = default;
|
||||||
|
Mutex& operator=(Mutex&&) noexcept = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class RecursiveMutex Mutex.hpp <FreeRTOS/Mutex.hpp>
|
||||||
|
*
|
||||||
|
* @brief Class that encapsulates the functionality of a FreeRTOS recursive
|
||||||
|
* mutex.
|
||||||
|
*
|
||||||
|
* Each recursive mutex require a small amount of RAM that is used to hold the
|
||||||
|
* recursive mutex's state. If a mutex is created using FreeRTOS::RecursiveMutex
|
||||||
|
* then the required RAM is automatically allocated from the FreeRTOS heap. If a
|
||||||
|
* recursive mutex is created using FreeRTOS::StaticRecursiveMutex then the RAM
|
||||||
|
* is provided by the application writer, which requires an additional
|
||||||
|
* parameter, but allows the RAM to be statically allocated at compile time. See
|
||||||
|
* the Static Vs Dynamic allocation page for more information.
|
||||||
|
*
|
||||||
|
* Contrary to non-recursive mutexes, a task can lock a recursive mutex multiple
|
||||||
|
* times, and the recursive mutex will only be returned after the holding task
|
||||||
|
* has unlocked the mutex the same number of times it locked the mutex.
|
||||||
|
*
|
||||||
|
* Like non-recursive mutexes, recursive mutexes implement a priority
|
||||||
|
* inheritance algorithm. The priority of a task that locks a mutex will be
|
||||||
|
* temporarily raised if another task of higher priority attempts to obtain the
|
||||||
|
* same mutex. The task that owns the mutex 'inherits' the priority of the task
|
||||||
|
* attempting to lock the same mutex. This means the mutex must always be
|
||||||
|
* unlocked otherwise the higher priority task will never be able to obtain the
|
||||||
|
* mutex, and the lower priority task will never 'disinherit' the priority.
|
||||||
|
*/
|
||||||
|
class RecursiveMutex : public RecursiveMutexBase {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Mutex.hpp
|
||||||
|
*
|
||||||
|
* @brief Construct a new RecursiveMutex object by calling
|
||||||
|
* <tt>SemaphoreHandle_t xSemaphoreCreateRecursiveMutex( void )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xSemaphoreCreateRecursiveMutex.html>
|
||||||
|
*
|
||||||
|
* @warning The user should call isValid() on this object to verify that the
|
||||||
|
* recursive mutex was created successfully in case the memory required to
|
||||||
|
* create the queue could not be allocated.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Mutex/recursiveMutex.cpp
|
||||||
|
*/
|
||||||
|
RecursiveMutex() { this->handle = xSemaphoreCreateRecursiveMutex(); }
|
||||||
|
~RecursiveMutex() = default;
|
||||||
|
|
||||||
|
RecursiveMutex(const RecursiveMutex&) = delete;
|
||||||
|
RecursiveMutex& operator=(const RecursiveMutex&) = delete;
|
||||||
|
|
||||||
|
RecursiveMutex(RecursiveMutex&&) noexcept = default;
|
||||||
|
RecursiveMutex& operator=(RecursiveMutex&&) noexcept = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||||
|
|
||||||
|
#if (configSUPPORT_STATIC_ALLOCATION == 1)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class StaticMutex Mutex.hpp <FreeRTOS/Mutex.hpp>
|
||||||
|
*
|
||||||
|
* @brief Class that encapsulates the functionality of a FreeRTOS mutex.
|
||||||
|
*
|
||||||
|
* Each mutex require a small amount of RAM that is used to hold the mutex's
|
||||||
|
* state. If a mutex is created using FreeRTOS::Mutex then the required RAM is
|
||||||
|
* automatically allocated from the FreeRTOS heap. If a mutex is created using
|
||||||
|
* FreeRTOS::StaticMutex then the RAM is provided by the application writer and
|
||||||
|
* allows the RAM to be statically allocated at compile time. See the Static Vs
|
||||||
|
* Dynamic allocation page for more information.
|
||||||
|
*
|
||||||
|
* Mutexes and binary semaphores are very similar but have some subtle
|
||||||
|
* differences: Mutexes include a priority inheritance mechanism, binary
|
||||||
|
* semaphores do not. This makes binary semaphores the better choice for
|
||||||
|
* implementing synchronisation (between tasks or between tasks and an
|
||||||
|
* interrupt), and mutexes the better choice for implementing simple mutual
|
||||||
|
* exclusion.
|
||||||
|
*
|
||||||
|
* The priority of a task that locks a mutex will be temporarily raised if
|
||||||
|
* another task of higher priority attempts to obtain the same mutex. The task
|
||||||
|
* that owns the mutex 'inherits' the priority of the task attempting to lock
|
||||||
|
* the same mutex. This means the mutex must always be unlocked back otherwise
|
||||||
|
* the higher priority task will never be able to lock the mutex, and the lower
|
||||||
|
* priority task will never 'disinherit' the priority.
|
||||||
|
*/
|
||||||
|
class StaticMutex : public MutexBase {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Mutex.hpp
|
||||||
|
*
|
||||||
|
* @brief Construct a new StaticMutex object by calling
|
||||||
|
* <tt>SemaphoreHandle_t xSemaphoreCreateMutexStatic( StaticSemaphore_t
|
||||||
|
* *pxMutexBuffer )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xSemaphoreCreateMutexStatic.html>
|
||||||
|
*
|
||||||
|
* @warning This class contains the storage buffer for the mutex, so the user
|
||||||
|
* should create this object as a global object or with the static storage
|
||||||
|
* specifier so that the object instance is not on the stack.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Mutex/staticMutex.cpp
|
||||||
|
*/
|
||||||
|
StaticMutex() { this->handle = xSemaphoreCreateMutexStatic(&staticMutex); }
|
||||||
|
~StaticMutex() = default;
|
||||||
|
|
||||||
|
StaticMutex(const StaticMutex&) = delete;
|
||||||
|
StaticMutex& operator=(const StaticMutex&) = delete;
|
||||||
|
|
||||||
|
StaticMutex(StaticMutex&&) noexcept = default;
|
||||||
|
StaticMutex& operator=(StaticMutex&&) noexcept = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
StaticSemaphore_t staticMutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class StaticRecursiveMutex Mutex.hpp <FreeRTOS/Mutex.hpp>
|
||||||
|
*
|
||||||
|
* @brief Class that encapsulates the functionality of a FreeRTOS recursive
|
||||||
|
* mutex.
|
||||||
|
*
|
||||||
|
* Each recursive mutex require a small amount of RAM that is used to hold the
|
||||||
|
* recursive mutex's state. If a mutex is created using FreeRTOS::RecursiveMutex
|
||||||
|
* then the required RAM is automatically allocated from the FreeRTOS heap. If a
|
||||||
|
* recursive mutex is created using FreeRTOS::StaticRecursiveMutex then the RAM
|
||||||
|
* is provided by the application writer, which requires an additional
|
||||||
|
* parameter, but allows the RAM to be statically allocated at compile time. See
|
||||||
|
* the Static Vs Dynamic allocation page for more information.
|
||||||
|
*
|
||||||
|
* Contrary to non-recursive mutexes, a task can lock a recursive mutex multiple
|
||||||
|
* times, and the recursive mutex will only be returned after the holding task
|
||||||
|
* has unlocked the mutex the same number of times it locked the mutex.
|
||||||
|
*
|
||||||
|
* Like non-recursive mutexes, recursive mutexes implement a priority
|
||||||
|
* inheritance algorithm. The priority of a task that locks a mutex will be
|
||||||
|
* temporarily raised if another task of higher priority attempts to obtain the
|
||||||
|
* same mutex. The task that owns the mutex 'inherits' the priority of the task
|
||||||
|
* attempting to lock the same mutex. This means the mutex must always be
|
||||||
|
* unlocked otherwise the higher priority task will never be able to obtain the
|
||||||
|
* mutex, and the lower priority task will never 'disinherit' the priority.
|
||||||
|
*/
|
||||||
|
class StaticRecursiveMutex : public RecursiveMutexBase {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Mutex.hpp
|
||||||
|
*
|
||||||
|
* @brief Construct a new StaticRecursiveMutex object by calling
|
||||||
|
* <tt>SemaphoreHandle_t xSemaphoreCreateRecursiveMutexStatic(
|
||||||
|
* StaticSemaphore_t *pxMutexBuffer )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xSemaphoreCreateRecursiveMutexStatic.html>
|
||||||
|
*
|
||||||
|
* @warning This class contains the storage buffer for the recursive mutex, so
|
||||||
|
* the user should create this object as a global object or with the static
|
||||||
|
* storage specifier so that the object instance is not on the stack.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Mutex/staticRecursiveMutex.cpp
|
||||||
|
*/
|
||||||
|
StaticRecursiveMutex() {
|
||||||
|
this->handle = xSemaphoreCreateRecursiveMutexStatic(&staticRecursiveMutex);
|
||||||
|
}
|
||||||
|
~StaticRecursiveMutex() = default;
|
||||||
|
|
||||||
|
StaticRecursiveMutex(const StaticRecursiveMutex&) = delete;
|
||||||
|
StaticRecursiveMutex& operator=(const StaticRecursiveMutex&) = delete;
|
||||||
|
|
||||||
|
StaticRecursiveMutex(StaticRecursiveMutex&&) noexcept = default;
|
||||||
|
StaticRecursiveMutex& operator=(StaticRecursiveMutex&&) noexcept = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
StaticSemaphore_t staticRecursiveMutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||||
|
|
||||||
|
} // namespace FreeRTOS
|
||||||
|
|
||||||
|
#endif // FREERTOS_MUTEX_HPP
|
|
@ -0,0 +1,737 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS-Cpp
|
||||||
|
* Copyright (C) 2021 Jon Enz. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://github.com/jonenz/FreeRTOS-Cpp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FREERTOS_QUEUE_HPP
|
||||||
|
#define FREERTOS_QUEUE_HPP
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "queue.h"
|
||||||
|
|
||||||
|
namespace FreeRTOS {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class QueueBase Queue.hpp <FreeRTOS/Queue.hpp>
|
||||||
|
*
|
||||||
|
* @brief Base class that provides the standard queue interface to
|
||||||
|
* FreeRTOS::Queue and FreeRTOS::StaticQueue.
|
||||||
|
*
|
||||||
|
* @note This class is not intended to be instantiated by the user. Use
|
||||||
|
* FreeRTOS::Queue or FreeRTOS::StaticQueue.
|
||||||
|
*
|
||||||
|
* @tparam T Type to be stored in the queue.
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
class QueueBase {
|
||||||
|
public:
|
||||||
|
template <class>
|
||||||
|
friend class Queue;
|
||||||
|
|
||||||
|
template <class, UBaseType_t>
|
||||||
|
friend class StaticQueue;
|
||||||
|
|
||||||
|
QueueBase(const QueueBase&) = delete;
|
||||||
|
QueueBase& operator=(const QueueBase&) = delete;
|
||||||
|
|
||||||
|
static void* operator new(size_t, void* ptr) { return ptr; }
|
||||||
|
static void* operator new[](size_t, void* ptr) { return ptr; }
|
||||||
|
static void* operator new(size_t) = delete;
|
||||||
|
static void* operator new[](size_t) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that checks if the underlying queue handle is not NULL.
|
||||||
|
* This should be used to ensure a queue has been created correctly.
|
||||||
|
*
|
||||||
|
* @retval true the handle is not NULL.
|
||||||
|
* @retval false the handle is NULL.
|
||||||
|
*/
|
||||||
|
inline bool isValid() const { return (handle != NULL); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>xQueueSendToBack( xQueue, pvItemToQueue,
|
||||||
|
* xTicksToWait )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/a00117.html>
|
||||||
|
*
|
||||||
|
* Post an item to the back of a queue. The item is queued by copy, not by
|
||||||
|
* reference. This function must not be called from an interrupt service
|
||||||
|
* routine. See FreeRTOS::Queue::sendToBackFromISR() for an alternative which
|
||||||
|
* may be used in an ISR.
|
||||||
|
*
|
||||||
|
* @param item A reference to the item that is to be placed on the queue.
|
||||||
|
* @param ticksToWait The maximum amount of time the task should block waiting
|
||||||
|
* for space to become available on the queue, should it already be full. The
|
||||||
|
* call will return immediately if this is set to 0 and the queue is full. The
|
||||||
|
* time is defined in tick periods so the constant portTICK_PERIOD_MS should
|
||||||
|
* be used to convert to real time if this is required.
|
||||||
|
* @retval true if the item was successfully posted.
|
||||||
|
* @retval false otherwise.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Queue/sendToBack.cpp
|
||||||
|
*/
|
||||||
|
inline bool sendToBack(const T& item,
|
||||||
|
const TickType_t ticksToWait = portMAX_DELAY) const {
|
||||||
|
return (xQueueSendToBack(handle, &item, ticksToWait) == pdTRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>xQueueSendToBackFromISR( xQueue,
|
||||||
|
* pvItemToQueue, pxHigherPriorityTaskWoken )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xQueueSendToBackFromISR.html>
|
||||||
|
*
|
||||||
|
* @param higherPriorityTaskWoken A reference that will be set to true if
|
||||||
|
* sending to the queue caused a task to unblock, and the unblocked task has a
|
||||||
|
* priority higher than the currently running task.
|
||||||
|
* @param item A reference to the item that is to be placed on the queue.
|
||||||
|
* @retval true if the item was successfully posted
|
||||||
|
* @retval false otherwise.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Queue/sendToBackFromISR.cpp
|
||||||
|
*/
|
||||||
|
inline bool sendToBackFromISR(bool& higherPriorityTaskWoken,
|
||||||
|
const T& item) const {
|
||||||
|
BaseType_t taskWoken = pdFALSE;
|
||||||
|
bool result =
|
||||||
|
(xQueueSendToBackFromISR(handle, &item, &taskWoken) == pdPASS);
|
||||||
|
if (taskWoken == pdTRUE) {
|
||||||
|
higherPriorityTaskWoken = true;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>xQueueSendToBackFromISR( xQueue,
|
||||||
|
* pvItemToQueue, pxHigherPriorityTaskWoken )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xQueueSendToBackFromISR.html>
|
||||||
|
*
|
||||||
|
* @overload
|
||||||
|
*/
|
||||||
|
inline bool sendToBackFromISR(const T& item) const {
|
||||||
|
return (xQueueSendToBackFromISR(handle, &item, NULL) == pdPASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>xQueueSendToFront( xQueue, pvItemToQueue,
|
||||||
|
* xTicksToWait )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xQueueSendToFront.html>
|
||||||
|
*
|
||||||
|
* @param item A reference to the item that is to be placed on the queue.
|
||||||
|
* @param ticksToWait The maximum amount of time the task should block waiting
|
||||||
|
* for space to become available on the queue, should it already be full. The
|
||||||
|
* call will return immediately if this is set to 0 and the queue is full. The
|
||||||
|
* time is defined in tick periods so the constant portTICK_PERIOD_MS should
|
||||||
|
* be used to convert to real time if this is required.
|
||||||
|
* @retval true if the item was successfully posted.
|
||||||
|
* @retval false otherwise.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Queue/sendToFront.cpp
|
||||||
|
*/
|
||||||
|
inline bool sendToFront(const T& item,
|
||||||
|
const TickType_t ticksToWait = portMAX_DELAY) const {
|
||||||
|
return (xQueueSendToFront(handle, &item, ticksToWait) == pdTRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>xQueueSendToFrontFromISR( xQueue,
|
||||||
|
* pvItemToQueue, pxHigherPriorityTaskWoken )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xQueueSendToFrontFromISR.html>
|
||||||
|
*
|
||||||
|
* @param higherPriorityTaskWoken A reference that will be set to true if
|
||||||
|
* sending to the queue caused a task to unblock, and the unblocked task has a
|
||||||
|
* priority higher than the currently running task.
|
||||||
|
* @param item A reference to the item that is to be placed on the queue.
|
||||||
|
* @retval true if the item was successfully posted
|
||||||
|
* @retval false otherwise.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Queue/sendToFrontFromISR.cpp
|
||||||
|
*/
|
||||||
|
inline bool sendToFrontFromISR(bool& higherPriorityTaskWoken,
|
||||||
|
const T& item) const {
|
||||||
|
BaseType_t taskWoken = pdFALSE;
|
||||||
|
bool result =
|
||||||
|
(xQueueSendToFrontFromISR(handle, &item, &taskWoken) == pdPASS);
|
||||||
|
if (taskWoken == pdTRUE) {
|
||||||
|
higherPriorityTaskWoken = true;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>xQueueSendToFrontFromISR( xQueue,
|
||||||
|
* pvItemToQueue, pxHigherPriorityTaskWoken )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xQueueSendToFrontFromISR.html>
|
||||||
|
*
|
||||||
|
* @overload
|
||||||
|
*/
|
||||||
|
inline bool sendToFrontFromISR(const T& item) const {
|
||||||
|
return (xQueueSendToFrontFromISR(handle, &item, NULL) == pdPASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>BaseType_t xQueueReceive( QueueHandle_t
|
||||||
|
* xQueue, void *pvBuffer, TickType_t xTicksToWait )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/a00118.html>
|
||||||
|
*
|
||||||
|
* Receive an item from a queue. This function must not be used in an
|
||||||
|
* interrupt service routine. See receiveFromISR() for an alternative that
|
||||||
|
* can.
|
||||||
|
*
|
||||||
|
* @param ticksToWait The maximum amount of time the task should block waiting
|
||||||
|
* for an item to receive should the queue be empty at the time of the call.
|
||||||
|
* Setting ticksToWait to 0 will cause the function to return immediately if
|
||||||
|
* the queue is empty. The time is defined in tick periods so the constant
|
||||||
|
* portTICK_PERIOD_MS should be used to convert to real time if this is
|
||||||
|
* required.
|
||||||
|
* @return std::optional<T> Object from the queue. User should check that the
|
||||||
|
* value is present.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Queue/receive.cpp
|
||||||
|
*/
|
||||||
|
inline std::optional<T> receive(
|
||||||
|
const TickType_t ticksToWait = portMAX_DELAY) const {
|
||||||
|
T buffer;
|
||||||
|
return (xQueueReceive(handle, &buffer, ticksToWait) == pdTRUE)
|
||||||
|
? std::optional<T>(buffer)
|
||||||
|
: std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>BaseType_t xQueueReceiveFromISR(
|
||||||
|
* QueueHandle_t xQueue, void *pvBuffer, BaseType_t *pxHigherPriorityTaskWoken
|
||||||
|
* )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/a00120.html>
|
||||||
|
*
|
||||||
|
* Receive an item from a queue. It is safe to use this function from within
|
||||||
|
* an interrupt service routine.
|
||||||
|
*
|
||||||
|
* @param higherPriorityTaskWoken A reference that will be set to true if
|
||||||
|
* sending to the queue caused a task to unblock, and the unblocked task has a
|
||||||
|
* priority higher than the currently running task.
|
||||||
|
* @return std::optional<T> Object from the queue. User should check that the
|
||||||
|
* value is present.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Queue/receiveFromISR.cpp
|
||||||
|
*/
|
||||||
|
inline std::optional<T> receiveFromISR(bool& higherPriorityTaskWoken) const {
|
||||||
|
T buffer;
|
||||||
|
BaseType_t taskWoken = pdFALSE;
|
||||||
|
bool result = (xQueueReceiveFromISR(handle, &buffer, &taskWoken) == pdTRUE);
|
||||||
|
if (taskWoken == pdTRUE) {
|
||||||
|
higherPriorityTaskWoken = true;
|
||||||
|
}
|
||||||
|
return result ? std::optional<T>(buffer) : std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>BaseType_t xQueueReceiveFromISR(
|
||||||
|
* QueueHandle_t xQueue, void *pvBuffer, BaseType_t *pxHigherPriorityTaskWoken
|
||||||
|
* )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/a00120.html>
|
||||||
|
*
|
||||||
|
* @overload
|
||||||
|
*/
|
||||||
|
inline std::optional<T> receiveFromISR() const {
|
||||||
|
T buffer;
|
||||||
|
return (xQueueReceiveFromISR(handle, &buffer, NULL) == pdTRUE)
|
||||||
|
? std::optional<T>(buffer)
|
||||||
|
: std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>UBaseType_t uxQueueMessagesWaiting(
|
||||||
|
* QueueHandle_t xQueue )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/a00018.html#ucQueueMessagesWaiting>
|
||||||
|
*
|
||||||
|
* Return the number of messages stored in a queue.
|
||||||
|
*
|
||||||
|
* @retval UBaseType_t The number of messages available in the queue.
|
||||||
|
*/
|
||||||
|
inline UBaseType_t messagesWaiting() const {
|
||||||
|
return uxQueueMessagesWaiting(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>UBaseType_t uxQueueMessagesWaitingFromISR(
|
||||||
|
* QueueHandle_t xQueue )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/a00018.html#ucQueueMessagesWaitingFromISR>
|
||||||
|
*
|
||||||
|
* A version of messagesWaiting() that can be called from an ISR. Return the
|
||||||
|
* number of messages stored in a queue.
|
||||||
|
*
|
||||||
|
* @retval UBaseType_t The number of messages available in the queue.
|
||||||
|
*/
|
||||||
|
inline UBaseType_t messagesWaitingFromISR() const {
|
||||||
|
return uxQueueMessagesWaitingFromISR(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>UBaseType_t uxQueueSpacesAvailable(
|
||||||
|
* QueueHandle_t xQueue )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/a00018.html#uxQueueSpacesAvailable>
|
||||||
|
*
|
||||||
|
* Return the number of free spaces in a queue.
|
||||||
|
*
|
||||||
|
* @retval UBaseType_t The number of free spaces available in the queue.
|
||||||
|
*/
|
||||||
|
inline UBaseType_t spacesAvailable() const {
|
||||||
|
return uxQueueSpacesAvailable(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>BaseType_t xQueueReset( QueueHandle_t xQueue
|
||||||
|
* )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/a00018.html#xQueueReset>
|
||||||
|
*
|
||||||
|
* Resets a queue to its original empty state.
|
||||||
|
*/
|
||||||
|
inline void reset() const { xQueueReset(handle); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>BaseType_t xQueueOverwrite( QueueHandle_t
|
||||||
|
* xQueue, const void * pvItemToQueue )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xQueueOverwrite.html>
|
||||||
|
*
|
||||||
|
* Only for use with queues that have a length of one - so the queue is either
|
||||||
|
* empty or full.
|
||||||
|
*
|
||||||
|
* Post an item on a queue. If the queue is already full then overwrite the
|
||||||
|
* value held in the queue. The item is queued by copy, not by reference.
|
||||||
|
*
|
||||||
|
* This function must not be called from an interrupt service routine. See
|
||||||
|
* overwriteFromISR() for an alternative which may be used in an ISR.
|
||||||
|
*
|
||||||
|
* @param item A reference to the item that is to be placed on the queue.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Queue/overwrite.cpp
|
||||||
|
*/
|
||||||
|
inline void overwrite(const T& item) const { xQueueOverwrite(handle, &item); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>BaseType_t xQueueOverwriteFromISR(
|
||||||
|
* QueueHandle_t xQueue, const void * pvItemToQueue, BaseType_t
|
||||||
|
* *pxHigherPriorityTaskWoken )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xQueueOverwriteFromISR.html>
|
||||||
|
*
|
||||||
|
* A version of overwrite() that can be used in an interrupt service routine
|
||||||
|
* (ISR).
|
||||||
|
*
|
||||||
|
* Only for use with queues that can hold a single item - so the queue is
|
||||||
|
* either empty or full.
|
||||||
|
*
|
||||||
|
* Post an item on a queue. If the queue is already full then overwrite the
|
||||||
|
* value held in the queue. The item is queued by copy, not by reference.
|
||||||
|
*
|
||||||
|
* @param higherPriorityTaskWoken A reference that will be set to true if
|
||||||
|
* sending to the queue caused a task to unblock, and the unblocked task has a
|
||||||
|
* priority higher than the currently running task.
|
||||||
|
* @param item A reference to the item that is to be placed on the queue.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Queue/overwriteFromISR.cpp
|
||||||
|
*/
|
||||||
|
inline void overwriteFromISR(bool& higherPriorityTaskWoken,
|
||||||
|
const T& item) const {
|
||||||
|
BaseType_t taskWoken = pdFALSE;
|
||||||
|
xQueueOverwriteFromISR(handle, &item, &taskWoken);
|
||||||
|
if (taskWoken == pdTRUE) {
|
||||||
|
higherPriorityTaskWoken = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>BaseType_t xQueueOverwriteFromISR(
|
||||||
|
* QueueHandle_t xQueue, const void * pvItemToQueue, BaseType_t
|
||||||
|
* *pxHigherPriorityTaskWoken )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xQueueOverwriteFromISR.html>
|
||||||
|
*
|
||||||
|
* @overload
|
||||||
|
*/
|
||||||
|
inline void overwriteFromISR(const T& item) const {
|
||||||
|
xQueueOverwriteFromISR(handle, &item, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>BaseType_t xQueuePeek( QueueHandle_t xQueue,
|
||||||
|
* void * const pvBuffer, TickType_t xTicksToWait )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xQueuePeek.html>
|
||||||
|
*
|
||||||
|
* Receive an item from a queue without removing the item from the queue.
|
||||||
|
*
|
||||||
|
* Successfully received items remain on the queue so will be returned again
|
||||||
|
* by the next call, or a call to receive().
|
||||||
|
*
|
||||||
|
* This function must not be used in an interrupt service routine. See
|
||||||
|
* peekFromISR() for an alternative that can be called from an interrupt
|
||||||
|
* service routine.
|
||||||
|
*
|
||||||
|
* @param ticksToWait The maximum amount of time the task should block waiting
|
||||||
|
* for an item to receive should the queue be empty at the time of the call.
|
||||||
|
* Setting ticksToWait to 0 will cause the function to return immediately if
|
||||||
|
* the queue is empty. The time is defined in tick periods so the constant
|
||||||
|
* portTICK_PERIOD_MS should be used to convert to real time if this is
|
||||||
|
* required.
|
||||||
|
* @return std::optional<T> Object from the queue. User should check that the
|
||||||
|
* value is present.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Queue/peek.cpp
|
||||||
|
*/
|
||||||
|
inline std::optional<T> peek(
|
||||||
|
const TickType_t ticksToWait = portMAX_DELAY) const {
|
||||||
|
T buffer;
|
||||||
|
return (xQueuePeek(handle, &buffer, ticksToWait) == pdTRUE)
|
||||||
|
? std::optional<T>(buffer)
|
||||||
|
: std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>BaseType_t xQueuePeekFromISR( QueueHandle_t
|
||||||
|
* xQueue, void *pvBuffer )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xQueuePeekFromISR.html>
|
||||||
|
*
|
||||||
|
* A version of peek() that can be called from an interrupt service routine
|
||||||
|
* (ISR).
|
||||||
|
*
|
||||||
|
* Receive an item from a queue without removing the item from the queue.
|
||||||
|
*
|
||||||
|
* Successfully received items remain on the queue so will be returned again
|
||||||
|
* by the next call, or a call to receive().
|
||||||
|
*
|
||||||
|
* @return std::optional<T> Object from the queue. User should check that the
|
||||||
|
* value is present.
|
||||||
|
*/
|
||||||
|
inline std::optional<T> peekFromISR() const {
|
||||||
|
T buffer;
|
||||||
|
return (xQueuePeekFromISR(handle, &buffer) == pdTRUE)
|
||||||
|
? std::optional<T>(buffer)
|
||||||
|
: std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>void vQueueAddToRegistry( QueueHandle_t
|
||||||
|
* xQueue, char *pcQueueName )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/vQueueAddToRegistry.html>
|
||||||
|
*
|
||||||
|
* The registry is provided as a means for kernel aware debuggers to locate
|
||||||
|
* queues, semaphores and mutexes. Call addToRegistry() add a queue,
|
||||||
|
* semaphore or mutex handle to the registry if you want the handle to be
|
||||||
|
* available to a kernel aware debugger. If you are not using a kernel aware
|
||||||
|
* debugger then this function can be ignored.
|
||||||
|
*
|
||||||
|
* configQUEUE_REGISTRY_SIZE defines the maximum number of handles the
|
||||||
|
* registry can hold. configQUEUE_REGISTRY_SIZE must be greater than 0 within
|
||||||
|
* FreeRTOSConfig.h for the registry to be available. Its value does not
|
||||||
|
* effect the number of queues, semaphores and mutexes that can be created -
|
||||||
|
* just the number that the registry can hold.
|
||||||
|
*
|
||||||
|
* If addToRegistry() is called more than once for the same queue, the
|
||||||
|
* registry will store the name parameter from the most recent call to
|
||||||
|
* addToRegistry().
|
||||||
|
*
|
||||||
|
* @param name The name to be associated with the handle. This is the name
|
||||||
|
* that the kernel aware debugger will display. The queue registry only
|
||||||
|
* stores a pointer to the string - so the string must be persistent (global
|
||||||
|
* or preferably in ROM/Flash), not on the stack.
|
||||||
|
*/
|
||||||
|
inline void addToRegistry(const char* name) const {
|
||||||
|
vQueueAddToRegistry(handle, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>void vQueueUnregisterQueue( QueueHandle_t
|
||||||
|
* xQueue )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/vQueueUnregisterQueue.html>
|
||||||
|
*
|
||||||
|
* The registry is provided as a means for kernel aware debuggers to locate
|
||||||
|
* queues, semaphores and mutexes. Call addToRegistry() add a queue,
|
||||||
|
* semaphore or mutex handle to the registry if you want the handle to be
|
||||||
|
* available to a kernel aware debugger, and unregister() to remove the queue,
|
||||||
|
* semaphore or mutex from the register. If you are not using a kernel aware
|
||||||
|
* debugger then this function can be ignored.
|
||||||
|
*/
|
||||||
|
inline void unregister() const { vQueueUnregisterQueue(handle); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>const char *pcQueueGetName( QueueHandle_t
|
||||||
|
* xQueue )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/pcQueueGetName.html>
|
||||||
|
*
|
||||||
|
* The queue registry is provided as a means for kernel aware debuggers to
|
||||||
|
* locate queues, semaphores and mutexes. Call getName() to look up and return
|
||||||
|
* the name of a queue in the queue registry from the queue's handle.
|
||||||
|
*
|
||||||
|
* @return If the queue referenced by the queue is in the queue registry, then
|
||||||
|
* the text name of the queue is returned, otherwise NULL is returned.
|
||||||
|
*/
|
||||||
|
inline const char* getName() const { return pcQueueGetName(handle); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>BaseType_t xQueueIsQueueFullFromISR( const
|
||||||
|
* QueueHandle_t xQueue )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/a00018.html#xQueueIsQueueFullFromISR>
|
||||||
|
*
|
||||||
|
* Queries a queue to determine if the queue is empty. This function should
|
||||||
|
* only be used in an ISR.
|
||||||
|
*
|
||||||
|
* @return true if the queue is full.
|
||||||
|
* @return false if the queue is not full.
|
||||||
|
*/
|
||||||
|
inline bool isFullFromISR() const {
|
||||||
|
return (xQueueIsQueueFullFromISR(handle) == pdTRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>BaseType_t xQueueIsQueueEmptyFromISR( const
|
||||||
|
* QueueHandle_t xQueue )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/a00018.html#xQueueIsQueueEmptyFromISR>
|
||||||
|
*
|
||||||
|
* Queries a queue to determine if the queue is empty. This function should
|
||||||
|
* only be used in an ISR.
|
||||||
|
*
|
||||||
|
* @retval true if the queue is empty.
|
||||||
|
* @retval false if the queue is not empty.
|
||||||
|
*/
|
||||||
|
inline bool isEmptyFromISR() const {
|
||||||
|
return (xQueueIsQueueEmptyFromISR(handle) == pdTRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Queue.hpp
|
||||||
|
*
|
||||||
|
* @brief Construct a new QueueBase object.
|
||||||
|
*
|
||||||
|
* @note Default constructor is deliberately private as this class is not
|
||||||
|
* intended to be instantiated or derived from by the user. Use
|
||||||
|
* FreeRTOS::Queue or FreeRTOS::StaticQueue.
|
||||||
|
*/
|
||||||
|
QueueBase() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue.hpp
|
||||||
|
*
|
||||||
|
* @brief Destroy the QueueBase object by calling <tt>void vQueueDelete(
|
||||||
|
* QueueHandle_t xQueue )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/a00018.html#vQueueDelete>
|
||||||
|
*
|
||||||
|
* Delete a queue - freeing all the memory allocated for storing of items
|
||||||
|
* placed on the queue.
|
||||||
|
*/
|
||||||
|
~QueueBase() { vQueueDelete(this->handle); }
|
||||||
|
|
||||||
|
QueueBase(QueueBase&&) noexcept = default;
|
||||||
|
QueueBase& operator=(QueueBase&&) noexcept = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Handle used to refer to the queue when using the FreeRTOS interface.
|
||||||
|
*/
|
||||||
|
QueueHandle_t handle = NULL;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class Queue Queue.hpp <FreeRTOS/Queue.hpp>
|
||||||
|
*
|
||||||
|
* @brief Class that encapsulates the functionality of a FreeRTOS queue.
|
||||||
|
*
|
||||||
|
* Each queue requires RAM that is used to hold the queue state, and to hold the
|
||||||
|
* items that are contained in the queue (the queue storage area). If a queue is
|
||||||
|
* created using this class then the required RAM is automatically allocated
|
||||||
|
* from the FreeRTOS heap.
|
||||||
|
*
|
||||||
|
* @tparam T Type to be stored in the queue.
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
class Queue : public QueueBase<T> {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Queue.hpp
|
||||||
|
*
|
||||||
|
* @brief Construct a new Queue object by calling <tt>QueueHandle_t
|
||||||
|
* xQueueCreate( UBaseType_t uxQueueLength, UBaseType_t uxItemSize )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/a00116.html>
|
||||||
|
*
|
||||||
|
* @warning The user should call isValid() on this object to verify that the
|
||||||
|
* queue was created successfully in case the memory required to create the
|
||||||
|
* queue could not be allocated.
|
||||||
|
*
|
||||||
|
* @param length The maximum number of items the queue can hold at any one
|
||||||
|
* time.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Queue/queue.cpp
|
||||||
|
*/
|
||||||
|
explicit Queue(const UBaseType_t length) {
|
||||||
|
this->handle = xQueueCreate(length, sizeof(T));
|
||||||
|
}
|
||||||
|
~Queue() = default;
|
||||||
|
|
||||||
|
Queue(const Queue&) = delete;
|
||||||
|
Queue& operator=(const Queue&) = delete;
|
||||||
|
|
||||||
|
Queue(Queue&&) noexcept = default;
|
||||||
|
Queue& operator=(Queue&&) noexcept = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||||
|
|
||||||
|
#if (configSUPPORT_STATIC_ALLOCATION == 1)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class StaticQueue Queue.hpp <FreeRTOS/Queue.hpp>
|
||||||
|
*
|
||||||
|
* @brief Class that encapsulates the functionality of a FreeRTOS queue.
|
||||||
|
*
|
||||||
|
* If a queue is created using this class then the RAM is provided by the
|
||||||
|
* application writer as part of the object instance and allows the RAM to be
|
||||||
|
* statically allocated at compile time.
|
||||||
|
*
|
||||||
|
* @tparam T Type to be stored in the queue.
|
||||||
|
* @tparam N The maximum number of items the queue can hold at any one time.
|
||||||
|
*/
|
||||||
|
template <class T, UBaseType_t N>
|
||||||
|
class StaticQueue : public QueueBase<T> {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Queue.hpp
|
||||||
|
*
|
||||||
|
* @brief Construct a new StaticQueue object by calling
|
||||||
|
* <tt>QueueHandle_t xQueueCreateStatic( UBaseType_t uxQueueLength,
|
||||||
|
* UBaseType_t uxItemSize, uint8_t *pucQueueStorageBuffer, StaticQueue_t
|
||||||
|
* *pxQueueBuffer )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xQueueCreateStatic.html>
|
||||||
|
*
|
||||||
|
* @warning This class contains the storage buffer for the queue, so the user
|
||||||
|
* should create this object as a global object or with the static storage
|
||||||
|
* specifier so that the object instance is not on the stack.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Queue/staticQueue.cpp
|
||||||
|
*/
|
||||||
|
StaticQueue() {
|
||||||
|
this->handle = xQueueCreateStatic(N, sizeof(T), storage, &staticQueue);
|
||||||
|
}
|
||||||
|
~StaticQueue() = default;
|
||||||
|
|
||||||
|
StaticQueue(const StaticQueue&) = delete;
|
||||||
|
StaticQueue& operator=(const StaticQueue&) = delete;
|
||||||
|
|
||||||
|
StaticQueue(StaticQueue&&) noexcept = default;
|
||||||
|
StaticQueue& operator=(StaticQueue&&) noexcept = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
StaticQueue_t staticQueue;
|
||||||
|
uint8_t storage[N * sizeof(T)];
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||||
|
|
||||||
|
} // namespace FreeRTOS
|
||||||
|
|
||||||
|
#endif // FREERTOS_QUEUE_HPP
|
|
@ -0,0 +1,523 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS-Cpp
|
||||||
|
* Copyright (C) 2021 Jon Enz. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://github.com/jonenz/FreeRTOS-Cpp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FREERTOS_SEMAPHORE_HPP
|
||||||
|
#define FREERTOS_SEMAPHORE_HPP
|
||||||
|
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "semphr.h"
|
||||||
|
|
||||||
|
namespace FreeRTOS {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class SemaphoreBase Semaphore.hpp <FreeRTOS/Semaphore.hpp>
|
||||||
|
*
|
||||||
|
* @brief Base class that provides the standard semaphore interface to
|
||||||
|
* FreeRTOS::BinarySemaphore, FreeRTOS::StaticBinarySemaphore,
|
||||||
|
* FreeRTOS::CountingSemaphore, and FreeRTOS::StaticCountingSemaphore.
|
||||||
|
*
|
||||||
|
* @note This class is not intended to be instantiated by the user. Use
|
||||||
|
* FreeRTOS::BinarySemaphore, FreeRTOS::StaticBinarySemaphore,
|
||||||
|
* FreeRTOS::CountingSemaphore, or FreeRTOS::StaticCountingSemaphore.
|
||||||
|
*/
|
||||||
|
class SemaphoreBase {
|
||||||
|
public:
|
||||||
|
friend class BinarySemaphore;
|
||||||
|
friend class StaticBinarySemaphore;
|
||||||
|
friend class CountingSemaphore;
|
||||||
|
friend class StaticCountingSemaphore;
|
||||||
|
|
||||||
|
SemaphoreBase(const SemaphoreBase&) = delete;
|
||||||
|
SemaphoreBase& operator=(const SemaphoreBase&) = delete;
|
||||||
|
|
||||||
|
static void* operator new(size_t, void* ptr) { return ptr; }
|
||||||
|
static void* operator new[](size_t, void* ptr) { return ptr; }
|
||||||
|
static void* operator new(size_t) = delete;
|
||||||
|
static void* operator new[](size_t) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Semaphore.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that checks if the underlying semaphore handle is not NULL.
|
||||||
|
* This should be used to ensure a semaphore has been created correctly.
|
||||||
|
*
|
||||||
|
* @retval true the handle is not NULL.
|
||||||
|
* @retval false the handle is NULL.
|
||||||
|
*/
|
||||||
|
inline bool isValid() const { return (handle != NULL); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Semaphore.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>UBaseType_t uxSemaphoreGetCount(
|
||||||
|
* SemaphoreHandle_t xSemaphore )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/uxSemaphoreGetCount.html>
|
||||||
|
*
|
||||||
|
* Returns the count of a semaphore.
|
||||||
|
*
|
||||||
|
* @return UBaseType_t If the semaphore is a counting semaphore then the
|
||||||
|
* semaphores current count value is returned. If the semaphore is a binary
|
||||||
|
* semaphore then 1 is returned if the semaphore is available, and 0 is
|
||||||
|
* returned if the semaphore is not available.
|
||||||
|
*/
|
||||||
|
inline UBaseType_t getCount() const { return uxSemaphoreGetCount(handle); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Semaphore.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>xSemaphoreTake( SemaphoreHandle_t
|
||||||
|
* xSemaphore, TickType_t xTicksToWait )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/a00122.html>
|
||||||
|
*
|
||||||
|
* Function to obtain a semaphore.
|
||||||
|
*
|
||||||
|
* This macro must not be called from an ISR. takeFromISR() can be used to
|
||||||
|
* take a semaphore from within an interrupt if required, although this would
|
||||||
|
* not be a normal operation. Semaphores use queues as their underlying
|
||||||
|
* mechanism, so functions are to some extent interoperable.
|
||||||
|
*
|
||||||
|
* @param ticksToWait The time in ticks to wait for the semaphore to become
|
||||||
|
* available. The macro portTICK_PERIOD_MS can be used to convert this to a
|
||||||
|
* real time. A block time of zero can be used to poll the semaphore.
|
||||||
|
* @retval true If the semaphore was obtained.
|
||||||
|
* @retval false If xTicksToWait expired without the semaphore becoming
|
||||||
|
* available.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Semaphore/take.cpp
|
||||||
|
*/
|
||||||
|
inline bool take(const TickType_t ticksToWait = portMAX_DELAY) const {
|
||||||
|
return (xSemaphoreTake(handle, ticksToWait) == pdTRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Semaphore.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>xSemaphoreTakeFromISR( SemaphoreHandle_t
|
||||||
|
* xSemaphore, signed BaseType_t *pxHigherPriorityTaskWoken)</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xSemaphoreTakeFromISR.html>
|
||||||
|
*
|
||||||
|
* A version of take() that can be called from an ISR. Unlike take(),
|
||||||
|
* takeFromISR() does not permit a block time to be specified.
|
||||||
|
*
|
||||||
|
* @param higherPriorityTaskWoken It is possible (although unlikely, and
|
||||||
|
* dependent on the semaphore type) that a semaphore will have one or more
|
||||||
|
* tasks blocked on it waiting to give the semaphore. Calling takeFromISR()
|
||||||
|
* will make a task that was blocked waiting to give the semaphore leave the
|
||||||
|
* Blocked state. If calling the API function causes a task to leave the
|
||||||
|
* Blocked state, and the unblocked task has a priority equal to or higher
|
||||||
|
* than the currently executing task (the task that was interrupted), then,
|
||||||
|
* internally, the API function will set higherPriorityTaskWoken to true. If
|
||||||
|
* takeFromISR() sets higherPriorityTaskWoken to true, then a context switch
|
||||||
|
* should be performed before the interrupt is exited. This will ensure that
|
||||||
|
* the interrupt returns directly to the highest priority Ready state task.
|
||||||
|
* The mechanism is identical to that used in the FreeRTOS::receiveFromISR()
|
||||||
|
* function, and readers are referred to the FreeRTOS::receiveFromISR()
|
||||||
|
* documentation for further explanation.
|
||||||
|
* @retval true If the semaphore was successfully taken.
|
||||||
|
* @retval false If the semaphore was not successfully taken because it was
|
||||||
|
* not available.
|
||||||
|
*/
|
||||||
|
inline bool takeFromISR(bool& higherPriorityTaskWoken) const {
|
||||||
|
BaseType_t taskWoken = pdFALSE;
|
||||||
|
bool result = (xSemaphoreTakeFromISR(handle, &taskWoken) == pdTRUE);
|
||||||
|
if (taskWoken == pdTRUE) {
|
||||||
|
higherPriorityTaskWoken = true;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Semaphore.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>xSemaphoreTakeFromISR( SemaphoreHandle_t
|
||||||
|
* xSemaphore, signed BaseType_t *pxHigherPriorityTaskWoken)</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xSemaphoreTakeFromISR.html>
|
||||||
|
*
|
||||||
|
* @overload
|
||||||
|
*/
|
||||||
|
inline bool takeFromISR() const {
|
||||||
|
return (xSemaphoreTakeFromISR(handle, NULL) == pdTRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Semaphore.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>xSemaphoreGive( SemaphoreHandle_t xSemaphore
|
||||||
|
* )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/a00123.html>
|
||||||
|
*
|
||||||
|
* Function to release a semaphore.
|
||||||
|
*
|
||||||
|
* This must not be used from an ISR. See giveFromISR() for an alternative
|
||||||
|
* which can be used from an ISR.
|
||||||
|
*
|
||||||
|
* @retval true If the semaphore was released.
|
||||||
|
* @retval false If an error occurred. Semaphores are implemented using
|
||||||
|
* queues. An error can occur if there is no space on the queue to post a
|
||||||
|
* message indicating that the semaphore was not first obtained correctly.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Semaphore/give.cpp
|
||||||
|
*/
|
||||||
|
inline bool give() const { return (xSemaphoreGive(handle) == pdTRUE); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Semaphore.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>xSemaphoreGiveFromISR( SemaphoreHandle_t
|
||||||
|
* xSemaphore, signed BaseType_t *pxHigherPriorityTaskWoken )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/a00124.html>
|
||||||
|
*
|
||||||
|
* Function to release a semaphore.
|
||||||
|
*
|
||||||
|
* This macro can be used from an ISR.
|
||||||
|
*
|
||||||
|
* @param higherPriorityTaskWoken giveFromISR() will set
|
||||||
|
* higherPriorityTaskWoken to true if giving the semaphore caused a task to
|
||||||
|
* unblock, and the unblocked task has a priority higher than the currently
|
||||||
|
* running task. If giveFromISR() sets this value to true then a context
|
||||||
|
* switch should be requested before the interrupt is exited.
|
||||||
|
* @retval true If the semaphore was successfully given.
|
||||||
|
* @retval false Otherwise.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Semaphore/giveFromISR.cpp
|
||||||
|
*/
|
||||||
|
inline bool giveFromISR(bool& higherPriorityTaskWoken) const {
|
||||||
|
BaseType_t taskWoken = pdFALSE;
|
||||||
|
bool result = (xSemaphoreGiveFromISR(handle, &taskWoken) == pdTRUE);
|
||||||
|
if (taskWoken == pdTRUE) {
|
||||||
|
higherPriorityTaskWoken = true;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Semaphore.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>xSemaphoreGiveFromISR( SemaphoreHandle_t
|
||||||
|
* xSemaphore, signed BaseType_t *pxHigherPriorityTaskWoken )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/a00124.html>
|
||||||
|
*
|
||||||
|
* @overload
|
||||||
|
*/
|
||||||
|
inline bool giveFromISR() const {
|
||||||
|
return (xSemaphoreGiveFromISR(handle, NULL) == pdTRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
SemaphoreBase() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Semaphore.hpp
|
||||||
|
*
|
||||||
|
* @brief Destroy the SemaphoreBase object by calling <tt>void
|
||||||
|
* vSemaphoreDelete( SemaphoreHandle_t xSemaphore )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/a00113.html#vSemaphoreDelete>
|
||||||
|
*
|
||||||
|
* @note Do not delete a semaphore that has tasks blocked on it (tasks that
|
||||||
|
* are in the Blocked state waiting for the semaphore to become available).
|
||||||
|
*/
|
||||||
|
~SemaphoreBase() { vSemaphoreDelete(this->handle); }
|
||||||
|
|
||||||
|
SemaphoreBase(SemaphoreBase&&) noexcept = default;
|
||||||
|
SemaphoreBase& operator=(SemaphoreBase&&) noexcept = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Handle used to refer to the semaphore when using the FreeRTOS
|
||||||
|
* interface.
|
||||||
|
*/
|
||||||
|
SemaphoreHandle_t handle = NULL;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class BinarySemaphore Semaphore.hpp <FreeRTOS/Semaphore.hpp>
|
||||||
|
*
|
||||||
|
* @brief Class that encapsulates the functionality of a FreeRTOS binary
|
||||||
|
* semaphore.
|
||||||
|
*
|
||||||
|
* Each binary semaphore require a small amount of RAM that is used to hold the
|
||||||
|
* semaphore's state. If a binary semaphore is created using
|
||||||
|
* FreeRTOS::BinarySemaphore then the required RAM is automatically allocated
|
||||||
|
* from the FreeRTOS heap. If a binary semaphore is created using
|
||||||
|
* FreeRTOS::StaticBinarySemaphore then the RAM is provided by the application
|
||||||
|
* writer as part of the class and allows the RAM to be statically allocated at
|
||||||
|
* compile time. See the Static Vs Dynamic allocation page for more information.
|
||||||
|
*
|
||||||
|
* The semaphore is created in the 'empty' state, meaning the semaphore must
|
||||||
|
* first be given using the give() API function before it can subsequently be
|
||||||
|
* taken (obtained) using the take() function.
|
||||||
|
*
|
||||||
|
* Binary semaphores and mutexes are very similar but have some subtle
|
||||||
|
* differences: Mutexes include a priority inheritance mechanism, binary
|
||||||
|
* semaphores do not. This makes binary semaphores the better choice for
|
||||||
|
* implementing synchronisation (between tasks or between tasks and an
|
||||||
|
* interrupt), and mutexes the better choice for implementing simple mutual
|
||||||
|
* exclusion.
|
||||||
|
*
|
||||||
|
* A binary semaphore need not be given back once obtained, so task
|
||||||
|
* synchronisation can be implemented by one task/interrupt continuously
|
||||||
|
* 'giving' the semaphore while another continuously 'takes' the semaphore. This
|
||||||
|
* is demonstrated by the sample code on the giveFromISR() documentation page.
|
||||||
|
* Note the same functionality can often be achieved in a more efficient way
|
||||||
|
* using a direct to task notification.
|
||||||
|
*
|
||||||
|
* The priority of a task that 'takes' a mutex can potentially be raised if
|
||||||
|
* another task of higher priority attempts to obtain the same mutex. The task
|
||||||
|
* that owns the mutex 'inherits' the priority of the task attempting to 'take'
|
||||||
|
* the same mutex. This means the mutex must always be 'given' back - otherwise
|
||||||
|
* the higher priority task will never be able to obtain the mutex, and the
|
||||||
|
* lower priority task will never 'disinherit' the priority. An example of a
|
||||||
|
* mutex being used to implement mutual exclusion is provided on the take()
|
||||||
|
* documentation page.
|
||||||
|
*/
|
||||||
|
class BinarySemaphore : public SemaphoreBase {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Semaphore.hpp
|
||||||
|
*
|
||||||
|
* @brief Construct a new BinarySemaphore object by calling
|
||||||
|
* <tt>SemaphoreHandle_t xSemaphoreCreateBinary( void )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xSemaphoreCreateBinary.html>
|
||||||
|
*
|
||||||
|
* @warning The user should call isValid() on this object to verify that the
|
||||||
|
* binary semaphore was created successfully in case the memory required to
|
||||||
|
* create the queue could not be allocated.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Semaphore/binarySemaphore.cpp
|
||||||
|
*/
|
||||||
|
BinarySemaphore() { this->handle = xSemaphoreCreateBinary(); }
|
||||||
|
~BinarySemaphore() = default;
|
||||||
|
|
||||||
|
BinarySemaphore(const BinarySemaphore&) = delete;
|
||||||
|
BinarySemaphore& operator=(const BinarySemaphore&) = delete;
|
||||||
|
|
||||||
|
BinarySemaphore(BinarySemaphore&&) noexcept = default;
|
||||||
|
BinarySemaphore& operator=(BinarySemaphore&&) noexcept = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class CountingSemaphore Semaphore.hpp <FreeRTOS/Semaphore.hpp>
|
||||||
|
*
|
||||||
|
* @brief Class that encapsulates the functionality of a FreeRTOS counting
|
||||||
|
* semaphore.
|
||||||
|
*
|
||||||
|
* Each counting semaphore require a small amount of RAM that is used to hold
|
||||||
|
* the semaphore's state. If a counting semaphore is created using
|
||||||
|
* FreeRTOS::CountingSemaphore then the required RAM is automatically allocated
|
||||||
|
* from the FreeRTOS heap. If a counting semaphore is created using
|
||||||
|
* FreeRTOS::StaticCountingSemaphore then the RAM is provided by the application
|
||||||
|
* writer as part of the class and allows the RAM to be statically allocated at
|
||||||
|
* compile time. See the Static Vs Dynamic allocation page for more information.
|
||||||
|
*
|
||||||
|
* Counting semaphores are typically used for two things:
|
||||||
|
* 1. <b>Counting Events:</b>
|
||||||
|
* In this usage scenario an event handler will 'give' a semaphore each time an
|
||||||
|
* event occurs (incrementing the semaphore count value), and a handler task
|
||||||
|
* will 'take' a semaphore each time it processes an event (decrementing the
|
||||||
|
* semaphore count value). The count value is therefore the difference between
|
||||||
|
* the number of events that have occurred and the number that have been
|
||||||
|
* processed. In this case it is desirable for the initial count value to be
|
||||||
|
* zero. Note the same functionality can often be achieved in a more efficient
|
||||||
|
* way using a direct to task notification.
|
||||||
|
*
|
||||||
|
* 2. <b>Resource Management:</b>
|
||||||
|
* In this usage scenario the count value indicates the number of resources
|
||||||
|
* available. To obtain control of a resource a task must first obtain a
|
||||||
|
* semaphore - decrementing the semaphore count value. When the count value
|
||||||
|
* reaches zero there are no free resources. When a task finishes with the
|
||||||
|
* resource it 'gives' the semaphore back - incrementing the semaphore count
|
||||||
|
* value. In this case it is desirable for the initial count value to be equal
|
||||||
|
* to the maximum count value, indicating that all resources are free.
|
||||||
|
*/
|
||||||
|
class CountingSemaphore : public SemaphoreBase {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Semaphore.hpp
|
||||||
|
*
|
||||||
|
* @brief Construct a new CountingSemaphore by calling
|
||||||
|
* <tt>SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount,
|
||||||
|
* UBaseType_t uxInitialCount)</tt>
|
||||||
|
*
|
||||||
|
* @warning The user should call isValid() on this object to verify that the
|
||||||
|
* binary semaphore was created successfully in case the memory required to
|
||||||
|
* create the queue could not be allocated.
|
||||||
|
*
|
||||||
|
* @param maxCount The maximum count value that can be reached. When the
|
||||||
|
* semaphore reaches this value it can no longer be 'given'.
|
||||||
|
* @param initialCount The count value assigned to the semaphore when
|
||||||
|
* it is created.
|
||||||
|
*/
|
||||||
|
explicit CountingSemaphore(const UBaseType_t maxCount,
|
||||||
|
const UBaseType_t initialCount = 0) {
|
||||||
|
this->handle = xSemaphoreCreateCounting(maxCount, initialCount);
|
||||||
|
}
|
||||||
|
~CountingSemaphore() = default;
|
||||||
|
|
||||||
|
CountingSemaphore(const CountingSemaphore&) = delete;
|
||||||
|
CountingSemaphore& operator=(const CountingSemaphore&) = delete;
|
||||||
|
|
||||||
|
CountingSemaphore(CountingSemaphore&&) noexcept = default;
|
||||||
|
CountingSemaphore& operator=(CountingSemaphore&&) noexcept = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||||
|
|
||||||
|
#if (configSUPPORT_STATIC_ALLOCATION == 1)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class StaticBinarySemaphore Semaphore.hpp <FreeRTOS/Semaphore.hpp>
|
||||||
|
*
|
||||||
|
* @brief Class that encapsulates the functionality of a FreeRTOS binary
|
||||||
|
* semaphore.
|
||||||
|
*
|
||||||
|
* Each binary semaphore require a small amount of RAM that is used to hold the
|
||||||
|
* semaphore's state. If a binary semaphore is created using
|
||||||
|
* FreeRTOS::BinarySemaphore then the required RAM is automatically allocated
|
||||||
|
* from the FreeRTOS heap. If a binary semaphore is created using
|
||||||
|
* FreeRTOS::StaticBinarySemaphore then the RAM is provided by the application
|
||||||
|
* writer as part of the class and allows the RAM to be statically allocated at
|
||||||
|
* compile time. See the Static Vs Dynamic allocation page for more information.
|
||||||
|
*
|
||||||
|
* The semaphore is created in the 'empty' state, meaning the semaphore must
|
||||||
|
* first be given using the give() API function before it can subsequently be
|
||||||
|
* taken (obtained) using the take() function.
|
||||||
|
*
|
||||||
|
* Binary semaphores and mutexes are very similar but have some subtle
|
||||||
|
* differences: Mutexes include a priority inheritance mechanism, binary
|
||||||
|
* semaphores do not. This makes binary semaphores the better choice for
|
||||||
|
* implementing synchronisation (between tasks or between tasks and an
|
||||||
|
* interrupt), and mutexes the better choice for implementing simple mutual
|
||||||
|
* exclusion.
|
||||||
|
*
|
||||||
|
* A binary semaphore need not be given back once obtained, so task
|
||||||
|
* synchronisation can be implemented by one task/interrupt continuously
|
||||||
|
* 'giving' the semaphore while another continuously 'takes' the semaphore. This
|
||||||
|
* is demonstrated by the sample code on the giveFromISR() documentation page.
|
||||||
|
* Note the same functionality can often be achieved in a more efficient way
|
||||||
|
* using a direct to task notification.
|
||||||
|
*
|
||||||
|
* The priority of a task that 'takes' a mutex can potentially be raised if
|
||||||
|
* another task of higher priority attempts to obtain the same mutex. The task
|
||||||
|
* that owns the mutex 'inherits' the priority of the task attempting to 'take'
|
||||||
|
* the same mutex. This means the mutex must always be 'given' back - otherwise
|
||||||
|
* the higher priority task will never be able to obtain the mutex, and the
|
||||||
|
* lower priority task will never 'disinherit' the priority. An example of a
|
||||||
|
* mutex being used to implement mutual exclusion is provided on the take()
|
||||||
|
* documentation page.
|
||||||
|
*/
|
||||||
|
class StaticBinarySemaphore : public SemaphoreBase {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Semaphore.hpp
|
||||||
|
*
|
||||||
|
* @brief Construct a new StaticBinarySemaphore object by calling
|
||||||
|
* <tt>SemaphoreHandle_t xSemaphoreCreateBinaryStatic( StaticSemaphore_t
|
||||||
|
* *pxSemaphoreBuffer )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xSemaphoreCreateBinaryStatic.html>
|
||||||
|
*
|
||||||
|
* @warning This class contains the storage buffer for the binary semaphore,
|
||||||
|
* so the user should create this object as a global object or with the static
|
||||||
|
* storage specifier so that the object instance is not on the stack.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Semaphore/staticBinarySemaphore.cpp
|
||||||
|
*/
|
||||||
|
StaticBinarySemaphore() {
|
||||||
|
this->handle = xSemaphoreCreateBinaryStatic(&staticBinarySemaphore);
|
||||||
|
}
|
||||||
|
~StaticBinarySemaphore() = default;
|
||||||
|
|
||||||
|
StaticBinarySemaphore(const StaticBinarySemaphore&) = delete;
|
||||||
|
StaticBinarySemaphore& operator=(const StaticBinarySemaphore&) = delete;
|
||||||
|
|
||||||
|
StaticBinarySemaphore(StaticBinarySemaphore&&) noexcept = default;
|
||||||
|
StaticBinarySemaphore& operator=(StaticBinarySemaphore&&) noexcept = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
StaticSemaphore_t staticBinarySemaphore;
|
||||||
|
};
|
||||||
|
|
||||||
|
class StaticCountingSemaphore : public SemaphoreBase {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Construct a new StaticCountingSemaphore object by calling
|
||||||
|
* <tt>SemaphoreHandle_t xSemaphoreCreateCountingStatic( UBaseType_t
|
||||||
|
* uxMaxCount, UBaseType_t uxInitialCount, StaticSemaphore_t
|
||||||
|
* *pxSemaphoreBuffer )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xSemaphoreCreateCountingStatic.html>
|
||||||
|
*
|
||||||
|
* @warning This class contains the storage buffer for the counting semaphore,
|
||||||
|
* so the user should create this object as a global object or with the static
|
||||||
|
* storage specifier so that the object instance is not on the stack.
|
||||||
|
*
|
||||||
|
* @param maxCount The maximum count value that can be reached. When the
|
||||||
|
* semaphore reaches this value it can no longer be 'given'.
|
||||||
|
* @param initialCount The count value assigned to the semaphore when it is
|
||||||
|
* created.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Semaphore/staticCountingSemaphore.cpp
|
||||||
|
*/
|
||||||
|
explicit StaticCountingSemaphore(const UBaseType_t maxCount,
|
||||||
|
const UBaseType_t initialCount = 0) {
|
||||||
|
this->handle = xSemaphoreCreateCountingStatic(maxCount, initialCount,
|
||||||
|
&staticCountingSemaphore);
|
||||||
|
}
|
||||||
|
~StaticCountingSemaphore() = default;
|
||||||
|
|
||||||
|
StaticCountingSemaphore(const StaticCountingSemaphore&) = delete;
|
||||||
|
StaticCountingSemaphore& operator=(const StaticCountingSemaphore&) = delete;
|
||||||
|
|
||||||
|
StaticCountingSemaphore(StaticCountingSemaphore&&) noexcept = default;
|
||||||
|
StaticCountingSemaphore& operator=(StaticCountingSemaphore&&) noexcept =
|
||||||
|
default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
StaticSemaphore_t staticCountingSemaphore;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||||
|
|
||||||
|
} // namespace FreeRTOS
|
||||||
|
|
||||||
|
#endif // FREERTOS_SEMAPHORE_HPP
|
|
@ -0,0 +1,566 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS-Cpp
|
||||||
|
* Copyright (C) 2021 Jon Enz. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://github.com/jonenz/FreeRTOS-Cpp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FREERTOS_STREAMBUFFER_HPP
|
||||||
|
#define FREERTOS_STREAMBUFFER_HPP
|
||||||
|
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "stream_buffer.h"
|
||||||
|
|
||||||
|
namespace FreeRTOS {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class StreamBufferBase StreamBuffer.hpp <FreeRTOS/StreamBuffer.hpp>
|
||||||
|
*
|
||||||
|
* @brief Base class that provides the standard stream buffer interface to
|
||||||
|
* FreeRTOS::StreamBuffer and FreeRTOS::StaticStreamBuffer.
|
||||||
|
*
|
||||||
|
* @note This class is not intended to be instantiated by the user. Use
|
||||||
|
* FreeRTOS::StreamBuffer or FreeRTOS::StaticStreamBuffer.
|
||||||
|
*
|
||||||
|
* @warning Uniquely among FreeRTOS objects, the stream buffer implementation
|
||||||
|
* (so also the message buffer implementation, as message buffers are built on
|
||||||
|
* top of stream buffers) assumes there is only one task or interrupt that will
|
||||||
|
* write to the buffer (the writer), and only one task or interrupt that will
|
||||||
|
* read from the buffer (the reader). It is safe for the writer and reader to
|
||||||
|
* be different tasks or interrupts, but, unlike other FreeRTOS objects, it is
|
||||||
|
* not safe to have multiple different writers or multiple different readers. If
|
||||||
|
* there are to be multiple different writers then the application writer must
|
||||||
|
* place each call to a writing API function (such as send()) inside a critical
|
||||||
|
* section and set the send block time to 0. Likewise, if there are to be
|
||||||
|
* multiple different readers then the application writer must place each call
|
||||||
|
* to a reading API function (such as read()) inside a critical section and set
|
||||||
|
* the receive block time to 0.
|
||||||
|
*/
|
||||||
|
class StreamBufferBase {
|
||||||
|
public:
|
||||||
|
friend class StreamBuffer;
|
||||||
|
template <size_t>
|
||||||
|
friend class StaticStreamBuffer;
|
||||||
|
|
||||||
|
StreamBufferBase(const StreamBufferBase&) = delete;
|
||||||
|
StreamBufferBase& operator=(const StreamBufferBase&) = delete;
|
||||||
|
|
||||||
|
static void* operator new(size_t, void* ptr) { return ptr; }
|
||||||
|
static void* operator new[](size_t, void* ptr) { return ptr; }
|
||||||
|
static void* operator new(size_t) = delete;
|
||||||
|
static void* operator new[](size_t) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StreamBuffer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that checks if the underlying stream buffer handle is not
|
||||||
|
* NULL. This should be used to ensure a stream buffer has been created
|
||||||
|
* correctly.
|
||||||
|
*
|
||||||
|
* @retval true If the handle is not NULL.
|
||||||
|
* @retval false If the handle is NULL.
|
||||||
|
*/
|
||||||
|
inline bool isValid() const { return (handle != NULL); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StreamBuffer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>size_t xStreamBufferSend(
|
||||||
|
* StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t
|
||||||
|
* xDataLengthBytes, TickType_t xTicksToWait )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xStreamBufferSend.html>
|
||||||
|
*
|
||||||
|
* Sends bytes to a stream buffer. The bytes are copied into the stream
|
||||||
|
* buffer.
|
||||||
|
*
|
||||||
|
* Use send() to write to a stream buffer from a task. Use sendFromISR() to
|
||||||
|
* write to a stream buffer from an interrupt service routine (ISR).
|
||||||
|
*
|
||||||
|
* @param data A pointer to the buffer that holds the bytes to be copied into
|
||||||
|
* the stream buffer.
|
||||||
|
* @param length The maximum number of bytes to copy from data into the stream
|
||||||
|
* buffer.
|
||||||
|
* @param ticksToWait The maximum amount of time the task should remain in the
|
||||||
|
* Blocked state to wait for enough space to become available in the stream
|
||||||
|
* buffer, should the stream buffer contain too little space to hold the
|
||||||
|
* another length bytes. The block time is specified in tick periods, so the
|
||||||
|
* absolute time it represents is dependent on the tick frequency. The macro
|
||||||
|
* pdMS_TO_TICKS() can be used to convert a time specified in milliseconds
|
||||||
|
* into a time specified in ticks. Setting ticksToWait to portMAX_DELAY will
|
||||||
|
* cause the task to wait indefinitely (without timing out), provided
|
||||||
|
* INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. If a task times out
|
||||||
|
* before it can write all length into the buffer it will still write as many
|
||||||
|
* bytes as possible. A task does not use any CPU time when it is in the
|
||||||
|
* blocked state.
|
||||||
|
* @return size_t The number of bytes written to the stream buffer. If a task
|
||||||
|
* times out before it can write all length into the buffer it will still
|
||||||
|
* write as many bytes as possible.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include StreamBuffer/send.cpp
|
||||||
|
*/
|
||||||
|
inline size_t send(const void* data, const size_t length,
|
||||||
|
const TickType_t ticksToWait = portMAX_DELAY) const {
|
||||||
|
return xStreamBufferSend(handle, data, length, ticksToWait);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StreamBuffer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>size_t xStreamBufferSendFromISR(
|
||||||
|
* StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t
|
||||||
|
* xDataLengthBytes, BaseType_t *pxHigherPriorityTaskWoken )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xStreamBufferSendFromISR.html>
|
||||||
|
*
|
||||||
|
* Interrupt safe version of the API function that sends a stream of bytes to
|
||||||
|
* the stream buffer.
|
||||||
|
*
|
||||||
|
* Use send() to write to a stream buffer from a task. Use sendFromISR() to
|
||||||
|
* write to a stream buffer from an interrupt service routine (ISR).
|
||||||
|
*
|
||||||
|
* @param higherPriorityTaskWoken It is possible that a stream buffer will
|
||||||
|
* have a task blocked on it waiting for data. Calling sendFromISR() can make
|
||||||
|
* data available, and so cause a task that was waiting for data to leave the
|
||||||
|
* Blocked state. If calling sendFromISR() causes a task to leave the Blocked
|
||||||
|
* state, and the unblocked task has a priority higher than the currently
|
||||||
|
* executing task (the task that was interrupted), then, internally,
|
||||||
|
* sendFromISR() will set higherPriorityTaskWoken to true. If sendFromISR()
|
||||||
|
* sets this value to true, then normally a context switch should be performed
|
||||||
|
* before the interrupt is exited. This will ensure that the interrupt
|
||||||
|
* returns directly to the highest priority Ready state task.
|
||||||
|
* higherPriorityTaskWoken should be set to false before it is passed into the
|
||||||
|
* function. See the example code below for an example.
|
||||||
|
* @param data A pointer to the buffer that holds the bytes to be copied into
|
||||||
|
* the stream buffer.
|
||||||
|
* @param length The maximum number of bytes to copy from data into the stream
|
||||||
|
* buffer.
|
||||||
|
* @return size_t The number of bytes written to the stream buffer. If a task
|
||||||
|
* times out before it can write all length into the buffer it will still
|
||||||
|
* write as many bytes as possible.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include StreamBuffer/sendFromISR.cpp
|
||||||
|
*/
|
||||||
|
inline size_t sendFromISR(bool& higherPriorityTaskWoken, const void* data,
|
||||||
|
const size_t length) const {
|
||||||
|
BaseType_t taskWoken = pdFALSE;
|
||||||
|
size_t result = xStreamBufferSendFromISR(handle, data, length, &taskWoken);
|
||||||
|
if (taskWoken == pdTRUE) {
|
||||||
|
higherPriorityTaskWoken = true;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StreamBuffer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>size_t xStreamBufferSendFromISR(
|
||||||
|
* StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t
|
||||||
|
* xDataLengthBytes, BaseType_t *pxHigherPriorityTaskWoken )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xStreamBufferSendFromISR.html>
|
||||||
|
*
|
||||||
|
* @overload
|
||||||
|
*/
|
||||||
|
inline size_t sendFromISR(const void* data, const size_t length) const {
|
||||||
|
return xStreamBufferSendFromISR(handle, data, length, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StreamBuffer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>size_t xStreamBufferReceive(
|
||||||
|
* StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t
|
||||||
|
* xBufferLengthBytes, TickType_t xTicksToWait )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xStreamBufferReceive.html>
|
||||||
|
*
|
||||||
|
* Receives bytes from a stream buffer.
|
||||||
|
*
|
||||||
|
* Use receive() to read from a stream buffer from a task. Use
|
||||||
|
* receiveFromISR() to read from a stream buffer from an interrupt service
|
||||||
|
* routine (ISR).
|
||||||
|
*
|
||||||
|
* @param buffer A pointer to the buffer into which the received bytes will be
|
||||||
|
* copied.
|
||||||
|
* @param bufferLength The length of the buffer pointed to by the data
|
||||||
|
* parameter. This sets the maximum number of bytes to receive in one call.
|
||||||
|
* receive() will return as many bytes as possible up to a maximum set by
|
||||||
|
* length.
|
||||||
|
* @param ticksToWait The maximum amount of time the task should remain in the
|
||||||
|
* Blocked state to wait for data to become available if the stream buffer is
|
||||||
|
* empty. receive() will return immediately if ticksToWait is zero. The block
|
||||||
|
* time is specified in tick periods, so the absolute time it represents is
|
||||||
|
* dependent on the tick frequency. The macro pdMS_TO_TICKS() can be used to
|
||||||
|
* convert a time specified in milliseconds into a time specified in ticks.
|
||||||
|
* Setting ticksToWait to portMAX_DELAY will cause the task to wait
|
||||||
|
* indefinitely (without timing out), provided INCLUDE_vTaskSuspend is set to
|
||||||
|
* 1 in FreeRTOSConfig.h. A task does not use any CPU time when it is in the
|
||||||
|
* Blocked state.
|
||||||
|
* @return size_t The number of bytes read from the stream buffer. This will
|
||||||
|
* be the number of bytes available up to a maximum of length.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include StreamBuffer/receive.cpp
|
||||||
|
*/
|
||||||
|
inline size_t receive(void* buffer, const size_t bufferLength,
|
||||||
|
const TickType_t ticksToWait = portMAX_DELAY) const {
|
||||||
|
return xStreamBufferReceive(handle, buffer, bufferLength, ticksToWait);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StreamBuffer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>size_t xStreamBufferReceiveFromISR(
|
||||||
|
* StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t
|
||||||
|
* xBufferLengthBytes, BaseType_t *pxHigherPriorityTaskWoken )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xStreamBufferReceiveFromISR.html>
|
||||||
|
*
|
||||||
|
* An interrupt safe version of the API function that receives bytes from a
|
||||||
|
* stream buffer.
|
||||||
|
*
|
||||||
|
* Use receive() to read from a stream buffer from a task. Use
|
||||||
|
* receiveFromISR() to read from a stream buffer from an interrupt service
|
||||||
|
* routine (ISR).
|
||||||
|
*
|
||||||
|
* @param higherPriorityTaskWoken It is possible that a stream buffer will
|
||||||
|
* have a task blocked on it waiting for space to become available. Calling
|
||||||
|
* receiveFromISR() can make space available, and so cause a task that is
|
||||||
|
* waiting for space to leave the Blocked state. If calling receiveFromISR()
|
||||||
|
* causes a task to leave the Blocked state, and the unblocked task has a
|
||||||
|
* priority higher than the currently executing task (the task that was
|
||||||
|
* interrupted), then, internally, receiveFromISR() will set
|
||||||
|
* higherPriorityTaskWoken to true. If receiveFromISR() sets this value to
|
||||||
|
* true, then normally a context switch should be performed before the
|
||||||
|
* interrupt is exited. That will ensure the interrupt returns directly to the
|
||||||
|
* highest priority Ready state task. higherPriorityTaskWoken should be set to
|
||||||
|
* false before it is passed into the function. See the code example below for
|
||||||
|
* an example.
|
||||||
|
* @param buffer A pointer to the buffer into which the received bytes will be
|
||||||
|
* copied.
|
||||||
|
* @param bufferLength The length of the buffer pointed to by the buffer
|
||||||
|
* parameter. This sets the maximum number of bytes to receive in one call.
|
||||||
|
* receive() will return as many bytes as possible up to a maximum set by
|
||||||
|
* length.
|
||||||
|
* @return size_t The number of bytes read from the stream buffer, if any.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include StreamBuffer/receiveFromISR.cpp
|
||||||
|
*/
|
||||||
|
inline size_t receiveFromISR(bool& higherPriorityTaskWoken, void* buffer,
|
||||||
|
const size_t bufferLength) const {
|
||||||
|
BaseType_t taskWoken = pdFALSE;
|
||||||
|
size_t result =
|
||||||
|
xStreamBufferReceiveFromISR(handle, buffer, bufferLength, &taskWoken);
|
||||||
|
if (taskWoken == pdTRUE) {
|
||||||
|
higherPriorityTaskWoken = true;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StreamBuffer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>size_t xStreamBufferReceiveFromISR(
|
||||||
|
* StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t
|
||||||
|
* xBufferLengthBytes, BaseType_t *pxHigherPriorityTaskWoken )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xStreamBufferReceiveFromISR.html>
|
||||||
|
*
|
||||||
|
* @overload
|
||||||
|
*/
|
||||||
|
inline size_t receiveFromISR(void* buffer, const size_t bufferLength) const {
|
||||||
|
return xStreamBufferReceiveFromISR(handle, buffer, bufferLength, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StreamBuffer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>size_t xStreamBufferBytesAvailable(
|
||||||
|
* StreamBufferHandle_t xStreamBuffer )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xStreamBufferBytesAvailable.html>
|
||||||
|
*
|
||||||
|
* Queries the stream buffer to see how much data it contains, which is equal
|
||||||
|
* to the number of bytes that can be read from the stream buffer before the
|
||||||
|
* stream buffer would be empty.
|
||||||
|
*
|
||||||
|
* @return size_t The number of bytes that can be read from the stream buffer
|
||||||
|
* before the stream buffer would be empty.
|
||||||
|
*/
|
||||||
|
inline size_t bytesAvailable() const {
|
||||||
|
return xStreamBufferBytesAvailable(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StreamBuffer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>size_t xStreamBufferSpacesAvailable(
|
||||||
|
* StreamBufferHandle_t xStreamBuffer )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xStreamBufferSpacesAvailable.html>
|
||||||
|
*
|
||||||
|
* Queries a stream buffer to see how much free space it contains, which is
|
||||||
|
* equal to the amount of data that can be sent to the stream buffer before it
|
||||||
|
* is full.
|
||||||
|
*
|
||||||
|
* @return size_t The number of bytes that can be written to the stream buffer
|
||||||
|
* before the stream buffer would be full.
|
||||||
|
*/
|
||||||
|
inline size_t spacesAvailable() const {
|
||||||
|
return xStreamBufferSpacesAvailable(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StreamBuffer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>BaseType_t xStreamBufferSetTriggerLevel(
|
||||||
|
* StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xStreamBufferSetTriggerLevel.html>
|
||||||
|
*
|
||||||
|
* A stream buffer's trigger level is the number of bytes that must be in the
|
||||||
|
* stream buffer before a task that is blocked on the stream buffer to wait
|
||||||
|
* for data is moved out of the blocked state. For example, if a task is
|
||||||
|
* blocked on a read of an empty stream buffer that has a trigger level of 1
|
||||||
|
* then the task will be unblocked when a single byte is written to the buffer
|
||||||
|
* or the task's block time expires. As another example, if a task is blocked
|
||||||
|
* on a read of an empty stream buffer that has a trigger level of 10 then the
|
||||||
|
* task will not be unblocked until the stream buffer contains at least 10
|
||||||
|
* bytes or the task's block time expires. If a reading task's block time
|
||||||
|
* expires before the trigger level is reached then the task will still
|
||||||
|
* receive however many bytes are actually available. Setting a trigger level
|
||||||
|
* of 0 will result in a trigger level of 1 being used. It is not valid to
|
||||||
|
* specify a trigger level that is greater than the buffer size.
|
||||||
|
*
|
||||||
|
* @param triggerLevel The new trigger level for the stream buffer.
|
||||||
|
* @retval true If triggerLevel was less than or equal to the stream buffer's
|
||||||
|
* length then the trigger level was updated.
|
||||||
|
* @retval false Otherwise.
|
||||||
|
*/
|
||||||
|
inline bool setTriggerLevel(const size_t triggerLevel = 0) const {
|
||||||
|
return (xStreamBufferSetTriggerLevel(handle, triggerLevel) == pdTRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StreamBuffer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>BaseType_t xStreamBufferReset(
|
||||||
|
* StreamBufferHandle_t xStreamBuffer )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xStreamBufferReset.html>
|
||||||
|
*
|
||||||
|
* Resets a stream buffer to its initial, empty, state. Any data that was in
|
||||||
|
* the stream buffer is discarded. A stream buffer can only be reset if there
|
||||||
|
* are no tasks blocked waiting to either send to or receive from the stream
|
||||||
|
* buffer.
|
||||||
|
*
|
||||||
|
* @return true If the stream buffer is reset.
|
||||||
|
* @return false If there was a task blocked waiting to send to or read from
|
||||||
|
* the stream buffer then the stream buffer was not reset.
|
||||||
|
*/
|
||||||
|
inline bool reset() const { return (xStreamBufferReset(handle) == pdPASS); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StreamBuffer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>BaseType_t xStreamBufferIsEmpty(
|
||||||
|
* StreamBufferHandle_t xStreamBuffer )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xStreamBufferIsEmpty.html>
|
||||||
|
*
|
||||||
|
* Queries a stream buffer to see if it is empty. A stream buffer is empty if
|
||||||
|
* it does not contain any data.
|
||||||
|
*
|
||||||
|
* @return true If the stream buffer is empty.
|
||||||
|
* @return false Otherwise.
|
||||||
|
*/
|
||||||
|
inline bool isEmpty() const {
|
||||||
|
return (xStreamBufferIsEmpty(handle) == pdTRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StreamBuffer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>BaseType_t xStreamBufferIsFull(
|
||||||
|
* StreamBufferHandle_t xStreamBuffer )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xStreamBufferIsFull.html>
|
||||||
|
*
|
||||||
|
* Queries a stream buffer to see if it is full. A stream buffer is full if it
|
||||||
|
* does not have any free space, and therefore cannot accept any more data.
|
||||||
|
*
|
||||||
|
* @return true If the stream buffer is full.
|
||||||
|
* @return false Otherwise.
|
||||||
|
*/
|
||||||
|
inline bool isFull() const { return (xStreamBufferIsFull(handle) == pdTRUE); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
StreamBufferBase() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StreamBuffer.hpp
|
||||||
|
*
|
||||||
|
* @brief Destroy the StreamBufferBase object by calling
|
||||||
|
* <tt>void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/vStreamBufferDelete.html>
|
||||||
|
*
|
||||||
|
* Deletes a stream buffer and free the allocated memory.
|
||||||
|
*/
|
||||||
|
~StreamBufferBase() { vStreamBufferDelete(this->handle); }
|
||||||
|
|
||||||
|
StreamBufferBase(StreamBufferBase&&) noexcept = default;
|
||||||
|
StreamBufferBase& operator=(StreamBufferBase&&) noexcept = default;
|
||||||
|
|
||||||
|
StreamBufferHandle_t handle = NULL;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class StreamBuffer StreamBuffer.hpp <FreeRTOS/StreamBuffer.hpp>
|
||||||
|
*
|
||||||
|
* @brief Class that encapsulates the functionality of a FreeRTOS stream buffer.
|
||||||
|
*
|
||||||
|
* A stream buffer using dynamically allocated memory from the FreeRTOS heap.
|
||||||
|
* See FreeRTOS::StaticStreamBuffer for a version that uses statically allocated
|
||||||
|
* memory (memory that is allocated at compile time).
|
||||||
|
*/
|
||||||
|
class StreamBuffer : public StreamBufferBase {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* StreamBuffer.hpp
|
||||||
|
*
|
||||||
|
* @brief Construct a new StreamBuffer object by calling
|
||||||
|
* <tt>StreamBufferHandle_t xStreamBufferCreate( size_t xBufferSizeBytes,
|
||||||
|
* size_t xTriggerLevelBytes )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xStreamBufferCreate.html>
|
||||||
|
*
|
||||||
|
* @warning The user should call isValid() on this object to verify that the
|
||||||
|
* stream buffer was created successfully in case the memory required to
|
||||||
|
* create the message buffer could not be allocated.
|
||||||
|
*
|
||||||
|
* @param size The total number of bytes the stream buffer will be able to
|
||||||
|
* hold at any one time.
|
||||||
|
* @param triggerLevel The number of bytes that must be in the stream
|
||||||
|
* buffer before a task that is blocked on the stream buffer to wait for data
|
||||||
|
* is moved out of the blocked state. For example, if a task is blocked on a
|
||||||
|
* read of an empty stream buffer that has a trigger level of 1 then the task
|
||||||
|
* will be unblocked when a single byte is written to the buffer or the task's
|
||||||
|
* block time expires. As another example, if a task is blocked on a read of
|
||||||
|
* an empty stream buffer that has a trigger level of 10 then the task will
|
||||||
|
* not be unblocked until the stream buffer contains at least 10 bytes or the
|
||||||
|
* task's block time expires. If a reading task's block time expires before
|
||||||
|
* the trigger level is reached then the task will still receive however many
|
||||||
|
* bytes are actually available. Setting a trigger level of 0 will result in a
|
||||||
|
* trigger level of 1 being used. It is not valid to specify a trigger level
|
||||||
|
* that is greater than the buffer size.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include StreamBuffer/streamBuffer.cpp
|
||||||
|
*/
|
||||||
|
explicit StreamBuffer(const size_t size, const size_t triggerLevel = 0) {
|
||||||
|
this->handle = xStreamBufferCreate(size, triggerLevel);
|
||||||
|
}
|
||||||
|
~StreamBuffer() = default;
|
||||||
|
|
||||||
|
StreamBuffer(const StreamBuffer&) = delete;
|
||||||
|
StreamBuffer& operator=(const StreamBuffer&) = delete;
|
||||||
|
|
||||||
|
StreamBuffer(StreamBuffer&&) noexcept = default;
|
||||||
|
StreamBuffer& operator=(StreamBuffer&&) noexcept = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||||
|
|
||||||
|
#if (configSUPPORT_STATIC_ALLOCATION == 1)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class StaticStreamBuffer StreamBuffer.hpp <FreeRTOS/StreamBuffer.hpp>
|
||||||
|
*
|
||||||
|
* @brief Class that encapsulates the functionality of a FreeRTOS stream buffer.
|
||||||
|
*
|
||||||
|
* If a stream buffer is created using this class then the RAM is provided by
|
||||||
|
* the application writer as part of the object instance and allows the RAM to
|
||||||
|
* be statically allocated at compile time.
|
||||||
|
*
|
||||||
|
* @tparam N The size, in bytes, of the storage buffer for the stream buffer.
|
||||||
|
*/
|
||||||
|
template <size_t N>
|
||||||
|
class StaticStreamBuffer : public StreamBufferBase {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* StreamBuffer.hpp
|
||||||
|
*
|
||||||
|
* @brief Construct a new StaticStreamBuffer object by calling
|
||||||
|
* <tt>StreamBufferHandle_t xStreamBufferCreateStatic( size_t
|
||||||
|
* xBufferSizeBytes, size_t xTriggerLevelBytes, uint8_t
|
||||||
|
* *pucStreamBufferStorageArea, StaticStreamBuffer_t *pxStaticStreamBuffer
|
||||||
|
* )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xStreamBufferCreateStatic.html>
|
||||||
|
*
|
||||||
|
* @param triggerLevel The number of bytes that must be in the stream
|
||||||
|
* buffer before a task that is blocked on the stream buffer to wait for data
|
||||||
|
* is moved out of the blocked state. For example, if a task is blocked on a
|
||||||
|
* read of an empty stream buffer that has a trigger level of 1 then the task
|
||||||
|
* will be unblocked when a single byte is written to the buffer or the task's
|
||||||
|
* block time expires. As another example, if a task is blocked on a read of
|
||||||
|
* an empty stream buffer that has a trigger level of 10 then the task will
|
||||||
|
* not be unblocked until the stream buffer contains at least 10 bytes or the
|
||||||
|
* task's block time expires. If a reading task's block time expires before
|
||||||
|
* the trigger level is reached then the task will still receive however many
|
||||||
|
* bytes are actually available. Setting a trigger level of 0 will result in a
|
||||||
|
* trigger level of 1 being used. It is not valid to specify a trigger level
|
||||||
|
* that is greater than the buffer size.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include StreamBuffer/staticStreamBuffer.cpp
|
||||||
|
*/
|
||||||
|
explicit StaticStreamBuffer(const size_t triggerLevel = 0) {
|
||||||
|
this->handle = xStreamBufferCreateStatic(sizeof(storage), triggerLevel,
|
||||||
|
storage, &staticStreamBuffer);
|
||||||
|
}
|
||||||
|
~StaticStreamBuffer() = default;
|
||||||
|
|
||||||
|
StaticStreamBuffer(const StaticStreamBuffer&) = delete;
|
||||||
|
StaticStreamBuffer& operator=(const StaticStreamBuffer&) = delete;
|
||||||
|
|
||||||
|
StaticStreamBuffer(StaticStreamBuffer&&) noexcept = default;
|
||||||
|
StaticStreamBuffer& operator=(StaticStreamBuffer&&) noexcept = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
StaticStreamBuffer_t staticStreamBuffer;
|
||||||
|
uint8_t storage[N];
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||||
|
|
||||||
|
} // namespace FreeRTOS
|
||||||
|
|
||||||
|
#endif // FREERTOS_STREAMBUFFER_HPP
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,928 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS-Cpp
|
||||||
|
* Copyright (C) 2021 Jon Enz. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://github.com/jonenz/FreeRTOS-Cpp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FREERTOS_TIMER_HPP
|
||||||
|
#define FREERTOS_TIMER_HPP
|
||||||
|
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "timers.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief C function that is used to interface this class with the FreeRTOS
|
||||||
|
* kernel.
|
||||||
|
*
|
||||||
|
* @note This function should not be called or referenced by the user.
|
||||||
|
*
|
||||||
|
* @param task Pointer to an instance of FreeRTOS::TimerBase.
|
||||||
|
*/
|
||||||
|
void callTimerFunction(TimerHandle_t timer);
|
||||||
|
|
||||||
|
namespace FreeRTOS {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class TimerBase Timer.hpp <FreeRTOS/Timer.hpp>
|
||||||
|
*
|
||||||
|
* @brief Base class that provides the standard task interface to
|
||||||
|
* FreeRTOS::Timer and FreeRTOS::StaticTimer.
|
||||||
|
*
|
||||||
|
* @note This class is not intended to be instantiated or derived from by the
|
||||||
|
* user. Use FreeRTOS::Timer or FreeRTOS::StaticTimer as a base class for a user
|
||||||
|
* implemented task.
|
||||||
|
*/
|
||||||
|
class TimerBase {
|
||||||
|
public:
|
||||||
|
friend class Timer;
|
||||||
|
friend class StaticTimer;
|
||||||
|
|
||||||
|
TimerBase(const TimerBase&) = delete;
|
||||||
|
TimerBase& operator=(const TimerBase&) = delete;
|
||||||
|
|
||||||
|
static void* operator new(size_t, void* ptr) { return ptr; }
|
||||||
|
static void* operator new[](size_t, void* ptr) { return ptr; }
|
||||||
|
static void* operator new(size_t) = delete;
|
||||||
|
static void* operator new[](size_t) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that acts as the entry point of the timer instance.
|
||||||
|
*
|
||||||
|
* @note This function is only public so that it can be accessed by the C
|
||||||
|
* interface function <tt>callTimerFunction()</tt> and should not be called or
|
||||||
|
* referenced by the user.
|
||||||
|
*/
|
||||||
|
virtual inline void timerEntry() final { timerFunction(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that checks the value of the timer handle. This function
|
||||||
|
* should be called to ensure the timer was created successfully.
|
||||||
|
*
|
||||||
|
* @return true If the timer was created successfully.
|
||||||
|
* @return false If the timer was not created successfully due to insufficient
|
||||||
|
* memory.
|
||||||
|
*/
|
||||||
|
inline bool isValid() const { return (handle != NULL); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>BaseType_t xTimerIsTimerActive(
|
||||||
|
* TimerHandle_t xTimer )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/FreeRTOS-timers-xTimerIsTimerActive.html>
|
||||||
|
*
|
||||||
|
* Queries a software timer to see if it is active or dormant.
|
||||||
|
*
|
||||||
|
* A timer will be dormant if:
|
||||||
|
* -# It has been created but not started, or
|
||||||
|
* -# It is an expired one-shot timer that has not been restarted.
|
||||||
|
*
|
||||||
|
* @note Timers are created in the dormant state. The start(), reset(),
|
||||||
|
* startFromISR(), resetFromISR(), changePeriod() and changePeriodFromISR()
|
||||||
|
* API functions can all be used to transition a timer into the active state.
|
||||||
|
*
|
||||||
|
* @return false If the timer is dormant.
|
||||||
|
* @return true Otherwise.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Timer/isActive.cpp
|
||||||
|
*/
|
||||||
|
inline bool isActive() const {
|
||||||
|
return (xTimerIsTimerActive(handle) != pdFALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>BaseType_t xTimerStart( TimerHandle_t
|
||||||
|
* xTimer, TickType_t xBlockTime )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/FreeRTOS-timers-xTimerStart.html>
|
||||||
|
*
|
||||||
|
* start() starts a timer. If the timer had already been started and was
|
||||||
|
* already in the active state, then start() has equivalent functionality to
|
||||||
|
* the reset() API function.
|
||||||
|
*
|
||||||
|
* Starting a timer ensures the timer is in the active state. If the timer is
|
||||||
|
* not stopped, deleted, or reset in the mean time, timerFunction() will get
|
||||||
|
* called 'n 'ticks after start() was called, where 'n' is the timers defined
|
||||||
|
* period.
|
||||||
|
*
|
||||||
|
* It is valid to call start() before the RTOS scheduler has been started, but
|
||||||
|
* when this is done the timer will not actually start until the RTOS
|
||||||
|
* scheduler is started, and the timers expiry time will be relative to when
|
||||||
|
* the RTOS scheduler is started, not relative to when start() was called.
|
||||||
|
*
|
||||||
|
* @param blockTime Specifies the time, in ticks, that the calling task should
|
||||||
|
* be held in the Blocked state to wait for the start command to be
|
||||||
|
* successfully sent to the timer command queue, should the queue already be
|
||||||
|
* full when start() was called. blockTime is ignored if start() is called
|
||||||
|
* before the RTOS scheduler is started.
|
||||||
|
* @return true If the command was successfully sent to the timer command
|
||||||
|
* queue. When the command is actually processed will depend on the priority
|
||||||
|
* of the timer service/daemon task relative to other tasks in the system,
|
||||||
|
* although the timers expiry time is relative to when start() is actually
|
||||||
|
* called. The timer service/daemon task priority is set by the
|
||||||
|
* configTIMER_TASK_PRIORITY configuration constant.
|
||||||
|
* @return false If the start command could not be sent to the timer command
|
||||||
|
* queue even after blockTime ticks had passed.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Timer/timer.cpp
|
||||||
|
*/
|
||||||
|
inline bool start(const TickType_t blockTime = 0) const {
|
||||||
|
return (xTimerStart(handle, blockTime) == pdPASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>BaseType_t xTimerStartFromISR( TimerHandle_t
|
||||||
|
* xTimer, BaseType_t *pxHigherPriorityTaskWoken )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/FreeRTOS-timers-xTimerStartFromISR.html>
|
||||||
|
*
|
||||||
|
* A version of start() that can be called from an interrupt service routine.
|
||||||
|
*
|
||||||
|
* @param higherPriorityTaskWoken The timer service/daemon task spends most of
|
||||||
|
* its time in the Blocked state, waiting for messages to arrive on the timer
|
||||||
|
* command queue. Calling startFromISR() writes a message to the timer command
|
||||||
|
* queue, so has the potential to transition the timer service/daemon task out
|
||||||
|
* of the Blocked state. If calling startFromISR() causes the timer
|
||||||
|
* service/daemon task to leave the Blocked state, and the timer service/
|
||||||
|
* daemon task has a priority equal to or greater than the currently executing
|
||||||
|
* task (the task that was interrupted), then higherPriorityTaskWoken will get
|
||||||
|
* set to true internally within the startFromISR() function. If
|
||||||
|
* startFromISR() sets this value to true, then a context switch should be
|
||||||
|
* performed before the interrupt exits.
|
||||||
|
* @return true If the command was successfully sent to the timer command
|
||||||
|
* queue. When the command is actually processed will depend on the priority
|
||||||
|
* of the timer service/daemon task relative to other tasks in the system,
|
||||||
|
* although the timers expiry time is relative to when startFromISR() is
|
||||||
|
* actually called. The timer service/daemon task priority is set by the
|
||||||
|
* configTIMER_TASK_PRIORITY configuration constant.
|
||||||
|
* @return false If the start command could not be sent to the timer command
|
||||||
|
* queue.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Timer/startFromISR.cpp
|
||||||
|
*/
|
||||||
|
inline bool startFromISR(bool& higherPriorityTaskWoken) const {
|
||||||
|
BaseType_t taskWoken = pdFALSE;
|
||||||
|
bool result = (xTimerStartFromISR(handle, &taskWoken) == pdPASS);
|
||||||
|
if (taskWoken == pdTRUE) {
|
||||||
|
higherPriorityTaskWoken = true;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>BaseType_t xTimerStartFromISR( TimerHandle_t
|
||||||
|
* xTimer, BaseType_t *pxHigherPriorityTaskWoken )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/FreeRTOS-timers-xTimerStartFromISR.html>
|
||||||
|
*
|
||||||
|
* @overload
|
||||||
|
*/
|
||||||
|
inline bool startFromISR() const {
|
||||||
|
return (xTimerStartFromISR(handle, NULL) == pdPASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>BaseType_t xTimerStop( TimerHandle_t xTimer,
|
||||||
|
* TickType_t xBlockTime )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/FreeRTOS-timers-xTimerStop.html>
|
||||||
|
*
|
||||||
|
* stop() stops a timer that was previously started using either of the
|
||||||
|
* start(), reset(), startFromISR(), resetFromISR(), changePeriod() and
|
||||||
|
* changePeriodFromISR() API functions.
|
||||||
|
*
|
||||||
|
* Stopping a timer ensures the timer is not in the active state.
|
||||||
|
*
|
||||||
|
* @param blockTime Specifies the time, in ticks, that the calling task should
|
||||||
|
* be held in the Blocked state to wait for the stop command to be
|
||||||
|
* successfully sent to the timer command queue, should the queue already be
|
||||||
|
* full when stop() was called. blockTime is ignored if stop() is called
|
||||||
|
* before the RTOS scheduler is started.
|
||||||
|
* @return true If the command was successfully sent to the timer command
|
||||||
|
* queue. When the command is actually processed will depend on the priority
|
||||||
|
* of the timer service/daemon task relative to other tasks in the system. The
|
||||||
|
* timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY
|
||||||
|
* configuration constant.
|
||||||
|
* @return false If the stop command could not be sent to the timer command
|
||||||
|
* queue even after blockTime ticks had passed.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Timer/timer.cpp
|
||||||
|
*/
|
||||||
|
inline bool stop(const TickType_t blockTime = 0) const {
|
||||||
|
return (xTimerStop(handle, blockTime) == pdPASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>BaseType_t xTimerStopFromISR( TimerHandle_t
|
||||||
|
* xTimer, BaseType_t *pxHigherPriorityTaskWoken )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/FreeRTOS-timers-xTimerStopFromISR.html>
|
||||||
|
*
|
||||||
|
* A version of stop() that can be called from an interrupt service routine.
|
||||||
|
*
|
||||||
|
* @param higherPriorityTaskWoken The timer service/daemon task spends most of
|
||||||
|
* its time in the Blocked state, waiting for messages to arrive on the timer
|
||||||
|
* command queue. Calling stopFromISR() writes a message to the timer command
|
||||||
|
* queue, so has the potential to transition the timer service/daemon task out
|
||||||
|
* of the Blocked state. If calling stopFromISR() causes the timer
|
||||||
|
* service/daemon task to leave the Blocked state, and the timer service/
|
||||||
|
* daemon task has a priority equal to or greater than the currently executing
|
||||||
|
* task (the task that was interrupted), then higherPriorityTaskWoken will get
|
||||||
|
* set to true internally within the stopFromISR() function. If stopFromISR()
|
||||||
|
* sets this value to true, then a context switch should be performed before
|
||||||
|
* the interrupt exits.
|
||||||
|
* @return true If the command was successfully sent to the timer command
|
||||||
|
* queue. When the command is actually processed will depend on the priority
|
||||||
|
* of the timer service/daemon task relative to other tasks in the system. The
|
||||||
|
* timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY
|
||||||
|
* configuration constant.
|
||||||
|
* @return false If the start command could not be sent to the timer command
|
||||||
|
* queue.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Timer/stopFromISR.cpp
|
||||||
|
*/
|
||||||
|
inline bool stopFromISR(bool& higherPriorityTaskWoken) const {
|
||||||
|
BaseType_t taskWoken = pdFALSE;
|
||||||
|
bool result = (xTimerStopFromISR(handle, &taskWoken) == pdPASS);
|
||||||
|
if (taskWoken == pdTRUE) {
|
||||||
|
higherPriorityTaskWoken = true;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>BaseType_t xTimerStopFromISR( TimerHandle_t
|
||||||
|
* xTimer, BaseType_t *pxHigherPriorityTaskWoken )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/FreeRTOS-timers-xTimerStopFromISR.html>
|
||||||
|
*
|
||||||
|
* @overload
|
||||||
|
*/
|
||||||
|
inline bool stopFromISR() const {
|
||||||
|
return (xTimerStopFromISR(handle, NULL) == pdPASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>BaseType_t xTimerChangePeriod( TimerHandle_t
|
||||||
|
* xTimer, TickType_t xNewPeriod, TickType_t xBlockTime )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/FreeRTOS-timers-xTimerChangePeriod.html>
|
||||||
|
*
|
||||||
|
* changePeriod() changes the period of a timer.
|
||||||
|
*
|
||||||
|
* changePeriod() can be called to change the period of an active or dormant
|
||||||
|
* state timer. Changing the period of a dormant timers will also start the
|
||||||
|
* timer.
|
||||||
|
*
|
||||||
|
* @param newPeriod The new period for timer. Timer periods are specified in
|
||||||
|
* tick periods, so the constant portTICK_PERIOD_MS can be used to convert a
|
||||||
|
* time that has been specified in milliseconds. For example, if the timer
|
||||||
|
* must expire after 100 ticks, then newPeriod should be set to 100.
|
||||||
|
* Alternatively, if the timer must expire after 500ms, then newPeriod can be
|
||||||
|
* set to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less
|
||||||
|
* than or equal to 1000.
|
||||||
|
* @param blockTime Specifies the time, in ticks, that the calling task should
|
||||||
|
* be held in the Blocked state to wait for the change period command to be
|
||||||
|
* successfully sent to the timer command queue, should the queue already be
|
||||||
|
* full when changePeriod() was called. blockTime is ignored if changePeriod()
|
||||||
|
* is called before the RTOS scheduler is started.
|
||||||
|
* @return true If the command was successfully sent to the timer command
|
||||||
|
* queue. When the command is actually processed will depend on the priority
|
||||||
|
* of the timer service/daemon task relative to other tasks in the system. The
|
||||||
|
* timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY
|
||||||
|
* configuration constant.
|
||||||
|
* @return false If the change period command could not be sent to the timer
|
||||||
|
* command queue even after blockTime ticks had passed.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Timer/changePeriod.cpp
|
||||||
|
*/
|
||||||
|
inline bool changePeriod(const TickType_t newPeriod,
|
||||||
|
const TickType_t blockTime = 0) const {
|
||||||
|
return (xTimerChangePeriod(handle, newPeriod, blockTime) == pdPASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>BaseType_t xTimerChangePeriodFromISR(
|
||||||
|
* TimerHandle_t xTimer, TickType_t xNewPeriod, BaseType_t
|
||||||
|
* *pxHigherPriorityTaskWoken )</tt>
|
||||||
|
*
|
||||||
|
* @see
|
||||||
|
* <https://www.freertos.org/FreeRTOS-timers-xTimerChangePeriodFromISR.html>
|
||||||
|
*
|
||||||
|
* A version of changePeriod() that can be called from an interrupt service
|
||||||
|
* routine.
|
||||||
|
*
|
||||||
|
* @param newPeriod The new period for timer. Timer periods are specified in
|
||||||
|
* tick periods, so the constant portTICK_PERIOD_MS can be used to convert a
|
||||||
|
* time that has been specified in milliseconds. For example, if the timer
|
||||||
|
* must expire after 100 ticks, then newPeriod should be set to 100.
|
||||||
|
* Alternatively, if the timer must expire after 500ms, then newPeriod can be
|
||||||
|
* set to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less
|
||||||
|
* than or equal to 1000.
|
||||||
|
* @param higherPriorityTaskWoken The timer service/daemon task spends most of
|
||||||
|
* its time in the Blocked state, waiting for messages to arrive on the timer
|
||||||
|
* command queue. Calling changePeriodFromISR() writes a message to the timer
|
||||||
|
* command queue, so has the potential to transition the timer service/ daemon
|
||||||
|
* task out of the Blocked state. If calling changePeriodFromISR() causes the
|
||||||
|
* timer service/daemon task to leave the Blocked state, and the timer
|
||||||
|
* service/daemon task has a priority equal to or greater than the currently
|
||||||
|
* executing task (the task that was interrupted), then
|
||||||
|
* higherPriorityTaskWoken will get set to true internally within the
|
||||||
|
* changePeriodFromISR() function. If changePeriodFromISR() sets this value to
|
||||||
|
* true, then a context switch should be performed before the interrupt exits.
|
||||||
|
* @return true If the command was successfully sent to the timer command
|
||||||
|
* queue. When the command is actually processed will depend on the priority
|
||||||
|
* of the timer service/daemon task relative to other tasks in the system. The
|
||||||
|
* timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY
|
||||||
|
* configuration constant.
|
||||||
|
* @return false If the change period command could not be sent to the timer
|
||||||
|
* command queue.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Timer/changePeriodFromISR.cpp
|
||||||
|
*/
|
||||||
|
inline bool changePeriodFromISR(bool& higherPriorityTaskWoken,
|
||||||
|
const TickType_t newPeriod) const {
|
||||||
|
BaseType_t taskWoken = pdFALSE;
|
||||||
|
bool result =
|
||||||
|
(xTimerChangePeriodFromISR(handle, newPeriod, &taskWoken) == pdPASS);
|
||||||
|
if (taskWoken == pdTRUE) {
|
||||||
|
higherPriorityTaskWoken = true;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>BaseType_t xTimerChangePeriodFromISR(
|
||||||
|
* TimerHandle_t xTimer, TickType_t xNewPeriod, BaseType_t
|
||||||
|
* *pxHigherPriorityTaskWoken )</tt>
|
||||||
|
*
|
||||||
|
* @see
|
||||||
|
* <https://www.freertos.org/FreeRTOS-timers-xTimerChangePeriodFromISR.html>
|
||||||
|
*
|
||||||
|
* @overload
|
||||||
|
*/
|
||||||
|
inline bool changePeriodFromISR(const TickType_t newPeriod) const {
|
||||||
|
return (xTimerChangePeriodFromISR(handle, newPeriod, NULL) == pdPASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>BaseType_t xTimerDelete( TimerHandle_t
|
||||||
|
* xTimer, TickType_t xBlockTime )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/FreeRTOS-timers-xTimerDelete.html>
|
||||||
|
*
|
||||||
|
* deleteTimer() deletes a timer from the FreeRTOS timer task.
|
||||||
|
*
|
||||||
|
* @note This function is also called in the destructor of the timer using the
|
||||||
|
* deleteBlockTime specified when the object was created. This function
|
||||||
|
* should be used when the user wants to delete the timer from the FreeRTOS
|
||||||
|
* timer task without destroying the timer object or with a different block
|
||||||
|
* time than what was specified in the constructor.
|
||||||
|
*
|
||||||
|
* @param blockTime Specifies the time, in ticks, that the calling task should
|
||||||
|
* be held in the Blocked state to wait for the delete command to be
|
||||||
|
* successfully sent to the timer command queue, should the queue already be
|
||||||
|
* full when deleteTimer() was called. blockTime is ignored if deleteTimer()
|
||||||
|
* is called before the RTOS scheduler is started.
|
||||||
|
* @return true If the command was successfully sent to the timer command
|
||||||
|
* queue. When the command is actually processed will depend on the priority
|
||||||
|
* of the timer service/daemon task relative to other tasks in the system. The
|
||||||
|
* timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY
|
||||||
|
* configuration constant.
|
||||||
|
* @return false If the delete command could not be sent to the timer command
|
||||||
|
* queue even after blockTime ticks had passed.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Timer/changePeriod.cpp
|
||||||
|
*/
|
||||||
|
inline bool deleteTimer(const TickType_t blockTime = 0) {
|
||||||
|
if (xTimerDelete(handle, blockTime) == pdPASS) {
|
||||||
|
handle = NULL;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt> BaseType_t xTimerReset( TimerHandle_t
|
||||||
|
* xTimer, TickType_t xBlockTime )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/FreeRTOS-timers-xTimerReset.html>
|
||||||
|
*
|
||||||
|
* reset() re-starts a timer. If the timer had already been started and was
|
||||||
|
* already in the active state, then reset() will cause the timer to
|
||||||
|
* re-evaluate its expiry time so that it is relative to when reset() was
|
||||||
|
* called. If the timer was in the dormant state then reset() has equivalent
|
||||||
|
* functionality to the start() API function.
|
||||||
|
*
|
||||||
|
* Resetting a timer ensures the timer is in the active state. If the timer
|
||||||
|
* is not stopped, deleted, or reset in the mean time, the callback function
|
||||||
|
* associated with the timer will get called 'n' ticks after reset() was
|
||||||
|
* called, where 'n' is the timers defined period.
|
||||||
|
*
|
||||||
|
* It is valid to call reset() before the RTOS scheduler has been started, but
|
||||||
|
* when this is done the timer will not actually start until the RTOS
|
||||||
|
* scheduler is started, and the timers expiry time will be relative to when
|
||||||
|
* the RTOS scheduler is started, not relative to when reset() was called.
|
||||||
|
*
|
||||||
|
* @param blockTime Specifies the time, in ticks, that the calling task should
|
||||||
|
* be held in the Blocked state to wait for the reset command to be
|
||||||
|
* successfully sent to the timer command queue, should the queue already be
|
||||||
|
* full when reset() was called. blockTime is ignored if reset() is called
|
||||||
|
* before the RTOS scheduler is started.
|
||||||
|
* @return true If the command was successfully sent to the timer command
|
||||||
|
* queue. When the command is actually processed will depend on the priority
|
||||||
|
* of the timer service/daemon task relative to other tasks in the system,
|
||||||
|
* although the timers expiry time is relative to when reset() is actually
|
||||||
|
* called. The timer service/daemon task priority is set by the
|
||||||
|
* configTIMER_TASK_PRIORITY configuration constant.
|
||||||
|
* @return false If the reset command could not be sent to the timer command
|
||||||
|
* queue even after blockTime ticks had passed.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Timer/reset.cpp
|
||||||
|
*/
|
||||||
|
inline bool reset(const TickType_t blockTime = 0) const {
|
||||||
|
return (xTimerReset(handle, blockTime) == pdPASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>BaseType_t xTimerResetFromISR( TimerHandle_t
|
||||||
|
* xTimer, BaseType_t *pxHigherPriorityTaskWoken )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/FreeRTOS-timers-xTimerResetFromISR.html>
|
||||||
|
*
|
||||||
|
* A version of reset() that can be called from an interrupt service routine.
|
||||||
|
*
|
||||||
|
* @param higherPriorityTaskWoken The timer service/daemon task spends most of
|
||||||
|
* its time in the Blocked state, waiting for messages to arrive on the timer
|
||||||
|
* command queue. Calling resetFromISR() writes a message to the timer command
|
||||||
|
* queue, so has the potential to transition the timer service/daemon task out
|
||||||
|
* of the Blocked state. If calling resetFromISR() causes the timer
|
||||||
|
* service/daemon task to leave the Blocked state, and the timer
|
||||||
|
* service/daemon task has a priority equal to or greater than the currently
|
||||||
|
* executing task (the task that was interrupted), then
|
||||||
|
* higherPriorityTaskWoken will get set to true internally within the
|
||||||
|
* resetFromISR() function. If resetFromISR() sets this value to true, then a
|
||||||
|
* context switch should be performed before the interrupt exits.
|
||||||
|
* @return true If the command was successfully sent to the timer command
|
||||||
|
* queue. When the command is actually processed will depend on the priority
|
||||||
|
* of the timer service/daemon task relative to other tasks in the system,
|
||||||
|
* although the timers expiry time is relative to when resetFromISR() is
|
||||||
|
* actually called. The timer service/daemon task priority is set by the
|
||||||
|
* configTIMER_TASK_PRIORITY configuration constant.
|
||||||
|
* @return false If the change period command could not be sent to the timer
|
||||||
|
* command queue.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Timer/resetFromISR.cpp
|
||||||
|
*/
|
||||||
|
inline bool resetFromISR(bool& higherPriorityTaskWoken) const {
|
||||||
|
BaseType_t taskWoken = pdFALSE;
|
||||||
|
bool result = (xTimerResetFromISR(handle, &taskWoken) == pdPASS);
|
||||||
|
if (taskWoken == pdTRUE) {
|
||||||
|
higherPriorityTaskWoken = true;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>BaseType_t xTimerResetFromISR( TimerHandle_t
|
||||||
|
* xTimer, BaseType_t *pxHigherPriorityTaskWoken )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/FreeRTOS-timers-xTimerResetFromISR.html>
|
||||||
|
*
|
||||||
|
* @overload
|
||||||
|
*/
|
||||||
|
inline bool resetFromISR() const {
|
||||||
|
return (xTimerResetFromISR(handle, NULL) == pdPASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>void vTimerSetReloadMode( TimerHandle_t
|
||||||
|
* xTimer, const UBaseType_t uxAutoReload )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/FreeRTOS-Timers-vTimerSetReloadMode.html>
|
||||||
|
*
|
||||||
|
* Updates the 'mode' of a software timer to be either an auto reload timer or
|
||||||
|
* a one-shot timer.
|
||||||
|
*
|
||||||
|
* An auto reload timer resets itself each time it expires, causing the timer
|
||||||
|
* to expire (and therefore execute its callback) periodically.
|
||||||
|
*
|
||||||
|
* A one shot timer does not automatically reset itself, so will only expire
|
||||||
|
* (and therefore execute its callback) once unless it is manually restarted.
|
||||||
|
*
|
||||||
|
* @param autoReload Set autoReload to true to set the timer into auto reload
|
||||||
|
* mode, or false to set the timer into one shot mode.
|
||||||
|
*/
|
||||||
|
inline void setReloadMode(const bool autoReload) const {
|
||||||
|
vTimerSetReloadMode(handle, (autoReload ? pdTRUE : pdFALSE));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>const char * pcTimerGetName( TimerHandle_t
|
||||||
|
* xTimer )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/FreeRTOS-timers-pcTimerGetName.html>
|
||||||
|
*
|
||||||
|
* Returns the human readable text name of a software timer.
|
||||||
|
*
|
||||||
|
* Text names are assigned to timers in the constructor.
|
||||||
|
*
|
||||||
|
* @return const char* A pointer to the text name of the timer as a standard
|
||||||
|
* NULL terminated C string.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Timer/getName.cpp
|
||||||
|
*/
|
||||||
|
inline const char* getName() const { return pcTimerGetName(handle); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>TickType_t xTimerGetPeriod( TimerHandle_t
|
||||||
|
* xTimer )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/FreeRTOS-timers-xTimerGetPeriod.html>
|
||||||
|
*
|
||||||
|
* Returns the period of a software timer. The period is specified in ticks.
|
||||||
|
*
|
||||||
|
* The period of a timer is initially set using the period parameter of the
|
||||||
|
* constructor. It can then be changed using the changePeriod() and
|
||||||
|
* changePeriodFromISR() API functions.
|
||||||
|
*
|
||||||
|
* @return TickType_t The period of the timer, in ticks.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Timer/getPeriod.cpp
|
||||||
|
*/
|
||||||
|
inline TickType_t getPeriod() const { return xTimerGetPeriod(handle); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>TickType_t xTimerGetExpiryTime(
|
||||||
|
* TimerHandle_t xTimer )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/FreeRTOS-timers-xTimerGetExpiryTime.html>
|
||||||
|
*
|
||||||
|
* Returns the time at which the software timer will expire, which is the time
|
||||||
|
* at which the timer's callback function will execute.
|
||||||
|
*
|
||||||
|
* If the value returned by getExpiryTime() is less than the current time then
|
||||||
|
* the timer will expire after the tick count has overflowed and wrapped back
|
||||||
|
* to 0. Overflows are handled in the RTOS implementation itself, so a timer's
|
||||||
|
* callback function will execute at the correct time whether it is before or
|
||||||
|
* after the tick count overflows.
|
||||||
|
*
|
||||||
|
* @return TickType_t If the timer is active, then the time at which the timer
|
||||||
|
* will next expire is returned (which may be after the current tick count has
|
||||||
|
* overflowed, see the notes above). If the timer is not active then the
|
||||||
|
* return value is undefined.
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Timer/getExpiryTime.cpp
|
||||||
|
*/
|
||||||
|
inline TickType_t getExpiryTime() const {
|
||||||
|
return xTimerGetExpiryTime(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer.hpp
|
||||||
|
*
|
||||||
|
* @brief Function that calls <tt>UBaseType_t uxTimerGetReloadMode(
|
||||||
|
* TimerHandle_t xTimer )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/uxTimerGetReloadMode.html>
|
||||||
|
*
|
||||||
|
* Queries the 'mode' of the software timer.
|
||||||
|
*
|
||||||
|
* The mode can be either an auto-reloaded timer, which automatically resets
|
||||||
|
* itself each time it expires, or a one-shot timer, which will expire only
|
||||||
|
* once unless it is manually restarted.
|
||||||
|
*
|
||||||
|
* @return true If the timer is an auto-reload timer.
|
||||||
|
* @return false Otherwise.
|
||||||
|
*/
|
||||||
|
inline bool getReloadMode() const {
|
||||||
|
return (uxTimerGetReloadMode(handle) == pdTRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer.hpp
|
||||||
|
*
|
||||||
|
* @brief Set the delete block time. This value is used when the destructor
|
||||||
|
* calls deleteTimer().
|
||||||
|
*
|
||||||
|
* @param deleteBlockTime Delete block time to be set in ticks.
|
||||||
|
*/
|
||||||
|
inline void setDeleteBlockTime(const TickType_t deleteBlockTime = 0) {
|
||||||
|
this->deleteBlockTime = deleteBlockTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer.hpp
|
||||||
|
*
|
||||||
|
* @brief Set the delete block time. This value is used when the destructor
|
||||||
|
* calls deleteTimer().
|
||||||
|
*
|
||||||
|
* @return TickType_t Delete block time in ticks.
|
||||||
|
*/
|
||||||
|
inline TickType_t getDeleteBlockTime() const { return deleteBlockTime; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Timer.hpp
|
||||||
|
*
|
||||||
|
* @brief Abstraction function that acts as the entry point of the timer
|
||||||
|
* callback for the user.
|
||||||
|
*/
|
||||||
|
virtual void timerFunction() = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Timer.hpp
|
||||||
|
*
|
||||||
|
* @brief Construct a new TimerBase object. This default constructor is
|
||||||
|
* deliberately private as this class is not intended to be instantiated or
|
||||||
|
* derived from by the user. Use FreeRTOS::Timer or FreeRTOS::StaticTimer as
|
||||||
|
* a base class for creating a task.
|
||||||
|
*
|
||||||
|
* @param deleteBlockTime Set the delete block time. This value is used when
|
||||||
|
* the destructor calls deleteTimer().
|
||||||
|
*/
|
||||||
|
explicit TimerBase(const TickType_t deleteBlockTime = 0)
|
||||||
|
: deleteBlockTime(deleteBlockTime) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer.hpp
|
||||||
|
*
|
||||||
|
* @brief Destroy the TimerBase object.
|
||||||
|
*
|
||||||
|
* @note This destructor will check that the timer is still valid and has not
|
||||||
|
* already been deleted by deleteTimer() before calling the function. If the
|
||||||
|
* timer is still valid the destructor will call deleteTimer() and block for
|
||||||
|
* up to the amount of time specified by deleteBlockTime.
|
||||||
|
*/
|
||||||
|
~TimerBase() {
|
||||||
|
if (isValid()) {
|
||||||
|
deleteTimer(getDeleteBlockTime());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TimerBase(TimerBase&&) noexcept = default;
|
||||||
|
TimerBase& operator=(TimerBase&&) noexcept = default;
|
||||||
|
|
||||||
|
TimerHandle_t handle = NULL;
|
||||||
|
TickType_t deleteBlockTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer Timer.hpp <FreeRTOS/Timer.hpp>
|
||||||
|
*
|
||||||
|
* @brief Class that encapsulates the functionality of a FreeRTOS timer.
|
||||||
|
*
|
||||||
|
* Each software timer requires a small amount of RAM that is used to hold the
|
||||||
|
* timer's state. If a timer is created using this class then this RAM is
|
||||||
|
* automatically allocated from the FreeRTOS heap. If a software timer is
|
||||||
|
* created using FreeRTOS::StaticTimer() then the RAM is included in the object
|
||||||
|
* so it can be statically allocated at compile time. See the Static Vs Dynamic
|
||||||
|
* allocation page for more information.
|
||||||
|
*
|
||||||
|
* @note This class is not intended to be instantiated by the user. The user
|
||||||
|
* should create a class that derives from this class and implement
|
||||||
|
* timerFunction().
|
||||||
|
*/
|
||||||
|
class Timer : public TimerBase {
|
||||||
|
public:
|
||||||
|
Timer(const Timer&) = delete;
|
||||||
|
Timer& operator=(const Timer&) = delete;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Timer.hpp
|
||||||
|
*
|
||||||
|
* @brief Construct a new Timer object by calling <tt>TimerHandle_t
|
||||||
|
* xTimerCreate( const char * const pcTimerName, const TickType_t
|
||||||
|
* xTimerPeriod, const UBaseType_t uxAutoReload, void * const pvTimerID,
|
||||||
|
* TimerCallbackFunction_t pxCallbackFunction )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/FreeRTOS-timers-xTimerCreate.html>
|
||||||
|
*
|
||||||
|
* @warning The user should call isValid() on this object to verify that the
|
||||||
|
* timer was created successfully in case the memory required to create the
|
||||||
|
* timer could not be allocated.
|
||||||
|
*
|
||||||
|
* @note Timers are created in the dormant state. The start(), reset(),
|
||||||
|
* startFromISR(), resetFromISR(), changePeriod() and changePeriodFromISR()
|
||||||
|
* API functions can all be used to transition a timer into the active state.
|
||||||
|
*
|
||||||
|
* @note When calling <tt>xTimerCreate</tt> the constructor passes the
|
||||||
|
* <tt>this</tt> pointer as the pvTimerID argument. This pointer is used so
|
||||||
|
* that the interface function callTimerFunction() can invoke timerFunction()
|
||||||
|
* for this instance of the class.
|
||||||
|
*
|
||||||
|
* @param period The period of the timer. The period is specified in ticks,
|
||||||
|
* and the macro pdMS_TO_TICKS() can be used to convert a time specified in
|
||||||
|
* milliseconds to a time specified in ticks. For example, if the timer must
|
||||||
|
* expire after 100 ticks, then simply set period to 100. Alternatively, if
|
||||||
|
* the timer must expire after 500ms, then set period to pdMS_TO_TICKS( 500 ).
|
||||||
|
* pdMS_TO_TICKS() can only be used if configTICK_RATE_HZ is less than or
|
||||||
|
* equal to 1000. The timer period must be greater than 0.
|
||||||
|
* @param autoReload If autoReload is set to true, then the timer will expire
|
||||||
|
* repeatedly with a frequency set by the period parameter. If autoReload is
|
||||||
|
* set to false, then the timer will be a one-shot and enter the dormant state
|
||||||
|
* after it expires.
|
||||||
|
* @param name A human readable text name that is assigned to the timer. This
|
||||||
|
* is done purely to assist debugging. The RTOS kernel itself only ever
|
||||||
|
* references a timer by its handle, and never by its name.
|
||||||
|
* @param deleteBlockTime Specifies the time, in ticks, that the calling task
|
||||||
|
* should be held in the Blocked state to wait for the delete command to be
|
||||||
|
* successfully sent to the timer command queue, should the queue already be
|
||||||
|
* full when the destructor is called. deleteBlockTime is ignored if the
|
||||||
|
* destructor is called before the RTOS scheduler is started or if the timer
|
||||||
|
* has already been deleted by deleteTimer() before the destructor is called.
|
||||||
|
* This value can be updated by calling setDeleteBlockTime().
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Timer/timer.cpp
|
||||||
|
*/
|
||||||
|
explicit Timer(const TickType_t period, const bool autoReload = false,
|
||||||
|
const char* name = "", const TickType_t deleteBlockTime = 0)
|
||||||
|
: TimerBase(deleteBlockTime) {
|
||||||
|
this->handle = xTimerCreate(name, period, (autoReload ? pdTRUE : pdFALSE),
|
||||||
|
this, callTimerFunction);
|
||||||
|
}
|
||||||
|
~Timer() = default;
|
||||||
|
|
||||||
|
Timer(Timer&&) noexcept = default;
|
||||||
|
Timer& operator=(Timer&&) noexcept = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||||
|
|
||||||
|
#if (configSUPPORT_STATIC_ALLOCATION == 1)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer Timer.hpp <FreeRTOS/Timer.hpp>
|
||||||
|
*
|
||||||
|
* @brief Class that encapsulates the functionality of a FreeRTOS timer.
|
||||||
|
*
|
||||||
|
* Each software timer requires a small amount of RAM that is used to hold the
|
||||||
|
* timer's state. If a timer is created using FreeRTOS::Timer() then this RAM is
|
||||||
|
* automatically allocated from the FreeRTOS heap. If a software timer is
|
||||||
|
* created this class then the RAM is included in the object so it can be
|
||||||
|
* statically allocated at compile time. See the Static Vs Dynamic allocation
|
||||||
|
* page for more information.
|
||||||
|
*
|
||||||
|
* @note This class is not intended to be instantiated by the user. The user
|
||||||
|
* should create a class that derives from this class and implement
|
||||||
|
* timerFunction().
|
||||||
|
*
|
||||||
|
* @warning This class contains the timer data structure, so any instance of
|
||||||
|
* this class or class derived from this class should be persistent (not
|
||||||
|
* declared on the stack of another function).
|
||||||
|
*/
|
||||||
|
class StaticTimer : public TimerBase {
|
||||||
|
public:
|
||||||
|
StaticTimer(const StaticTimer&) = delete;
|
||||||
|
StaticTimer& operator=(const StaticTimer&) = delete;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Timer.hpp
|
||||||
|
*
|
||||||
|
* @brief Construct a new StaticTimer object by calling <tt>TimerHandle_t
|
||||||
|
* xTimerCreateStatic( const char * const pcTimerName, const TickType_t
|
||||||
|
* xTimerPeriod, const UBaseType_t uxAutoReload, void * const pvTimerID,
|
||||||
|
* TimerCallbackFunction_t pxCallbackFunction StaticTimer_t *pxTimerBuffer
|
||||||
|
* )</tt>
|
||||||
|
*
|
||||||
|
* @see <https://www.freertos.org/xTimerCreateStatic.html>
|
||||||
|
*
|
||||||
|
* @note When calling <tt>xTimerCreateStatic</tt> the constructor passes the
|
||||||
|
* <tt>this</tt> pointer as the pvTimerID argument. This pointer is used so
|
||||||
|
* that the interface function callTimerFunction() can invoke timerFunction()
|
||||||
|
* for this instance of the class.
|
||||||
|
*
|
||||||
|
* @note Timers are created in the dormant state. The start(), reset(),
|
||||||
|
* startFromISR(), resetFromISR(), changePeriod() and changePeriodFromISR()
|
||||||
|
* API functions can all be used to transition a timer into the active state.
|
||||||
|
*
|
||||||
|
* @param period The period of the timer. The period is specified in ticks,
|
||||||
|
* and the macro pdMS_TO_TICKS() can be used to convert a time specified in
|
||||||
|
* milliseconds to a time specified in ticks. For example, if the timer must
|
||||||
|
* expire after 100 ticks, then simply set period to 100. Alternatively, if
|
||||||
|
* the timer must expire after 500ms, then set period to pdMS_TO_TICKS( 500 ).
|
||||||
|
* pdMS_TO_TICKS() can only be used if configTICK_RATE_HZ is less than or
|
||||||
|
* equal to 1000. The timer period must be greater than 0.
|
||||||
|
* @param autoReload If autoReload is set to true, then the timer will expire
|
||||||
|
* repeatedly with a frequency set by the period parameter. If autoReload is
|
||||||
|
* set to false, then the timer will be a one-shot and enter the dormant state
|
||||||
|
* after it expires.
|
||||||
|
* @param name A human readable text name that is assigned to the timer. This
|
||||||
|
* is done purely to assist debugging. The RTOS kernel itself only ever
|
||||||
|
* references a timer by its handle, and never by its name.
|
||||||
|
* @param deleteBlockTime Specifies the time, in ticks, that the calling task
|
||||||
|
* should be held in the Blocked state to wait for the delete command to be
|
||||||
|
* successfully sent to the timer command queue, should the queue already be
|
||||||
|
* full when the destructor is called. deleteBlockTime is ignored if the
|
||||||
|
* destructor is called before the RTOS scheduler is started or if the timer
|
||||||
|
* has already been deleted by deleteTimer() before the destructor is called.
|
||||||
|
* This value can be updated by calling setDeleteBlockTime().
|
||||||
|
*
|
||||||
|
* <b>Example Usage</b>
|
||||||
|
* @include Timer/staticTimer.cpp
|
||||||
|
*/
|
||||||
|
explicit StaticTimer(const TickType_t period, const bool autoReload = false,
|
||||||
|
const char* name = "",
|
||||||
|
const TickType_t deleteBlockTime = 0)
|
||||||
|
: TimerBase(deleteBlockTime) {
|
||||||
|
this->handle =
|
||||||
|
xTimerCreateStatic(name, period, (autoReload ? pdTRUE : pdFALSE), this,
|
||||||
|
callTimerFunction, &staticTimer);
|
||||||
|
}
|
||||||
|
~StaticTimer() = default;
|
||||||
|
|
||||||
|
StaticTimer(StaticTimer&&) noexcept = default;
|
||||||
|
StaticTimer& operator=(StaticTimer&&) noexcept = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
StaticTimer_t staticTimer;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||||
|
|
||||||
|
} // namespace FreeRTOS
|
||||||
|
|
||||||
|
inline void callTimerFunction(TimerHandle_t timer) {
|
||||||
|
static_cast<FreeRTOS::TimerBase*>(pvTimerGetTimerID(timer))->timerEntry();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FREERTOS_TIMER_HPP
|
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef TIMER_HPP
|
||||||
|
#define TIMER_HPP
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include "murax.h"
|
||||||
|
|
||||||
|
// Klasa TimeR
|
||||||
|
class TimeR {
|
||||||
|
public:
|
||||||
|
static inline uint32_t readValue() {
|
||||||
|
return ptr->VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const Timer_Reg* ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TIMER_HPP
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,300 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef cJSON__h
|
||||||
|
#define cJSON__h
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
|
||||||
|
#define __WINDOWS__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __WINDOWS__
|
||||||
|
|
||||||
|
/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 3 define options:
|
||||||
|
|
||||||
|
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
|
||||||
|
CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
|
||||||
|
CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
|
||||||
|
|
||||||
|
For *nix builds that support visibility attribute, you can define similar behavior by
|
||||||
|
|
||||||
|
setting default visibility to hidden by adding
|
||||||
|
-fvisibility=hidden (for gcc)
|
||||||
|
or
|
||||||
|
-xldscope=hidden (for sun cc)
|
||||||
|
to CFLAGS
|
||||||
|
|
||||||
|
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define CJSON_CDECL __cdecl
|
||||||
|
#define CJSON_STDCALL __stdcall
|
||||||
|
|
||||||
|
/* export symbols by default, this is necessary for copy pasting the C and header file */
|
||||||
|
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
|
||||||
|
#define CJSON_EXPORT_SYMBOLS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CJSON_HIDE_SYMBOLS)
|
||||||
|
#define CJSON_PUBLIC(type) type CJSON_STDCALL
|
||||||
|
#elif defined(CJSON_EXPORT_SYMBOLS)
|
||||||
|
#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL
|
||||||
|
#elif defined(CJSON_IMPORT_SYMBOLS)
|
||||||
|
#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL
|
||||||
|
#endif
|
||||||
|
#else /* !__WINDOWS__ */
|
||||||
|
#define CJSON_CDECL
|
||||||
|
#define CJSON_STDCALL
|
||||||
|
|
||||||
|
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
|
||||||
|
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
|
||||||
|
#else
|
||||||
|
#define CJSON_PUBLIC(type) type
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* project version */
|
||||||
|
#define CJSON_VERSION_MAJOR 1
|
||||||
|
#define CJSON_VERSION_MINOR 7
|
||||||
|
#define CJSON_VERSION_PATCH 18
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
/* cJSON Types: */
|
||||||
|
#define cJSON_Invalid (0)
|
||||||
|
#define cJSON_False (1 << 0)
|
||||||
|
#define cJSON_True (1 << 1)
|
||||||
|
#define cJSON_NULL (1 << 2)
|
||||||
|
#define cJSON_Number (1 << 3)
|
||||||
|
#define cJSON_String (1 << 4)
|
||||||
|
#define cJSON_Array (1 << 5)
|
||||||
|
#define cJSON_Object (1 << 6)
|
||||||
|
#define cJSON_Raw (1 << 7) /* raw json */
|
||||||
|
|
||||||
|
#define cJSON_IsReference 256
|
||||||
|
#define cJSON_StringIsConst 512
|
||||||
|
|
||||||
|
/* The cJSON structure: */
|
||||||
|
typedef struct cJSON
|
||||||
|
{
|
||||||
|
/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
|
||||||
|
struct cJSON *next;
|
||||||
|
struct cJSON *prev;
|
||||||
|
/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
|
||||||
|
struct cJSON *child;
|
||||||
|
|
||||||
|
/* The type of the item, as above. */
|
||||||
|
int type;
|
||||||
|
|
||||||
|
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
|
||||||
|
char *valuestring;
|
||||||
|
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
|
||||||
|
int valueint;
|
||||||
|
/* The item's number, if type==cJSON_Number */
|
||||||
|
double valuedouble;
|
||||||
|
|
||||||
|
/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
|
||||||
|
char *string;
|
||||||
|
} cJSON;
|
||||||
|
|
||||||
|
typedef struct cJSON_Hooks
|
||||||
|
{
|
||||||
|
/* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */
|
||||||
|
void *(CJSON_CDECL *malloc_fn)(size_t sz);
|
||||||
|
void (CJSON_CDECL *free_fn)(void *ptr);
|
||||||
|
} cJSON_Hooks;
|
||||||
|
|
||||||
|
typedef int cJSON_bool;
|
||||||
|
|
||||||
|
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
|
||||||
|
* This is to prevent stack overflows. */
|
||||||
|
#ifndef CJSON_NESTING_LIMIT
|
||||||
|
#define CJSON_NESTING_LIMIT 1000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* returns the version of cJSON as a string */
|
||||||
|
CJSON_PUBLIC(const char*) cJSON_Version(void);
|
||||||
|
|
||||||
|
/* Supply malloc, realloc and free functions to cJSON */
|
||||||
|
CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
|
||||||
|
|
||||||
|
/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
|
||||||
|
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length);
|
||||||
|
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
|
||||||
|
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated);
|
||||||
|
|
||||||
|
/* Render a cJSON entity to text for transfer/storage. */
|
||||||
|
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
|
||||||
|
/* Render a cJSON entity to text for transfer/storage without any formatting. */
|
||||||
|
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
|
||||||
|
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
|
||||||
|
CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
|
||||||
|
/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
|
||||||
|
/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
|
||||||
|
/* Delete a cJSON entity and all subentities. */
|
||||||
|
CJSON_PUBLIC(void) cJSON_Delete(cJSON *item);
|
||||||
|
|
||||||
|
/* Returns the number of items in an array (or object). */
|
||||||
|
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
|
||||||
|
/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
|
||||||
|
/* Get item "string" from object. Case insensitive. */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
|
||||||
|
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
|
||||||
|
CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
|
||||||
|
|
||||||
|
/* Check item type and return its value */
|
||||||
|
CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item);
|
||||||
|
|
||||||
|
/* These functions check the type of an item */
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);
|
||||||
|
|
||||||
|
/* These calls create a cJSON item of the appropriate type. */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
|
||||||
|
/* raw json */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
|
||||||
|
|
||||||
|
/* Create a string where valuestring references a string so
|
||||||
|
* it will not be freed by cJSON_Delete */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
|
||||||
|
/* Create an object/array that only references it's elements so
|
||||||
|
* they will not be freed by cJSON_Delete */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
|
||||||
|
|
||||||
|
/* These utilities create an Array of count items.
|
||||||
|
* The parameter count cannot be greater than the number of elements in the number array, otherwise array access will be out of bounds.*/
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count);
|
||||||
|
|
||||||
|
/* Append item to the specified array/object. */
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
|
||||||
|
/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
|
||||||
|
* WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
|
||||||
|
* writing to `item->string` */
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
|
||||||
|
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
|
||||||
|
|
||||||
|
/* Remove/Detach items from Arrays/Objects. */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
|
||||||
|
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||||
|
CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
|
||||||
|
CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||||
|
|
||||||
|
/* Update array items. */
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
|
||||||
|
|
||||||
|
/* Duplicate a cJSON item */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
|
||||||
|
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
|
||||||
|
* need to be released. With recurse!=0, it will duplicate any children connected to the item.
|
||||||
|
* The item->next and ->prev pointers are always zero on return from Duplicate. */
|
||||||
|
/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
|
||||||
|
* case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
|
||||||
|
|
||||||
|
/* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings.
|
||||||
|
* The input pointer json cannot point to a read-only address area, such as a string constant,
|
||||||
|
* but should point to a readable and writable address area. */
|
||||||
|
CJSON_PUBLIC(void) cJSON_Minify(char *json);
|
||||||
|
|
||||||
|
/* Helper functions for creating and adding items to an object at the same time.
|
||||||
|
* They return the added item or NULL on failure. */
|
||||||
|
CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);
|
||||||
|
CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);
|
||||||
|
CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);
|
||||||
|
CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean);
|
||||||
|
CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);
|
||||||
|
CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);
|
||||||
|
CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);
|
||||||
|
CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);
|
||||||
|
CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);
|
||||||
|
|
||||||
|
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
|
||||||
|
#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
|
||||||
|
/* helper for the cJSON_SetNumberValue macro */
|
||||||
|
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
|
||||||
|
#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
|
||||||
|
/* Change the valuestring of a cJSON_String object, only takes effect when type of object is cJSON_String */
|
||||||
|
CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring);
|
||||||
|
|
||||||
|
/* If the object is not a boolean type this does nothing and returns cJSON_Invalid else it returns the new type*/
|
||||||
|
#define cJSON_SetBoolValue(object, boolValue) ( \
|
||||||
|
(object != NULL && ((object)->type & (cJSON_False|cJSON_True))) ? \
|
||||||
|
(object)->type=((object)->type &(~(cJSON_False|cJSON_True)))|((boolValue)?cJSON_True:cJSON_False) : \
|
||||||
|
cJSON_Invalid\
|
||||||
|
)
|
||||||
|
|
||||||
|
/* Macro for iterating over an array or object */
|
||||||
|
#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
|
||||||
|
|
||||||
|
/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */
|
||||||
|
CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
|
||||||
|
CJSON_PUBLIC(void) cJSON_free(void *object);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,88 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef cJSON_Utils__h
|
||||||
|
#define cJSON_Utils__h
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "cJSON.h"
|
||||||
|
|
||||||
|
/* Implement RFC6901 (https://tools.ietf.org/html/rfc6901) JSON Pointer spec. */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSONUtils_GetPointer(cJSON * const object, const char *pointer);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSONUtils_GetPointerCaseSensitive(cJSON * const object, const char *pointer);
|
||||||
|
|
||||||
|
/* Implement RFC6902 (https://tools.ietf.org/html/rfc6902) JSON Patch spec. */
|
||||||
|
/* NOTE: This modifies objects in 'from' and 'to' by sorting the elements by their key */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSONUtils_GeneratePatches(cJSON * const from, cJSON * const to);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSONUtils_GeneratePatchesCaseSensitive(cJSON * const from, cJSON * const to);
|
||||||
|
/* Utility for generating patch array entries. */
|
||||||
|
CJSON_PUBLIC(void) cJSONUtils_AddPatchToArray(cJSON * const array, const char * const operation, const char * const path, const cJSON * const value);
|
||||||
|
/* Returns 0 for success. */
|
||||||
|
CJSON_PUBLIC(int) cJSONUtils_ApplyPatches(cJSON * const object, const cJSON * const patches);
|
||||||
|
CJSON_PUBLIC(int) cJSONUtils_ApplyPatchesCaseSensitive(cJSON * const object, const cJSON * const patches);
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Note that ApplyPatches is NOT atomic on failure. To implement an atomic ApplyPatches, use:
|
||||||
|
//int cJSONUtils_AtomicApplyPatches(cJSON **object, cJSON *patches)
|
||||||
|
//{
|
||||||
|
// cJSON *modme = cJSON_Duplicate(*object, 1);
|
||||||
|
// int error = cJSONUtils_ApplyPatches(modme, patches);
|
||||||
|
// if (!error)
|
||||||
|
// {
|
||||||
|
// cJSON_Delete(*object);
|
||||||
|
// *object = modme;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// cJSON_Delete(modme);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return error;
|
||||||
|
//}
|
||||||
|
// Code not added to library since this strategy is a LOT slower.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Implement RFC7386 (https://tools.ietf.org/html/rfc7396) JSON Merge Patch spec. */
|
||||||
|
/* target will be modified by patch. return value is new ptr for target. */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSONUtils_MergePatch(cJSON *target, const cJSON * const patch);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSONUtils_MergePatchCaseSensitive(cJSON *target, const cJSON * const patch);
|
||||||
|
/* generates a patch to move from -> to */
|
||||||
|
/* NOTE: This modifies objects in 'from' and 'to' by sorting the elements by their key */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSONUtils_GenerateMergePatch(cJSON * const from, cJSON * const to);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSONUtils_GenerateMergePatchCaseSensitive(cJSON * const from, cJSON * const to);
|
||||||
|
|
||||||
|
/* Given a root object and a target object, construct a pointer from one to the other. */
|
||||||
|
CJSON_PUBLIC(char *) cJSONUtils_FindPointerFromObjectTo(const cJSON * const object, const cJSON * const target);
|
||||||
|
|
||||||
|
/* Sorts the members of the object into alphabetical order. */
|
||||||
|
CJSON_PUBLIC(void) cJSONUtils_SortObject(cJSON * const object);
|
||||||
|
CJSON_PUBLIC(void) cJSONUtils_SortObjectCaseSensitive(cJSON * const object);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -5,10 +5,10 @@
|
||||||
#include "murax.h"
|
#include "murax.h"
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
#include <initializer_list>
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
|
#include "lib/cJSON.h"
|
||||||
|
|
||||||
#define mainTIMER_PERIOD_MS (1 / portTICK_PERIOD_MS) // Ustawienie okresu timera na 1 sekundę
|
#define mainTIMER_PERIOD_MS (1 / portTICK_PERIOD_MS) // Ustawienie okresu timera na 1 sekundę
|
||||||
#define QUEUE_LENGTH 5
|
#define QUEUE_LENGTH 5
|
||||||
#define QUEUE_ITEM_SIZE sizeof(uint32_t)
|
#define QUEUE_ITEM_SIZE sizeof(uint32_t)
|
||||||
|
@ -16,6 +16,42 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
void vApplicationMallocFailedHook(void);
|
void vApplicationMallocFailedHook(void);
|
||||||
void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName);
|
void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName);
|
||||||
|
|
||||||
|
extern char _heap_start []; // Początek sterty
|
||||||
|
extern char _heap_end []; // Koniec sterty
|
||||||
|
|
||||||
|
extern int errno;
|
||||||
|
|
||||||
|
static char *current_heap_end = (char *) _heap_start;
|
||||||
|
|
||||||
|
#define ENOMEM 12
|
||||||
|
|
||||||
|
void *_sbrk(intptr_t increment) {
|
||||||
|
char *prev_heap_end;
|
||||||
|
|
||||||
|
if ((current_heap_end + increment) > (char *)_heap_end) {
|
||||||
|
// Brak wystarczającej pamięci
|
||||||
|
errno = ENOMEM;
|
||||||
|
return (void *)-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
prev_heap_end = current_heap_end;
|
||||||
|
current_heap_end += increment;
|
||||||
|
|
||||||
|
return (void *)prev_heap_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void print(const char*str){
|
||||||
|
while(*str){
|
||||||
|
uart_write(UART,*str);
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void println(const char*str){
|
||||||
|
print(str);
|
||||||
|
uart_write(UART,'\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -29,58 +65,62 @@ static QueueHandle_t xQueue;
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include <include/FreeRTOS/Task.hpp>
|
||||||
|
|
||||||
|
class MyTask : public FreeRTOS::Task {
|
||||||
// Modern C++ aproach
|
public:
|
||||||
// ---
|
MyTask(const UBaseType_t priority, const char* name)
|
||||||
class TimeR {
|
: FreeRTOS::Task(priority, configMINIMAL_STACK_SIZE, name) {}
|
||||||
|
void taskFunction() final;
|
||||||
public:
|
|
||||||
static inline uint32_t readValue() {
|
|
||||||
return ptr->VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
static const Timer_Reg* ptr ;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const Timer_Reg* TimeR::ptr = reinterpret_cast<const Timer_Reg*>(0xF0020040);
|
// Task to be created.
|
||||||
|
void MyTask::taskFunction() {
|
||||||
|
|
||||||
|
cJSON *root = cJSON_CreateObject();
|
||||||
|
|
||||||
void test (std::initializer_list<int> vals) {
|
cJSON_AddStringToObject(root, "sensor", "gps");
|
||||||
int buffer[50];
|
cJSON_AddNumberToObject(root, "time", 1351824120);
|
||||||
|
|
||||||
for (auto p = vals.begin(); p != vals.end(); ++p) {
|
cJSON *data = cJSON_CreateObject();
|
||||||
|
cJSON_AddItemToObject(root, "data", data);
|
||||||
|
cJSON_AddNumberToObject(data, "lat", 48.756080);
|
||||||
|
cJSON_AddNumberToObject(data, "lon", 2.302038);
|
||||||
|
|
||||||
int * i = buffer;
|
char *jsonString = cJSON_Print(root);
|
||||||
*i++ = *p;
|
println (jsonString);
|
||||||
// sprintf(buffer, "%d\n", *p);
|
|
||||||
// printf("%s", buffer);
|
std::string result(jsonString);
|
||||||
|
|
||||||
|
cJSON_Delete(root);
|
||||||
|
free(jsonString);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
println("Delay 10ms");
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
|
// Task code goes here.
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
#include "include/Timer.hpp"
|
||||||
|
|
||||||
|
const Timer_Reg* TimeR::ptr = reinterpret_cast<const Timer_Reg*>(0xF0020040);
|
||||||
|
|
||||||
|
#include "X.hpp"
|
||||||
|
|
||||||
|
#include "SimpleOStream.hpp"
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
|
|
||||||
std::vector<int> numbers;
|
// Definicja globalnego obiektu strumienia wyjściowego
|
||||||
|
SimpleOStream simpleCout;
|
||||||
|
|
||||||
// Dodawanie elementów do wektora
|
|
||||||
for (int i = 0; i < 10; ++i) {
|
|
||||||
numbers.push_back(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wypisywanie elementów wektora
|
X var {7};
|
||||||
char buffer[100];
|
|
||||||
sprintf(buffer, "Elements in the vector: ");
|
|
||||||
|
|
||||||
for (int number : numbers) {
|
println("hello world arty a7 v1");
|
||||||
sprintf(buffer, "%d ", number);
|
|
||||||
}
|
|
||||||
sprintf(buffer, "\n");
|
|
||||||
|
|
||||||
test({1,2,3,4,5});
|
|
||||||
|
|
||||||
xQueue = xQueueCreate(QUEUE_LENGTH, QUEUE_ITEM_SIZE); // Tworzenie kolejki
|
xQueue = xQueueCreate(QUEUE_LENGTH, QUEUE_ITEM_SIZE); // Tworzenie kolejki
|
||||||
if (xQueue == NULL) {
|
if (xQueue == NULL) {
|
||||||
|
@ -106,6 +146,15 @@ std::vector<int> numbers;
|
||||||
// Tworzenie zadania hungryTask
|
// Tworzenie zadania hungryTask
|
||||||
xTaskCreate(hungryTask, "Hungry Task", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL);
|
xTaskCreate(hungryTask, "Hungry Task", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL);
|
||||||
|
|
||||||
|
// Create the task.
|
||||||
|
MyTask task((tskIDLE_PRIORITY + 1), "NAME");
|
||||||
|
/*
|
||||||
|
// Check that the task was created successfully.
|
||||||
|
if (task.isValid()) {
|
||||||
|
FreeRTOS::Kernel::startScheduler();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// Uruchomienie planisty
|
// Uruchomienie planisty
|
||||||
vTaskStartScheduler();
|
vTaskStartScheduler();
|
||||||
|
|
||||||
|
@ -126,6 +175,11 @@ static void timerCallback(TimerHandle_t xTimer) {
|
||||||
static void hungryTask(void *pvParameters) {
|
static void hungryTask(void *pvParameters) {
|
||||||
uint32_t ulReceivedValue;
|
uint32_t ulReceivedValue;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
||||||
|
|
||||||
|
println("Delay 10ms");
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
|
|
||||||
// if (xQueueReceive(xQueue, &ulReceivedValue, portMAX_DELAY) == pdPASS) {
|
// if (xQueueReceive(xQueue, &ulReceivedValue, portMAX_DELAY) == pdPASS) {
|
||||||
//printf("hungry\n"); // Drukowanie, gdy odbierzemy wartość z kolejki
|
//printf("hungry\n"); // Drukowanie, gdy odbierzemy wartość z kolejki
|
||||||
// }
|
// }
|
||||||
|
|
|
@ -72,15 +72,15 @@
|
||||||
|
|
||||||
OUTPUT_ARCH( "riscv" )
|
OUTPUT_ARCH( "riscv" )
|
||||||
|
|
||||||
_STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0x10000;
|
_HEAP_SIZE = DEFINED(_HEAP_SIZE) ? _HEAP_SIZE : 0xb0000;
|
||||||
_HEAP_SIZE = DEFINED(_HEAP_SIZE) ? _HEAP_SIZE : 0x10000;
|
_STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0x20000;
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* Define memory layout
|
* Define memory layout
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
MEMORY {
|
MEMORY {
|
||||||
imem : ORIGIN = 0x80000000, LENGTH = 0x00080000
|
imem : ORIGIN = 0x80000000, LENGTH = 1024K
|
||||||
dmem : ORIGIN = 0x80080000, LENGTH = 0x00060000
|
dmem : ORIGIN = 0x80100000, LENGTH = 1024K
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Specify the default entry point to the program */
|
/* Specify the default entry point to the program */
|
||||||
|
|
Binary file not shown.
|
@ -1,103 +1,64 @@
|
||||||
/*
|
/*
|
||||||
FreeRTOS V8.2.3 - Copyright (C) 2015 Real Time Engineers Ltd.
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
All rights reserved
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
This file is part of the FreeRTOS distribution.
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
* the Software without restriction, including without limitation the rights to
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
***************************************************************************
|
*
|
||||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
* copies or substantial portions of the Software.
|
||||||
>>! obliged to provide the source code for proprietary components !<<
|
*
|
||||||
>>! outside of the FreeRTOS kernel. !<<
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
***************************************************************************
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
link: http://www.freertos.org/a00114.html
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
***************************************************************************
|
* https://github.com/FreeRTOS
|
||||||
* *
|
*
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
*/
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
|
||||||
* platform software that is more than just the market leader, it *
|
|
||||||
* is the industry's de facto standard. *
|
|
||||||
* *
|
|
||||||
* Help yourself get started quickly while simultaneously helping *
|
|
||||||
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
|
||||||
* tutorial book, reference manual, or both: *
|
|
||||||
* http://www.FreeRTOS.org/Documentation *
|
|
||||||
* *
|
|
||||||
***************************************************************************
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
|
||||||
the FAQ page "My application does not run, what could be wrong?". Have you
|
|
||||||
defined configASSERT()?
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
|
||||||
embedded software for free we request you assist our global community by
|
|
||||||
participating in the support forum.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
|
||||||
be as productive as possible as early as possible. Now you can receive
|
|
||||||
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
|
||||||
Ltd, and the world's leading authority on the world's leading RTOS.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
|
||||||
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
|
||||||
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and commercial middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
#include "croutine.h"
|
#include "croutine.h"
|
||||||
|
|
||||||
/* Remove the whole file is co-routines are not being used. */
|
/* Remove the whole file if co-routines are not being used. */
|
||||||
#if( configUSE_CO_ROUTINES != 0 )
|
#if ( configUSE_CO_ROUTINES != 0 )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Some kernel aware debuggers require data to be viewed to be global, rather
|
* Some kernel aware debuggers require data to be viewed to be global, rather
|
||||||
* than file scope.
|
* than file scope.
|
||||||
*/
|
*/
|
||||||
#ifdef portREMOVE_STATIC_QUALIFIER
|
#ifdef portREMOVE_STATIC_QUALIFIER
|
||||||
#define static
|
#define static
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Lists for ready and blocked co-routines. --------------------*/
|
/* Lists for ready and blocked co-routines. --------------------*/
|
||||||
static List_t pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */
|
static List_t pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /**< Prioritised ready co-routines. */
|
||||||
static List_t xDelayedCoRoutineList1; /*< Delayed co-routines. */
|
static List_t xDelayedCoRoutineList1; /**< Delayed co-routines. */
|
||||||
static List_t xDelayedCoRoutineList2; /*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */
|
static List_t xDelayedCoRoutineList2; /**< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */
|
||||||
static List_t * pxDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used. */
|
static List_t * pxDelayedCoRoutineList = NULL; /**< Points to the delayed co-routine list currently being used. */
|
||||||
static List_t * pxOverflowDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */
|
static List_t * pxOverflowDelayedCoRoutineList = NULL; /**< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */
|
||||||
static List_t xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */
|
static List_t xPendingReadyCoRoutineList; /**< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */
|
||||||
|
|
||||||
/* Other file private variables. --------------------------------*/
|
/* Other file private variables. --------------------------------*/
|
||||||
CRCB_t * pxCurrentCoRoutine = NULL;
|
CRCB_t * pxCurrentCoRoutine = NULL;
|
||||||
static UBaseType_t uxTopCoRoutineReadyPriority = 0;
|
static UBaseType_t uxTopCoRoutineReadyPriority = ( UBaseType_t ) 0U;
|
||||||
static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0;
|
static TickType_t xCoRoutineTickCount = ( TickType_t ) 0U;
|
||||||
|
static TickType_t xLastTickCount = ( TickType_t ) 0U;
|
||||||
|
static TickType_t xPassedTicks = ( TickType_t ) 0U;
|
||||||
|
|
||||||
/* The initial state of the co-routine when it is created. */
|
/* The initial state of the co-routine when it is created. */
|
||||||
#define corINITIAL_STATE ( 0 )
|
#define corINITIAL_STATE ( 0 )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Place the co-routine represented by pxCRCB into the appropriate ready queue
|
* Place the co-routine represented by pxCRCB into the appropriate ready queue
|
||||||
|
@ -106,20 +67,20 @@ static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0;
|
||||||
* This macro accesses the co-routine ready lists and therefore must not be
|
* This macro accesses the co-routine ready lists and therefore must not be
|
||||||
* used from within an ISR.
|
* used from within an ISR.
|
||||||
*/
|
*/
|
||||||
#define prvAddCoRoutineToReadyQueue( pxCRCB ) \
|
#define prvAddCoRoutineToReadyQueue( pxCRCB ) \
|
||||||
{ \
|
do { \
|
||||||
if( pxCRCB->uxPriority > uxTopCoRoutineReadyPriority ) \
|
if( ( pxCRCB )->uxPriority > uxTopCoRoutineReadyPriority ) \
|
||||||
{ \
|
{ \
|
||||||
uxTopCoRoutineReadyPriority = pxCRCB->uxPriority; \
|
uxTopCoRoutineReadyPriority = ( pxCRCB )->uxPriority; \
|
||||||
} \
|
} \
|
||||||
vListInsertEnd( ( List_t * ) &( pxReadyCoRoutineLists[ pxCRCB->uxPriority ] ), &( pxCRCB->xGenericListItem ) ); \
|
vListInsertEnd( ( List_t * ) &( pxReadyCoRoutineLists[ ( pxCRCB )->uxPriority ] ), &( ( pxCRCB )->xGenericListItem ) ); \
|
||||||
}
|
} while( 0 )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Utility to ready all the lists used by the scheduler. This is called
|
* Utility to ready all the lists used by the scheduler. This is called
|
||||||
* automatically upon the creation of the first co-routine.
|
* automatically upon the creation of the first co-routine.
|
||||||
*/
|
*/
|
||||||
static void prvInitialiseCoRoutineLists( void );
|
static void prvInitialiseCoRoutineLists( void );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Co-routines that are readied by an interrupt cannot be placed directly into
|
* Co-routines that are readied by an interrupt cannot be placed directly into
|
||||||
|
@ -127,7 +88,7 @@ static void prvInitialiseCoRoutineLists( void );
|
||||||
* in the pending ready list in order that they can later be moved to the ready
|
* in the pending ready list in order that they can later be moved to the ready
|
||||||
* list by the co-routine scheduler.
|
* list by the co-routine scheduler.
|
||||||
*/
|
*/
|
||||||
static void prvCheckPendingReadyList( void );
|
static void prvCheckPendingReadyList( void );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Macro that looks at the list of co-routines that are currently delayed to
|
* Macro that looks at the list of co-routines that are currently delayed to
|
||||||
|
@ -137,21 +98,29 @@ static void prvCheckPendingReadyList( void );
|
||||||
* meaning once one co-routine has been found whose timer has not expired
|
* meaning once one co-routine has been found whose timer has not expired
|
||||||
* we need not look any further down the list.
|
* we need not look any further down the list.
|
||||||
*/
|
*/
|
||||||
static void prvCheckDelayedList( void );
|
static void prvCheckDelayedList( void );
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex )
|
BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode,
|
||||||
{
|
UBaseType_t uxPriority,
|
||||||
BaseType_t xReturn;
|
UBaseType_t uxIndex )
|
||||||
CRCB_t *pxCoRoutine;
|
{
|
||||||
|
BaseType_t xReturn;
|
||||||
|
CRCB_t * pxCoRoutine;
|
||||||
|
|
||||||
|
traceENTER_xCoRoutineCreate( pxCoRoutineCode, uxPriority, uxIndex );
|
||||||
|
|
||||||
/* Allocate the memory that will store the co-routine control block. */
|
/* Allocate the memory that will store the co-routine control block. */
|
||||||
|
/* MISRA Ref 11.5.1 [Malloc memory assignment] */
|
||||||
|
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
|
||||||
|
/* coverity[misra_c_2012_rule_11_5_violation] */
|
||||||
pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) );
|
pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) );
|
||||||
|
|
||||||
if( pxCoRoutine )
|
if( pxCoRoutine )
|
||||||
{
|
{
|
||||||
/* If pxCurrentCoRoutine is NULL then this is the first co-routine to
|
/* If pxCurrentCoRoutine is NULL then this is the first co-routine to
|
||||||
be created and the co-routine data structures need initialising. */
|
* be created and the co-routine data structures need initialising. */
|
||||||
if( pxCurrentCoRoutine == NULL )
|
if( pxCurrentCoRoutine == NULL )
|
||||||
{
|
{
|
||||||
pxCurrentCoRoutine = pxCoRoutine;
|
pxCurrentCoRoutine = pxCoRoutine;
|
||||||
|
@ -175,8 +144,8 @@ CRCB_t *pxCoRoutine;
|
||||||
vListInitialiseItem( &( pxCoRoutine->xEventListItem ) );
|
vListInitialiseItem( &( pxCoRoutine->xEventListItem ) );
|
||||||
|
|
||||||
/* Set the co-routine control block as a link back from the ListItem_t.
|
/* Set the co-routine control block as a link back from the ListItem_t.
|
||||||
This is so we can get back to the containing CRCB from a generic item
|
* This is so we can get back to the containing CRCB from a generic item
|
||||||
in a list. */
|
* in a list. */
|
||||||
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine );
|
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine );
|
||||||
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine );
|
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine );
|
||||||
|
|
||||||
|
@ -184,7 +153,7 @@ CRCB_t *pxCoRoutine;
|
||||||
listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), ( ( TickType_t ) configMAX_CO_ROUTINE_PRIORITIES - ( TickType_t ) uxPriority ) );
|
listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), ( ( TickType_t ) configMAX_CO_ROUTINE_PRIORITIES - ( TickType_t ) uxPriority ) );
|
||||||
|
|
||||||
/* Now the co-routine has been initialised it can be added to the ready
|
/* Now the co-routine has been initialised it can be added to the ready
|
||||||
list at the correct priority. */
|
* list at the correct priority. */
|
||||||
prvAddCoRoutineToReadyQueue( pxCoRoutine );
|
prvAddCoRoutineToReadyQueue( pxCoRoutine );
|
||||||
|
|
||||||
xReturn = pdPASS;
|
xReturn = pdPASS;
|
||||||
|
@ -194,21 +163,26 @@ CRCB_t *pxCoRoutine;
|
||||||
xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
|
xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
traceRETURN_xCoRoutineCreate( xReturn );
|
||||||
|
|
||||||
return xReturn;
|
return xReturn;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList )
|
void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay,
|
||||||
{
|
List_t * pxEventList )
|
||||||
TickType_t xTimeToWake;
|
{
|
||||||
|
TickType_t xTimeToWake;
|
||||||
|
|
||||||
|
traceENTER_vCoRoutineAddToDelayedList( xTicksToDelay, pxEventList );
|
||||||
|
|
||||||
/* Calculate the time to wake - this may overflow but this is
|
/* Calculate the time to wake - this may overflow but this is
|
||||||
not a problem. */
|
* not a problem. */
|
||||||
xTimeToWake = xCoRoutineTickCount + xTicksToDelay;
|
xTimeToWake = xCoRoutineTickCount + xTicksToDelay;
|
||||||
|
|
||||||
/* We must remove ourselves from the ready list before adding
|
/* We must remove ourselves from the ready list before adding
|
||||||
ourselves to the blocked list as the same list item is used for
|
* ourselves to the blocked list as the same list item is used for
|
||||||
both lists. */
|
* both lists. */
|
||||||
( void ) uxListRemove( ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
( void ) uxListRemove( ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
||||||
|
|
||||||
/* The list item will be inserted in wake time order. */
|
/* The list item will be inserted in wake time order. */
|
||||||
|
@ -217,38 +191,40 @@ TickType_t xTimeToWake;
|
||||||
if( xTimeToWake < xCoRoutineTickCount )
|
if( xTimeToWake < xCoRoutineTickCount )
|
||||||
{
|
{
|
||||||
/* Wake time has overflowed. Place this item in the
|
/* Wake time has overflowed. Place this item in the
|
||||||
overflow list. */
|
* overflow list. */
|
||||||
vListInsert( ( List_t * ) pxOverflowDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
vListInsert( ( List_t * ) pxOverflowDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* The wake time has not overflowed, so we can use the
|
/* The wake time has not overflowed, so we can use the
|
||||||
current block list. */
|
* current block list. */
|
||||||
vListInsert( ( List_t * ) pxDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
vListInsert( ( List_t * ) pxDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pxEventList )
|
if( pxEventList )
|
||||||
{
|
{
|
||||||
/* Also add the co-routine to an event list. If this is done then the
|
/* Also add the co-routine to an event list. If this is done then the
|
||||||
function must be called with interrupts disabled. */
|
* function must be called with interrupts disabled. */
|
||||||
vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) );
|
vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
traceRETURN_vCoRoutineAddToDelayedList();
|
||||||
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvCheckPendingReadyList( void )
|
static void prvCheckPendingReadyList( void )
|
||||||
{
|
{
|
||||||
/* Are there any co-routines waiting to get moved to the ready list? These
|
/* Are there any co-routines waiting to get moved to the ready list? These
|
||||||
are co-routines that have been readied by an ISR. The ISR cannot access
|
* are co-routines that have been readied by an ISR. The ISR cannot access
|
||||||
the ready lists itself. */
|
* the ready lists itself. */
|
||||||
while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE )
|
while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE )
|
||||||
{
|
{
|
||||||
CRCB_t *pxUnblockedCRCB;
|
CRCB_t * pxUnblockedCRCB;
|
||||||
|
|
||||||
/* The pending ready list can be accessed by an ISR. */
|
/* The pending ready list can be accessed by an ISR. */
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
{
|
{
|
||||||
pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) );
|
pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( ( &xPendingReadyCoRoutineList ) );
|
||||||
( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
|
( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
|
||||||
}
|
}
|
||||||
portENABLE_INTERRUPTS();
|
portENABLE_INTERRUPTS();
|
||||||
|
@ -256,14 +232,15 @@ static void prvCheckPendingReadyList( void )
|
||||||
( void ) uxListRemove( &( pxUnblockedCRCB->xGenericListItem ) );
|
( void ) uxListRemove( &( pxUnblockedCRCB->xGenericListItem ) );
|
||||||
prvAddCoRoutineToReadyQueue( pxUnblockedCRCB );
|
prvAddCoRoutineToReadyQueue( pxUnblockedCRCB );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvCheckDelayedList( void )
|
static void prvCheckDelayedList( void )
|
||||||
{
|
{
|
||||||
CRCB_t *pxCRCB;
|
CRCB_t * pxCRCB;
|
||||||
|
|
||||||
xPassedTicks = xTaskGetTickCount() - xLastTickCount;
|
xPassedTicks = xTaskGetTickCount() - xLastTickCount;
|
||||||
|
|
||||||
while( xPassedTicks )
|
while( xPassedTicks )
|
||||||
{
|
{
|
||||||
xCoRoutineTickCount++;
|
xCoRoutineTickCount++;
|
||||||
|
@ -275,7 +252,7 @@ CRCB_t *pxCRCB;
|
||||||
List_t * pxTemp;
|
List_t * pxTemp;
|
||||||
|
|
||||||
/* Tick count has overflowed so we need to swap the delay lists. If there are
|
/* Tick count has overflowed so we need to swap the delay lists. If there are
|
||||||
any items in pxDelayedCoRoutineList here then there is an error! */
|
* any items in pxDelayedCoRoutineList here then there is an error! */
|
||||||
pxTemp = pxDelayedCoRoutineList;
|
pxTemp = pxDelayedCoRoutineList;
|
||||||
pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList;
|
pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList;
|
||||||
pxOverflowDelayedCoRoutineList = pxTemp;
|
pxOverflowDelayedCoRoutineList = pxTemp;
|
||||||
|
@ -295,14 +272,14 @@ CRCB_t *pxCRCB;
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
{
|
{
|
||||||
/* The event could have occurred just before this critical
|
/* The event could have occurred just before this critical
|
||||||
section. If this is the case then the generic list item will
|
* section. If this is the case then the generic list item will
|
||||||
have been moved to the pending ready list and the following
|
* have been moved to the pending ready list and the following
|
||||||
line is still valid. Also the pvContainer parameter will have
|
* line is still valid. Also the pvContainer parameter will have
|
||||||
been set to NULL so the following lines are also valid. */
|
* been set to NULL so the following lines are also valid. */
|
||||||
( void ) uxListRemove( &( pxCRCB->xGenericListItem ) );
|
( void ) uxListRemove( &( pxCRCB->xGenericListItem ) );
|
||||||
|
|
||||||
/* Is the co-routine waiting on an event also? */
|
/* Is the co-routine waiting on an event also? */
|
||||||
if( pxCRCB->xEventListItem.pvContainer )
|
if( pxCRCB->xEventListItem.pxContainer )
|
||||||
{
|
{
|
||||||
( void ) uxListRemove( &( pxCRCB->xEventListItem ) );
|
( void ) uxListRemove( &( pxCRCB->xEventListItem ) );
|
||||||
}
|
}
|
||||||
|
@ -314,11 +291,18 @@ CRCB_t *pxCRCB;
|
||||||
}
|
}
|
||||||
|
|
||||||
xLastTickCount = xCoRoutineTickCount;
|
xLastTickCount = xCoRoutineTickCount;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vCoRoutineSchedule( void )
|
void vCoRoutineSchedule( void )
|
||||||
{
|
{
|
||||||
|
traceENTER_vCoRoutineSchedule();
|
||||||
|
|
||||||
|
/* Only run a co-routine after prvInitialiseCoRoutineLists() has been
|
||||||
|
* called. prvInitialiseCoRoutineLists() is called automatically when a
|
||||||
|
* co-routine is created. */
|
||||||
|
if( pxDelayedCoRoutineList != NULL )
|
||||||
|
{
|
||||||
/* See if any co-routines readied by events need moving to the ready lists. */
|
/* See if any co-routines readied by events need moving to the ready lists. */
|
||||||
prvCheckPendingReadyList();
|
prvCheckPendingReadyList();
|
||||||
|
|
||||||
|
@ -333,23 +317,25 @@ void vCoRoutineSchedule( void )
|
||||||
/* No more co-routines to check. */
|
/* No more co-routines to check. */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
--uxTopCoRoutineReadyPriority;
|
--uxTopCoRoutineReadyPriority;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines
|
/* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines
|
||||||
of the same priority get an equal share of the processor time. */
|
* of the same priority get an equal share of the processor time. */
|
||||||
listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) );
|
listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) );
|
||||||
|
|
||||||
/* Call the co-routine. */
|
/* Call the co-routine. */
|
||||||
( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex );
|
( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex );
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
traceRETURN_vCoRoutineSchedule();
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvInitialiseCoRoutineLists( void )
|
static void prvInitialiseCoRoutineLists( void )
|
||||||
{
|
{
|
||||||
UBaseType_t uxPriority;
|
UBaseType_t uxPriority;
|
||||||
|
|
||||||
for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ )
|
for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ )
|
||||||
{
|
{
|
||||||
|
@ -361,20 +347,22 @@ UBaseType_t uxPriority;
|
||||||
vListInitialise( ( List_t * ) &xPendingReadyCoRoutineList );
|
vListInitialise( ( List_t * ) &xPendingReadyCoRoutineList );
|
||||||
|
|
||||||
/* Start with pxDelayedCoRoutineList using list1 and the
|
/* Start with pxDelayedCoRoutineList using list1 and the
|
||||||
pxOverflowDelayedCoRoutineList using list2. */
|
* pxOverflowDelayedCoRoutineList using list2. */
|
||||||
pxDelayedCoRoutineList = &xDelayedCoRoutineList1;
|
pxDelayedCoRoutineList = &xDelayedCoRoutineList1;
|
||||||
pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2;
|
pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList )
|
BaseType_t xCoRoutineRemoveFromEventList( const List_t * pxEventList )
|
||||||
{
|
{
|
||||||
CRCB_t *pxUnblockedCRCB;
|
CRCB_t * pxUnblockedCRCB;
|
||||||
BaseType_t xReturn;
|
BaseType_t xReturn;
|
||||||
|
|
||||||
|
traceENTER_xCoRoutineRemoveFromEventList( pxEventList );
|
||||||
|
|
||||||
/* This function is called from within an interrupt. It can only access
|
/* This function is called from within an interrupt. It can only access
|
||||||
event lists and the pending ready list. This function assumes that a
|
* event lists and the pending ready list. This function assumes that a
|
||||||
check has already been made to ensure pxEventList is not empty. */
|
* check has already been made to ensure pxEventList is not empty. */
|
||||||
pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
|
pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
|
||||||
( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
|
( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
|
||||||
vListInsertEnd( ( List_t * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) );
|
vListInsertEnd( ( List_t * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) );
|
||||||
|
@ -388,8 +376,30 @@ BaseType_t xReturn;
|
||||||
xReturn = pdFALSE;
|
xReturn = pdFALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
traceRETURN_xCoRoutineRemoveFromEventList( xReturn );
|
||||||
|
|
||||||
return xReturn;
|
return xReturn;
|
||||||
}
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reset state in this file. This state is normally initialized at start up.
|
||||||
|
* This function must be called by the application before restarting the
|
||||||
|
* scheduler.
|
||||||
|
*/
|
||||||
|
void vCoRoutineResetState( void )
|
||||||
|
{
|
||||||
|
/* Lists for ready and blocked co-routines. */
|
||||||
|
pxDelayedCoRoutineList = NULL;
|
||||||
|
pxOverflowDelayedCoRoutineList = NULL;
|
||||||
|
|
||||||
|
/* Other file private variables. */
|
||||||
|
pxCurrentCoRoutine = NULL;
|
||||||
|
uxTopCoRoutineReadyPriority = ( UBaseType_t ) 0U;
|
||||||
|
xCoRoutineTickCount = ( TickType_t ) 0U;
|
||||||
|
xLastTickCount = ( TickType_t ) 0U;
|
||||||
|
xPassedTicks = ( TickType_t ) 0U;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#endif /* configUSE_CO_ROUTINES == 0 */
|
#endif /* configUSE_CO_ROUTINES == 0 */
|
||||||
|
|
||||||
|
|
|
@ -1,78 +1,37 @@
|
||||||
/*
|
/*
|
||||||
FreeRTOS V8.2.3 - Copyright (C) 2015 Real Time Engineers Ltd.
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
All rights reserved
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
This file is part of the FreeRTOS distribution.
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
* the Software without restriction, including without limitation the rights to
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
***************************************************************************
|
*
|
||||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
* copies or substantial portions of the Software.
|
||||||
>>! obliged to provide the source code for proprietary components !<<
|
*
|
||||||
>>! outside of the FreeRTOS kernel. !<<
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
***************************************************************************
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
link: http://www.freertos.org/a00114.html
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
***************************************************************************
|
* https://github.com/FreeRTOS
|
||||||
* *
|
*
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
*/
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
|
||||||
* platform software that is more than just the market leader, it *
|
|
||||||
* is the industry's de facto standard. *
|
|
||||||
* *
|
|
||||||
* Help yourself get started quickly while simultaneously helping *
|
|
||||||
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
|
||||||
* tutorial book, reference manual, or both: *
|
|
||||||
* http://www.FreeRTOS.org/Documentation *
|
|
||||||
* *
|
|
||||||
***************************************************************************
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
|
||||||
the FAQ page "My application does not run, what could be wrong?". Have you
|
|
||||||
defined configASSERT()?
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
|
||||||
embedded software for free we request you assist our global community by
|
|
||||||
participating in the support forum.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
|
||||||
be as productive as possible as early as possible. Now you can receive
|
|
||||||
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
|
||||||
Ltd, and the world's leading authority on the world's leading RTOS.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
|
||||||
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
|
||||||
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and commercial middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Standard includes. */
|
/* Standard includes. */
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
|
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
|
||||||
all the API functions to use the MPU wrappers. That should only be done when
|
* all the API functions to use the MPU wrappers. That should only be done when
|
||||||
task.h is included from an application file. */
|
* task.h is included from an application file. */
|
||||||
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||||
|
|
||||||
/* FreeRTOS includes. */
|
/* FreeRTOS includes. */
|
||||||
|
@ -81,45 +40,30 @@ task.h is included from an application file. */
|
||||||
#include "timers.h"
|
#include "timers.h"
|
||||||
#include "event_groups.h"
|
#include "event_groups.h"
|
||||||
|
|
||||||
/* Lint e961 and e750 are suppressed as a MISRA exception justified because the
|
/* The MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined
|
||||||
MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the
|
* for the header files above, but not in this file, in order to generate the
|
||||||
header files above, but not in this file, in order to generate the correct
|
* correct privileged Vs unprivileged linkage and placement. */
|
||||||
privileged Vs unprivileged linkage and placement. */
|
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */
|
|
||||||
|
|
||||||
#if ( INCLUDE_xEventGroupSetBitFromISR == 1 ) && ( configUSE_TIMERS == 0 )
|
/* This entire source file will be skipped if the application is not configured
|
||||||
#error configUSE_TIMERS must be set to 1 to make the xEventGroupSetBitFromISR() function available.
|
* to include event groups functionality. This #if is closed at the very bottom
|
||||||
#endif
|
* of this file. If you want to include event groups then ensure
|
||||||
|
* configUSE_EVENT_GROUPS is set to 1 in FreeRTOSConfig.h. */
|
||||||
|
#if ( configUSE_EVENT_GROUPS == 1 )
|
||||||
|
|
||||||
#if ( INCLUDE_xEventGroupSetBitFromISR == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 0 )
|
typedef struct EventGroupDef_t
|
||||||
#error INCLUDE_xTimerPendFunctionCall must also be set to one to make the xEventGroupSetBitFromISR() function available.
|
{
|
||||||
#endif
|
|
||||||
|
|
||||||
/* The following bit fields convey control information in a task's event list
|
|
||||||
item value. It is important they don't clash with the
|
|
||||||
taskEVENT_LIST_ITEM_VALUE_IN_USE definition. */
|
|
||||||
#if configUSE_16_BIT_TICKS == 1
|
|
||||||
#define eventCLEAR_EVENTS_ON_EXIT_BIT 0x0100U
|
|
||||||
#define eventUNBLOCKED_DUE_TO_BIT_SET 0x0200U
|
|
||||||
#define eventWAIT_FOR_ALL_BITS 0x0400U
|
|
||||||
#define eventEVENT_BITS_CONTROL_BYTES 0xff00U
|
|
||||||
#else
|
|
||||||
#define eventCLEAR_EVENTS_ON_EXIT_BIT 0x01000000UL
|
|
||||||
#define eventUNBLOCKED_DUE_TO_BIT_SET 0x02000000UL
|
|
||||||
#define eventWAIT_FOR_ALL_BITS 0x04000000UL
|
|
||||||
#define eventEVENT_BITS_CONTROL_BYTES 0xff000000UL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct xEventGroupDefinition
|
|
||||||
{
|
|
||||||
EventBits_t uxEventBits;
|
EventBits_t uxEventBits;
|
||||||
List_t xTasksWaitingForBits; /*< List of tasks waiting for a bit to be set. */
|
List_t xTasksWaitingForBits; /**< List of tasks waiting for a bit to be set. */
|
||||||
|
|
||||||
#if( configUSE_TRACE_FACILITY == 1 )
|
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||||
UBaseType_t uxEventGroupNumber;
|
UBaseType_t uxEventGroupNumber;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} EventGroup_t;
|
#if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
|
||||||
|
uint8_t ucStaticallyAllocated; /**< Set to pdTRUE if the event group is statically allocated to ensure no attempt is made to free the memory. */
|
||||||
|
#endif
|
||||||
|
} EventGroup_t;
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -131,19 +75,98 @@ typedef struct xEventGroupDefinition
|
||||||
* wait condition is met if any of the bits set in uxBitsToWait for are also set
|
* wait condition is met if any of the bits set in uxBitsToWait for are also set
|
||||||
* in uxCurrentEventBits.
|
* in uxCurrentEventBits.
|
||||||
*/
|
*/
|
||||||
static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits );
|
static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits,
|
||||||
|
const EventBits_t uxBitsToWaitFor,
|
||||||
|
const BaseType_t xWaitForAllBits ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
EventGroupHandle_t xEventGroupCreate( void )
|
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
{
|
|
||||||
EventGroup_t *pxEventBits;
|
EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer )
|
||||||
|
{
|
||||||
|
EventGroup_t * pxEventBits;
|
||||||
|
|
||||||
|
traceENTER_xEventGroupCreateStatic( pxEventGroupBuffer );
|
||||||
|
|
||||||
|
/* A StaticEventGroup_t object must be provided. */
|
||||||
|
configASSERT( pxEventGroupBuffer );
|
||||||
|
|
||||||
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
|
{
|
||||||
|
/* Sanity check that the size of the structure used to declare a
|
||||||
|
* variable of type StaticEventGroup_t equals the size of the real
|
||||||
|
* event group structure. */
|
||||||
|
volatile size_t xSize = sizeof( StaticEventGroup_t );
|
||||||
|
configASSERT( xSize == sizeof( EventGroup_t ) );
|
||||||
|
}
|
||||||
|
#endif /* configASSERT_DEFINED */
|
||||||
|
|
||||||
|
/* The user has provided a statically allocated event group - use it. */
|
||||||
|
/* MISRA Ref 11.3.1 [Misaligned access] */
|
||||||
|
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-113 */
|
||||||
|
/* coverity[misra_c_2012_rule_11_3_violation] */
|
||||||
|
pxEventBits = ( EventGroup_t * ) pxEventGroupBuffer;
|
||||||
|
|
||||||
pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) );
|
|
||||||
if( pxEventBits != NULL )
|
if( pxEventBits != NULL )
|
||||||
{
|
{
|
||||||
pxEventBits->uxEventBits = 0;
|
pxEventBits->uxEventBits = 0;
|
||||||
vListInitialise( &( pxEventBits->xTasksWaitingForBits ) );
|
vListInitialise( &( pxEventBits->xTasksWaitingForBits ) );
|
||||||
|
|
||||||
|
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||||
|
{
|
||||||
|
/* Both static and dynamic allocation can be used, so note that
|
||||||
|
* this event group was created statically in case the event group
|
||||||
|
* is later deleted. */
|
||||||
|
pxEventBits->ucStaticallyAllocated = pdTRUE;
|
||||||
|
}
|
||||||
|
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||||
|
|
||||||
|
traceEVENT_GROUP_CREATE( pxEventBits );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* xEventGroupCreateStatic should only ever be called with
|
||||||
|
* pxEventGroupBuffer pointing to a pre-allocated (compile time
|
||||||
|
* allocated) StaticEventGroup_t variable. */
|
||||||
|
traceEVENT_GROUP_CREATE_FAILED();
|
||||||
|
}
|
||||||
|
|
||||||
|
traceRETURN_xEventGroupCreateStatic( pxEventBits );
|
||||||
|
|
||||||
|
return pxEventBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||||
|
|
||||||
|
EventGroupHandle_t xEventGroupCreate( void )
|
||||||
|
{
|
||||||
|
EventGroup_t * pxEventBits;
|
||||||
|
|
||||||
|
traceENTER_xEventGroupCreate();
|
||||||
|
|
||||||
|
/* MISRA Ref 11.5.1 [Malloc memory assignment] */
|
||||||
|
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
|
||||||
|
/* coverity[misra_c_2012_rule_11_5_violation] */
|
||||||
|
pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) );
|
||||||
|
|
||||||
|
if( pxEventBits != NULL )
|
||||||
|
{
|
||||||
|
pxEventBits->uxEventBits = 0;
|
||||||
|
vListInitialise( &( pxEventBits->xTasksWaitingForBits ) );
|
||||||
|
|
||||||
|
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
|
{
|
||||||
|
/* Both static and dynamic allocation can be used, so note this
|
||||||
|
* event group was allocated statically in case the event group is
|
||||||
|
* later deleted. */
|
||||||
|
pxEventBits->ucStaticallyAllocated = pdFALSE;
|
||||||
|
}
|
||||||
|
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||||
|
|
||||||
traceEVENT_GROUP_CREATE( pxEventBits );
|
traceEVENT_GROUP_CREATE( pxEventBits );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -151,16 +174,25 @@ EventGroup_t *pxEventBits;
|
||||||
traceEVENT_GROUP_CREATE_FAILED();
|
traceEVENT_GROUP_CREATE_FAILED();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ( EventGroupHandle_t ) pxEventBits;
|
traceRETURN_xEventGroupCreate( pxEventBits );
|
||||||
}
|
|
||||||
|
return pxEventBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait )
|
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup,
|
||||||
{
|
const EventBits_t uxBitsToSet,
|
||||||
EventBits_t uxOriginalBitValue, uxReturn;
|
const EventBits_t uxBitsToWaitFor,
|
||||||
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
|
TickType_t xTicksToWait )
|
||||||
BaseType_t xAlreadyYielded;
|
{
|
||||||
BaseType_t xTimeoutOccurred = pdFALSE;
|
EventBits_t uxOriginalBitValue, uxReturn;
|
||||||
|
EventGroup_t * pxEventBits = xEventGroup;
|
||||||
|
BaseType_t xAlreadyYielded;
|
||||||
|
BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
|
|
||||||
|
traceENTER_xEventGroupSync( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTicksToWait );
|
||||||
|
|
||||||
configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||||
configASSERT( uxBitsToWaitFor != 0 );
|
configASSERT( uxBitsToWaitFor != 0 );
|
||||||
|
@ -182,7 +214,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
uxReturn = ( uxOriginalBitValue | uxBitsToSet );
|
uxReturn = ( uxOriginalBitValue | uxBitsToSet );
|
||||||
|
|
||||||
/* Rendezvous always clear the bits. They will have been cleared
|
/* Rendezvous always clear the bits. They will have been cleared
|
||||||
already unless this is the only task in the rendezvous. */
|
* already unless this is the only task in the rendezvous. */
|
||||||
pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
|
pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
|
||||||
|
|
||||||
xTicksToWait = 0;
|
xTicksToWait = 0;
|
||||||
|
@ -194,21 +226,22 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor );
|
traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor );
|
||||||
|
|
||||||
/* Store the bits that the calling task is waiting for in the
|
/* Store the bits that the calling task is waiting for in the
|
||||||
task's event list item so the kernel knows when a match is
|
* task's event list item so the kernel knows when a match is
|
||||||
found. Then enter the blocked state. */
|
* found. Then enter the blocked state. */
|
||||||
vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | eventCLEAR_EVENTS_ON_EXIT_BIT | eventWAIT_FOR_ALL_BITS ), xTicksToWait );
|
vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | eventCLEAR_EVENTS_ON_EXIT_BIT | eventWAIT_FOR_ALL_BITS ), xTicksToWait );
|
||||||
|
|
||||||
/* This assignment is obsolete as uxReturn will get set after
|
/* This assignment is obsolete as uxReturn will get set after
|
||||||
the task unblocks, but some compilers mistakenly generate a
|
* the task unblocks, but some compilers mistakenly generate a
|
||||||
warning about uxReturn being returned without being set if the
|
* warning about uxReturn being returned without being set if the
|
||||||
assignment is omitted. */
|
* assignment is omitted. */
|
||||||
uxReturn = 0;
|
uxReturn = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* The rendezvous bits were not set, but no block time was
|
/* The rendezvous bits were not set, but no block time was
|
||||||
specified - just return the current event bit value. */
|
* specified - just return the current event bit value. */
|
||||||
uxReturn = pxEventBits->uxEventBits;
|
uxReturn = pxEventBits->uxEventBits;
|
||||||
|
xTimeoutOccurred = pdTRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -218,7 +251,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
{
|
{
|
||||||
if( xAlreadyYielded == pdFALSE )
|
if( xAlreadyYielded == pdFALSE )
|
||||||
{
|
{
|
||||||
portYIELD_WITHIN_API();
|
taskYIELD_WITHIN_API();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -226,9 +259,9 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The task blocked to wait for its required bits to be set - at this
|
/* The task blocked to wait for its required bits to be set - at this
|
||||||
point either the required bits were set or the block time expired. If
|
* point either the required bits were set or the block time expired. If
|
||||||
the required bits were set they will have been stored in the task's
|
* the required bits were set they will have been stored in the task's
|
||||||
event list item, and they should now be retrieved then cleared. */
|
* event list item, and they should now be retrieved then cleared. */
|
||||||
uxReturn = uxTaskResetEventItemValue();
|
uxReturn = uxTaskResetEventItemValue();
|
||||||
|
|
||||||
if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 )
|
if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 )
|
||||||
|
@ -239,9 +272,9 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
uxReturn = pxEventBits->uxEventBits;
|
uxReturn = pxEventBits->uxEventBits;
|
||||||
|
|
||||||
/* Although the task got here because it timed out before the
|
/* Although the task got here because it timed out before the
|
||||||
bits it was waiting for were set, it is possible that since it
|
* bits it was waiting for were set, it is possible that since it
|
||||||
unblocked another task has set the bits. If this is the case
|
* unblocked another task has set the bits. If this is the case
|
||||||
then it needs to clear the bits before exiting. */
|
* then it needs to clear the bits before exiting. */
|
||||||
if( ( uxReturn & uxBitsToWaitFor ) == uxBitsToWaitFor )
|
if( ( uxReturn & uxBitsToWaitFor ) == uxBitsToWaitFor )
|
||||||
{
|
{
|
||||||
pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
|
pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
|
||||||
|
@ -261,25 +294,36 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Control bits might be set as the task had blocked should not be
|
/* Control bits might be set as the task had blocked should not be
|
||||||
returned. */
|
* returned. */
|
||||||
uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
|
uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
|
||||||
}
|
}
|
||||||
|
|
||||||
traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred );
|
traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred );
|
||||||
|
|
||||||
|
/* Prevent compiler warnings when trace macros are not used. */
|
||||||
|
( void ) xTimeoutOccurred;
|
||||||
|
|
||||||
|
traceRETURN_xEventGroupSync( uxReturn );
|
||||||
|
|
||||||
return uxReturn;
|
return uxReturn;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait )
|
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
|
||||||
{
|
const EventBits_t uxBitsToWaitFor,
|
||||||
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
|
const BaseType_t xClearOnExit,
|
||||||
EventBits_t uxReturn, uxControlBits = 0;
|
const BaseType_t xWaitForAllBits,
|
||||||
BaseType_t xWaitConditionMet, xAlreadyYielded;
|
TickType_t xTicksToWait )
|
||||||
BaseType_t xTimeoutOccurred = pdFALSE;
|
{
|
||||||
|
EventGroup_t * pxEventBits = xEventGroup;
|
||||||
|
EventBits_t uxReturn, uxControlBits = 0;
|
||||||
|
BaseType_t xWaitConditionMet, xAlreadyYielded;
|
||||||
|
BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
|
|
||||||
|
traceENTER_xEventGroupWaitBits( xEventGroup, uxBitsToWaitFor, xClearOnExit, xWaitForAllBits, xTicksToWait );
|
||||||
|
|
||||||
/* Check the user is not attempting to wait on the bits used by the kernel
|
/* Check the user is not attempting to wait on the bits used by the kernel
|
||||||
itself, and that at least one bit is being requested. */
|
* itself, and that at least one bit is being requested. */
|
||||||
configASSERT( xEventGroup );
|
configASSERT( xEventGroup );
|
||||||
configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||||
configASSERT( uxBitsToWaitFor != 0 );
|
configASSERT( uxBitsToWaitFor != 0 );
|
||||||
|
@ -299,7 +343,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
if( xWaitConditionMet != pdFALSE )
|
if( xWaitConditionMet != pdFALSE )
|
||||||
{
|
{
|
||||||
/* The wait condition has already been met so there is no need to
|
/* The wait condition has already been met so there is no need to
|
||||||
block. */
|
* block. */
|
||||||
uxReturn = uxCurrentEventBits;
|
uxReturn = uxCurrentEventBits;
|
||||||
xTicksToWait = ( TickType_t ) 0;
|
xTicksToWait = ( TickType_t ) 0;
|
||||||
|
|
||||||
|
@ -316,15 +360,16 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
else if( xTicksToWait == ( TickType_t ) 0 )
|
else if( xTicksToWait == ( TickType_t ) 0 )
|
||||||
{
|
{
|
||||||
/* The wait condition has not been met, but no block time was
|
/* The wait condition has not been met, but no block time was
|
||||||
specified, so just return the current value. */
|
* specified, so just return the current value. */
|
||||||
uxReturn = uxCurrentEventBits;
|
uxReturn = uxCurrentEventBits;
|
||||||
|
xTimeoutOccurred = pdTRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* The task is going to block to wait for its required bits to be
|
/* The task is going to block to wait for its required bits to be
|
||||||
set. uxControlBits are used to remember the specified behaviour of
|
* set. uxControlBits are used to remember the specified behaviour of
|
||||||
this call to xEventGroupWaitBits() - for use when the event bits
|
* this call to xEventGroupWaitBits() - for use when the event bits
|
||||||
unblock the task. */
|
* unblock the task. */
|
||||||
if( xClearOnExit != pdFALSE )
|
if( xClearOnExit != pdFALSE )
|
||||||
{
|
{
|
||||||
uxControlBits |= eventCLEAR_EVENTS_ON_EXIT_BIT;
|
uxControlBits |= eventCLEAR_EVENTS_ON_EXIT_BIT;
|
||||||
|
@ -344,13 +389,13 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store the bits that the calling task is waiting for in the
|
/* Store the bits that the calling task is waiting for in the
|
||||||
task's event list item so the kernel knows when a match is
|
* task's event list item so the kernel knows when a match is
|
||||||
found. Then enter the blocked state. */
|
* found. Then enter the blocked state. */
|
||||||
vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait );
|
vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait );
|
||||||
|
|
||||||
/* This is obsolete as it will get set after the task unblocks, but
|
/* This is obsolete as it will get set after the task unblocks, but
|
||||||
some compilers mistakenly generate a warning about the variable
|
* some compilers mistakenly generate a warning about the variable
|
||||||
being returned without being set if it is not done. */
|
* being returned without being set if it is not done. */
|
||||||
uxReturn = 0;
|
uxReturn = 0;
|
||||||
|
|
||||||
traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor );
|
traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor );
|
||||||
|
@ -362,7 +407,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
{
|
{
|
||||||
if( xAlreadyYielded == pdFALSE )
|
if( xAlreadyYielded == pdFALSE )
|
||||||
{
|
{
|
||||||
portYIELD_WITHIN_API();
|
taskYIELD_WITHIN_API();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -370,9 +415,9 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The task blocked to wait for its required bits to be set - at this
|
/* The task blocked to wait for its required bits to be set - at this
|
||||||
point either the required bits were set or the block time expired. If
|
* point either the required bits were set or the block time expired. If
|
||||||
the required bits were set they will have been stored in the task's
|
* the required bits were set they will have been stored in the task's
|
||||||
event list item, and they should now be retrieved then cleared. */
|
* event list item, and they should now be retrieved then cleared. */
|
||||||
uxReturn = uxTaskResetEventItemValue();
|
uxReturn = uxTaskResetEventItemValue();
|
||||||
|
|
||||||
if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 )
|
if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 )
|
||||||
|
@ -383,7 +428,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
uxReturn = pxEventBits->uxEventBits;
|
uxReturn = pxEventBits->uxEventBits;
|
||||||
|
|
||||||
/* It is possible that the event bits were updated between this
|
/* It is possible that the event bits were updated between this
|
||||||
task leaving the Blocked state and running again. */
|
* task leaving the Blocked state and running again. */
|
||||||
if( prvTestWaitCondition( uxReturn, uxBitsToWaitFor, xWaitForAllBits ) != pdFALSE )
|
if( prvTestWaitCondition( uxReturn, uxBitsToWaitFor, xWaitForAllBits ) != pdFALSE )
|
||||||
{
|
{
|
||||||
if( xClearOnExit != pdFALSE )
|
if( xClearOnExit != pdFALSE )
|
||||||
|
@ -399,11 +444,10 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
{
|
{
|
||||||
mtCOVERAGE_TEST_MARKER();
|
mtCOVERAGE_TEST_MARKER();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xTimeoutOccurred = pdTRUE;
|
||||||
}
|
}
|
||||||
taskEXIT_CRITICAL();
|
taskEXIT_CRITICAL();
|
||||||
|
|
||||||
/* Prevent compiler warnings when trace macros are not used. */
|
|
||||||
xTimeoutOccurred = pdFALSE;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -413,19 +457,28 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
/* The task blocked so control bits may have been set. */
|
/* The task blocked so control bits may have been set. */
|
||||||
uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
|
uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
|
||||||
}
|
}
|
||||||
|
|
||||||
traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred );
|
traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred );
|
||||||
|
|
||||||
|
/* Prevent compiler warnings when trace macros are not used. */
|
||||||
|
( void ) xTimeoutOccurred;
|
||||||
|
|
||||||
|
traceRETURN_xEventGroupWaitBits( uxReturn );
|
||||||
|
|
||||||
return uxReturn;
|
return uxReturn;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )
|
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup,
|
||||||
{
|
const EventBits_t uxBitsToClear )
|
||||||
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
|
{
|
||||||
EventBits_t uxReturn;
|
EventGroup_t * pxEventBits = xEventGroup;
|
||||||
|
EventBits_t uxReturn;
|
||||||
|
|
||||||
|
traceENTER_xEventGroupClearBits( xEventGroup, uxBitsToClear );
|
||||||
|
|
||||||
/* Check the user is not attempting to clear the bits used by the kernel
|
/* Check the user is not attempting to clear the bits used by the kernel
|
||||||
itself. */
|
* itself. */
|
||||||
configASSERT( xEventGroup );
|
configASSERT( xEventGroup );
|
||||||
configASSERT( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
configASSERT( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||||
|
|
||||||
|
@ -434,7 +487,7 @@ EventBits_t uxReturn;
|
||||||
traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear );
|
traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear );
|
||||||
|
|
||||||
/* The value returned is the event group value prior to the bits being
|
/* The value returned is the event group value prior to the bits being
|
||||||
cleared. */
|
* cleared. */
|
||||||
uxReturn = pxEventBits->uxEventBits;
|
uxReturn = pxEventBits->uxEventBits;
|
||||||
|
|
||||||
/* Clear the bits. */
|
/* Clear the bits. */
|
||||||
|
@ -442,57 +495,75 @@ EventBits_t uxReturn;
|
||||||
}
|
}
|
||||||
taskEXIT_CRITICAL();
|
taskEXIT_CRITICAL();
|
||||||
|
|
||||||
|
traceRETURN_xEventGroupClearBits( uxReturn );
|
||||||
|
|
||||||
return uxReturn;
|
return uxReturn;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
|
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
|
||||||
|
|
||||||
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )
|
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup,
|
||||||
|
const EventBits_t uxBitsToClear )
|
||||||
{
|
{
|
||||||
BaseType_t xReturn;
|
BaseType_t xReturn;
|
||||||
|
|
||||||
|
traceENTER_xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear );
|
||||||
|
|
||||||
traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear );
|
traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear );
|
||||||
xReturn = xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL );
|
xReturn = xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL );
|
||||||
|
|
||||||
|
traceRETURN_xEventGroupClearBitsFromISR( xReturn );
|
||||||
|
|
||||||
return xReturn;
|
return xReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif /* if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup )
|
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup )
|
||||||
{
|
{
|
||||||
UBaseType_t uxSavedInterruptStatus;
|
UBaseType_t uxSavedInterruptStatus;
|
||||||
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
|
EventGroup_t const * const pxEventBits = xEventGroup;
|
||||||
EventBits_t uxReturn;
|
EventBits_t uxReturn;
|
||||||
|
|
||||||
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
|
traceENTER_xEventGroupGetBitsFromISR( xEventGroup );
|
||||||
|
|
||||||
|
/* MISRA Ref 4.7.1 [Return value shall be checked] */
|
||||||
|
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */
|
||||||
|
/* coverity[misra_c_2012_directive_4_7_violation] */
|
||||||
|
uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR();
|
||||||
{
|
{
|
||||||
uxReturn = pxEventBits->uxEventBits;
|
uxReturn = pxEventBits->uxEventBits;
|
||||||
}
|
}
|
||||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
|
taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus );
|
||||||
|
|
||||||
|
traceRETURN_xEventGroupGetBitsFromISR( uxReturn );
|
||||||
|
|
||||||
return uxReturn;
|
return uxReturn;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet )
|
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
|
||||||
{
|
const EventBits_t uxBitsToSet )
|
||||||
ListItem_t *pxListItem, *pxNext;
|
{
|
||||||
ListItem_t const *pxListEnd;
|
ListItem_t * pxListItem;
|
||||||
List_t *pxList;
|
ListItem_t * pxNext;
|
||||||
EventBits_t uxBitsToClear = 0, uxBitsWaitedFor, uxControlBits;
|
ListItem_t const * pxListEnd;
|
||||||
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
|
List_t const * pxList;
|
||||||
BaseType_t xMatchFound = pdFALSE;
|
EventBits_t uxBitsToClear = 0, uxBitsWaitedFor, uxControlBits;
|
||||||
|
EventGroup_t * pxEventBits = xEventGroup;
|
||||||
|
BaseType_t xMatchFound = pdFALSE;
|
||||||
|
|
||||||
|
traceENTER_xEventGroupSetBits( xEventGroup, uxBitsToSet );
|
||||||
|
|
||||||
/* Check the user is not attempting to set the bits used by the kernel
|
/* Check the user is not attempting to set the bits used by the kernel
|
||||||
itself. */
|
* itself. */
|
||||||
configASSERT( xEventGroup );
|
configASSERT( xEventGroup );
|
||||||
configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||||
|
|
||||||
pxList = &( pxEventBits->xTasksWaitingForBits );
|
pxList = &( pxEventBits->xTasksWaitingForBits );
|
||||||
pxListEnd = listGET_END_MARKER( pxList ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
pxListEnd = listGET_END_MARKER( pxList );
|
||||||
vTaskSuspendAll();
|
vTaskSuspendAll();
|
||||||
{
|
{
|
||||||
traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet );
|
traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet );
|
||||||
|
@ -548,33 +619,41 @@ BaseType_t xMatchFound = pdFALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store the actual event flag value in the task's event list
|
/* Store the actual event flag value in the task's event list
|
||||||
item before removing the task from the event list. The
|
* item before removing the task from the event list. The
|
||||||
eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows
|
* eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows
|
||||||
that is was unblocked due to its required bits matching, rather
|
* that is was unblocked due to its required bits matching, rather
|
||||||
than because it timed out. */
|
* than because it timed out. */
|
||||||
( void ) xTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET );
|
vTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Move onto the next list item. Note pxListItem->pxNext is not
|
/* Move onto the next list item. Note pxListItem->pxNext is not
|
||||||
used here as the list item may have been removed from the event list
|
* used here as the list item may have been removed from the event list
|
||||||
and inserted into the ready/pending reading list. */
|
* and inserted into the ready/pending reading list. */
|
||||||
pxListItem = pxNext;
|
pxListItem = pxNext;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear any bits that matched when the eventCLEAR_EVENTS_ON_EXIT_BIT
|
/* Clear any bits that matched when the eventCLEAR_EVENTS_ON_EXIT_BIT
|
||||||
bit was set in the control word. */
|
* bit was set in the control word. */
|
||||||
pxEventBits->uxEventBits &= ~uxBitsToClear;
|
pxEventBits->uxEventBits &= ~uxBitsToClear;
|
||||||
}
|
}
|
||||||
( void ) xTaskResumeAll();
|
( void ) xTaskResumeAll();
|
||||||
|
|
||||||
|
traceRETURN_xEventGroupSetBits( pxEventBits->uxEventBits );
|
||||||
|
|
||||||
return pxEventBits->uxEventBits;
|
return pxEventBits->uxEventBits;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vEventGroupDelete( EventGroupHandle_t xEventGroup )
|
void vEventGroupDelete( EventGroupHandle_t xEventGroup )
|
||||||
{
|
{
|
||||||
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
|
EventGroup_t * pxEventBits = xEventGroup;
|
||||||
const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
|
const List_t * pxTasksWaitingForBits;
|
||||||
|
|
||||||
|
traceENTER_vEventGroupDelete( xEventGroup );
|
||||||
|
|
||||||
|
configASSERT( pxEventBits );
|
||||||
|
|
||||||
|
pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
|
||||||
|
|
||||||
vTaskSuspendAll();
|
vTaskSuspendAll();
|
||||||
{
|
{
|
||||||
|
@ -583,41 +662,126 @@ const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
|
||||||
while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 )
|
while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 )
|
||||||
{
|
{
|
||||||
/* Unblock the task, returning 0 as the event list is being deleted
|
/* Unblock the task, returning 0 as the event list is being deleted
|
||||||
and cannot therefore have any bits set. */
|
* and cannot therefore have any bits set. */
|
||||||
configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) );
|
configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( const ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) );
|
||||||
( void ) xTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET );
|
vTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET );
|
||||||
}
|
}
|
||||||
|
|
||||||
vPortFree( pxEventBits );
|
|
||||||
}
|
}
|
||||||
( void ) xTaskResumeAll();
|
( void ) xTaskResumeAll();
|
||||||
}
|
|
||||||
|
#if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) )
|
||||||
|
{
|
||||||
|
/* The event group can only have been allocated dynamically - free
|
||||||
|
* it again. */
|
||||||
|
vPortFree( pxEventBits );
|
||||||
|
}
|
||||||
|
#elif ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
|
||||||
|
{
|
||||||
|
/* The event group could have been allocated statically or
|
||||||
|
* dynamically, so check before attempting to free the memory. */
|
||||||
|
if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdFALSE )
|
||||||
|
{
|
||||||
|
vPortFree( pxEventBits );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||||
|
|
||||||
|
traceRETURN_vEventGroupDelete();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
|
BaseType_t xEventGroupGetStaticBuffer( EventGroupHandle_t xEventGroup,
|
||||||
|
StaticEventGroup_t ** ppxEventGroupBuffer )
|
||||||
|
{
|
||||||
|
BaseType_t xReturn;
|
||||||
|
EventGroup_t * pxEventBits = xEventGroup;
|
||||||
|
|
||||||
|
traceENTER_xEventGroupGetStaticBuffer( xEventGroup, ppxEventGroupBuffer );
|
||||||
|
|
||||||
|
configASSERT( pxEventBits );
|
||||||
|
configASSERT( ppxEventGroupBuffer );
|
||||||
|
|
||||||
|
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||||
|
{
|
||||||
|
/* Check if the event group was statically allocated. */
|
||||||
|
if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdTRUE )
|
||||||
|
{
|
||||||
|
/* MISRA Ref 11.3.1 [Misaligned access] */
|
||||||
|
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-113 */
|
||||||
|
/* coverity[misra_c_2012_rule_11_3_violation] */
|
||||||
|
*ppxEventGroupBuffer = ( StaticEventGroup_t * ) pxEventBits;
|
||||||
|
xReturn = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||||
|
{
|
||||||
|
/* Event group must have been statically allocated. */
|
||||||
|
/* MISRA Ref 11.3.1 [Misaligned access] */
|
||||||
|
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-113 */
|
||||||
|
/* coverity[misra_c_2012_rule_11_3_violation] */
|
||||||
|
*ppxEventGroupBuffer = ( StaticEventGroup_t * ) pxEventBits;
|
||||||
|
xReturn = pdTRUE;
|
||||||
|
}
|
||||||
|
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||||
|
|
||||||
|
traceRETURN_xEventGroupGetStaticBuffer( xReturn );
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* For internal use only - execute a 'set bits' command that was pended from
|
/* For internal use only - execute a 'set bits' command that was pended from
|
||||||
an interrupt. */
|
* an interrupt. */
|
||||||
void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet )
|
void vEventGroupSetBitsCallback( void * pvEventGroup,
|
||||||
{
|
uint32_t ulBitsToSet )
|
||||||
|
{
|
||||||
|
traceENTER_vEventGroupSetBitsCallback( pvEventGroup, ulBitsToSet );
|
||||||
|
|
||||||
|
/* MISRA Ref 11.5.4 [Callback function parameter] */
|
||||||
|
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
|
||||||
|
/* coverity[misra_c_2012_rule_11_5_violation] */
|
||||||
( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet );
|
( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet );
|
||||||
}
|
|
||||||
|
traceRETURN_vEventGroupSetBitsCallback();
|
||||||
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* For internal use only - execute a 'clear bits' command that was pended from
|
/* For internal use only - execute a 'clear bits' command that was pended from
|
||||||
an interrupt. */
|
* an interrupt. */
|
||||||
void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear )
|
void vEventGroupClearBitsCallback( void * pvEventGroup,
|
||||||
{
|
uint32_t ulBitsToClear )
|
||||||
|
{
|
||||||
|
traceENTER_vEventGroupClearBitsCallback( pvEventGroup, ulBitsToClear );
|
||||||
|
|
||||||
|
/* MISRA Ref 11.5.4 [Callback function parameter] */
|
||||||
|
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
|
||||||
|
/* coverity[misra_c_2012_rule_11_5_violation] */
|
||||||
( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear );
|
( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear );
|
||||||
}
|
|
||||||
|
traceRETURN_vEventGroupClearBitsCallback();
|
||||||
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits )
|
static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits,
|
||||||
{
|
const EventBits_t uxBitsToWaitFor,
|
||||||
BaseType_t xWaitConditionMet = pdFALSE;
|
const BaseType_t xWaitForAllBits )
|
||||||
|
{
|
||||||
|
BaseType_t xWaitConditionMet = pdFALSE;
|
||||||
|
|
||||||
if( xWaitForAllBits == pdFALSE )
|
if( xWaitForAllBits == pdFALSE )
|
||||||
{
|
{
|
||||||
/* Task only has to wait for one bit within uxBitsToWaitFor to be
|
/* Task only has to wait for one bit within uxBitsToWaitFor to be
|
||||||
set. Is one already set? */
|
* set. Is one already set? */
|
||||||
if( ( uxCurrentEventBits & uxBitsToWaitFor ) != ( EventBits_t ) 0 )
|
if( ( uxCurrentEventBits & uxBitsToWaitFor ) != ( EventBits_t ) 0 )
|
||||||
{
|
{
|
||||||
xWaitConditionMet = pdTRUE;
|
xWaitConditionMet = pdTRUE;
|
||||||
|
@ -630,7 +794,7 @@ BaseType_t xWaitConditionMet = pdFALSE;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Task has to wait for all the bits in uxBitsToWaitFor to be set.
|
/* Task has to wait for all the bits in uxBitsToWaitFor to be set.
|
||||||
Are they set already? */
|
* Are they set already? */
|
||||||
if( ( uxCurrentEventBits & uxBitsToWaitFor ) == uxBitsToWaitFor )
|
if( ( uxCurrentEventBits & uxBitsToWaitFor ) == uxBitsToWaitFor )
|
||||||
{
|
{
|
||||||
xWaitConditionMet = pdTRUE;
|
xWaitConditionMet = pdTRUE;
|
||||||
|
@ -642,30 +806,42 @@ BaseType_t xWaitConditionMet = pdFALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return xWaitConditionMet;
|
return xWaitConditionMet;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
|
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
|
||||||
|
|
||||||
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken )
|
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup,
|
||||||
|
const EventBits_t uxBitsToSet,
|
||||||
|
BaseType_t * pxHigherPriorityTaskWoken )
|
||||||
{
|
{
|
||||||
BaseType_t xReturn;
|
BaseType_t xReturn;
|
||||||
|
|
||||||
|
traceENTER_xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken );
|
||||||
|
|
||||||
traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet );
|
traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet );
|
||||||
xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken );
|
xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken );
|
||||||
|
|
||||||
|
traceRETURN_xEventGroupSetBitsFromISR( xReturn );
|
||||||
|
|
||||||
return xReturn;
|
return xReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif /* if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if (configUSE_TRACE_FACILITY == 1)
|
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||||
|
|
||||||
UBaseType_t uxEventGroupGetNumber( void* xEventGroup )
|
UBaseType_t uxEventGroupGetNumber( void * xEventGroup )
|
||||||
{
|
{
|
||||||
UBaseType_t xReturn;
|
UBaseType_t xReturn;
|
||||||
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
|
|
||||||
|
/* MISRA Ref 11.5.2 [Opaque pointer] */
|
||||||
|
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
|
||||||
|
/* coverity[misra_c_2012_rule_11_5_violation] */
|
||||||
|
EventGroup_t const * pxEventBits = ( EventGroup_t * ) xEventGroup;
|
||||||
|
|
||||||
|
traceENTER_uxEventGroupGetNumber( xEventGroup );
|
||||||
|
|
||||||
if( xEventGroup == NULL )
|
if( xEventGroup == NULL )
|
||||||
{
|
{
|
||||||
|
@ -676,8 +852,33 @@ BaseType_t xWaitConditionMet = pdFALSE;
|
||||||
xReturn = pxEventBits->uxEventGroupNumber;
|
xReturn = pxEventBits->uxEventGroupNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
traceRETURN_uxEventGroupGetNumber( xReturn );
|
||||||
|
|
||||||
return xReturn;
|
return xReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif /* configUSE_TRACE_FACILITY */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||||
|
|
||||||
|
void vEventGroupSetNumber( void * xEventGroup,
|
||||||
|
UBaseType_t uxEventGroupNumber )
|
||||||
|
{
|
||||||
|
traceENTER_vEventGroupSetNumber( xEventGroup, uxEventGroupNumber );
|
||||||
|
|
||||||
|
/* MISRA Ref 11.5.2 [Opaque pointer] */
|
||||||
|
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
|
||||||
|
/* coverity[misra_c_2012_rule_11_5_violation] */
|
||||||
|
( ( EventGroup_t * ) xEventGroup )->uxEventGroupNumber = uxEventGroupNumber;
|
||||||
|
|
||||||
|
traceRETURN_vEventGroupSetNumber();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* configUSE_TRACE_FACILITY */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* This entire source file will be skipped if the application is not configured
|
||||||
|
* to include event groups functionality. If you want to include event groups
|
||||||
|
* then ensure configUSE_EVENT_GROUPS is set to 1 in FreeRTOSConfig.h. */
|
||||||
|
#endif /* configUSE_EVENT_GROUPS == 1 */
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
# FreeRTOS internal cmake file. Do not use it in user top-level project
|
||||||
|
|
||||||
|
add_library(freertos_kernel_include INTERFACE)
|
||||||
|
|
||||||
|
target_include_directories(freertos_kernel_include
|
||||||
|
INTERFACE
|
||||||
|
.
|
||||||
|
# Note: DEPRECATED but still supported, may be removed in a future release.
|
||||||
|
$<$<NOT:$<TARGET_EXISTS:freertos_config>>:${FREERTOS_CONFIG_FILE_DIRECTORY}>
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(freertos_kernel_include
|
||||||
|
INTERFACE
|
||||||
|
$<$<TARGET_EXISTS:freertos_config>:freertos_config>
|
||||||
|
)
|
File diff suppressed because it is too large
Load Diff
|
@ -1,171 +1,34 @@
|
||||||
/*
|
/*
|
||||||
FreeRTOS V8.2.3 - Copyright (C) 2015 Real Time Engineers Ltd.
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
All rights reserved
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
This file is part of the FreeRTOS distribution.
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
* the Software without restriction, including without limitation the rights to
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
***************************************************************************
|
*
|
||||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
* copies or substantial portions of the Software.
|
||||||
>>! obliged to provide the source code for proprietary components !<<
|
*
|
||||||
>>! outside of the FreeRTOS kernel. !<<
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
***************************************************************************
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
link: http://www.freertos.org/a00114.html
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
***************************************************************************
|
* https://github.com/FreeRTOS
|
||||||
* *
|
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
|
||||||
* platform software that is more than just the market leader, it *
|
|
||||||
* is the industry's de facto standard. *
|
|
||||||
* *
|
|
||||||
* Help yourself get started quickly while simultaneously helping *
|
|
||||||
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
|
||||||
* tutorial book, reference manual, or both: *
|
|
||||||
* http://www.FreeRTOS.org/Documentation *
|
|
||||||
* *
|
|
||||||
***************************************************************************
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
|
||||||
the FAQ page "My application does not run, what could be wrong?". Have you
|
|
||||||
defined configASSERT()?
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
|
||||||
embedded software for free we request you assist our global community by
|
|
||||||
participating in the support forum.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
|
||||||
be as productive as possible as early as possible. Now you can receive
|
|
||||||
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
|
||||||
Ltd, and the world's leading authority on the world's leading RTOS.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
|
||||||
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
|
||||||
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and commercial middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef STACK_MACROS_H
|
|
||||||
#define STACK_MACROS_H
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Call the stack overflow hook function if the stack of the task being swapped
|
|
||||||
* out is currently overflowed, or looks like it might have overflowed in the
|
|
||||||
* past.
|
|
||||||
*
|
*
|
||||||
* Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check
|
|
||||||
* the current stack state only - comparing the current top of stack value to
|
|
||||||
* the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1
|
|
||||||
* will also cause the last few stack bytes to be checked to ensure the value
|
|
||||||
* to which the bytes were set when the task was created have not been
|
|
||||||
* overwritten. Note this second test does not guarantee that an overflowed
|
|
||||||
* stack will always be recognised.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
#if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) )
|
#ifndef _MSC_VER /* Visual Studio doesn't support #warning. */
|
||||||
|
#warning The name of this file has changed to stack_macros.h. Please update your code accordingly. This source file (which has the original name) will be removed in a future release.
|
||||||
/* Only the current stack state is to be checked. */
|
|
||||||
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
|
||||||
{ \
|
|
||||||
/* Is the currently saved stack pointer within the stack limit? */ \
|
|
||||||
if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \
|
|
||||||
{ \
|
|
||||||
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
#if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) )
|
|
||||||
|
|
||||||
/* Only the current stack state is to be checked. */
|
|
||||||
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
|
||||||
{ \
|
|
||||||
\
|
|
||||||
/* Is the currently saved stack pointer within the stack limit? */ \
|
|
||||||
if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \
|
|
||||||
{ \
|
|
||||||
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) )
|
|
||||||
|
|
||||||
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
|
||||||
{ \
|
|
||||||
const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \
|
|
||||||
const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5; \
|
|
||||||
\
|
|
||||||
if( ( pulStack[ 0 ] != ulCheckValue ) || \
|
|
||||||
( pulStack[ 1 ] != ulCheckValue ) || \
|
|
||||||
( pulStack[ 2 ] != ulCheckValue ) || \
|
|
||||||
( pulStack[ 3 ] != ulCheckValue ) ) \
|
|
||||||
{ \
|
|
||||||
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) )
|
|
||||||
|
|
||||||
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
|
||||||
{ \
|
|
||||||
int8_t *pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \
|
|
||||||
static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
|
||||||
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
|
||||||
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
|
||||||
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
|
||||||
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \
|
|
||||||
\
|
|
||||||
\
|
|
||||||
pcEndOfStack -= sizeof( ucExpectedStackBytes ); \
|
|
||||||
\
|
|
||||||
/* Has the extremity of the task stack ever been written over? */ \
|
|
||||||
if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \
|
|
||||||
{ \
|
|
||||||
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* Remove stack overflow macro if not being used. */
|
|
||||||
#ifndef taskCHECK_FOR_STACK_OVERFLOW
|
|
||||||
#define taskCHECK_FOR_STACK_OVERFLOW()
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "stack_macros.h"
|
||||||
|
|
||||||
#endif /* STACK_MACROS_H */
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,427 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file atomic.h
|
||||||
|
* @brief FreeRTOS atomic operation support.
|
||||||
|
*
|
||||||
|
* This file implements atomic functions by disabling interrupts globally.
|
||||||
|
* Implementations with architecture specific atomic instructions can be
|
||||||
|
* provided under each compiler directory.
|
||||||
|
*
|
||||||
|
* The atomic interface can be used in FreeRTOS tasks on all FreeRTOS ports. It
|
||||||
|
* can also be used in Interrupt Service Routines (ISRs) on FreeRTOS ports that
|
||||||
|
* support nested interrupts (i.e. portHAS_NESTED_INTERRUPTS is set to 1). The
|
||||||
|
* atomic interface must not be used in ISRs on FreeRTOS ports that do not
|
||||||
|
* support nested interrupts (i.e. portHAS_NESTED_INTERRUPTS is set to 0)
|
||||||
|
* because ISRs on these ports cannot be interrupted and therefore, do not need
|
||||||
|
* atomics in ISRs.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ATOMIC_H
|
||||||
|
#define ATOMIC_H
|
||||||
|
|
||||||
|
#ifndef INC_FREERTOS_H
|
||||||
|
#error "include FreeRTOS.h must appear in source files before include atomic.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Port specific definitions -- entering/exiting critical section.
|
||||||
|
* Refer template -- ./lib/FreeRTOS/portable/Compiler/Arch/portmacro.h
|
||||||
|
*
|
||||||
|
* Every call to ATOMIC_EXIT_CRITICAL() must be closely paired with
|
||||||
|
* ATOMIC_ENTER_CRITICAL().
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#if ( portHAS_NESTED_INTERRUPTS == 1 )
|
||||||
|
|
||||||
|
/* Nested interrupt scheme is supported in this port. */
|
||||||
|
#define ATOMIC_ENTER_CRITICAL() \
|
||||||
|
UBaseType_t uxCriticalSectionType = portSET_INTERRUPT_MASK_FROM_ISR()
|
||||||
|
|
||||||
|
#define ATOMIC_EXIT_CRITICAL() \
|
||||||
|
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxCriticalSectionType )
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* Nested interrupt scheme is NOT supported in this port. */
|
||||||
|
#define ATOMIC_ENTER_CRITICAL() portENTER_CRITICAL()
|
||||||
|
#define ATOMIC_EXIT_CRITICAL() portEXIT_CRITICAL()
|
||||||
|
|
||||||
|
#endif /* portSET_INTERRUPT_MASK_FROM_ISR() */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Port specific definition -- "always inline".
|
||||||
|
* Inline is compiler specific, and may not always get inlined depending on your
|
||||||
|
* optimization level. Also, inline is considered as performance optimization
|
||||||
|
* for atomic. Thus, if portFORCE_INLINE is not provided by portmacro.h,
|
||||||
|
* instead of resulting error, simply define it away.
|
||||||
|
*/
|
||||||
|
#ifndef portFORCE_INLINE
|
||||||
|
#define portFORCE_INLINE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ATOMIC_COMPARE_AND_SWAP_SUCCESS 0x1U /**< Compare and swap succeeded, swapped. */
|
||||||
|
#define ATOMIC_COMPARE_AND_SWAP_FAILURE 0x0U /**< Compare and swap failed, did not swap. */
|
||||||
|
|
||||||
|
/*----------------------------- Swap && CAS ------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Atomic compare-and-swap
|
||||||
|
*
|
||||||
|
* @brief Performs an atomic compare-and-swap operation on the specified values.
|
||||||
|
*
|
||||||
|
* @param[in, out] pulDestination Pointer to memory location from where value is
|
||||||
|
* to be loaded and checked.
|
||||||
|
* @param[in] ulExchange If condition meets, write this value to memory.
|
||||||
|
* @param[in] ulComparand Swap condition.
|
||||||
|
*
|
||||||
|
* @return Unsigned integer of value 1 or 0. 1 for swapped, 0 for not swapped.
|
||||||
|
*
|
||||||
|
* @note This function only swaps *pulDestination with ulExchange, if previous
|
||||||
|
* *pulDestination value equals ulComparand.
|
||||||
|
*/
|
||||||
|
static portFORCE_INLINE uint32_t Atomic_CompareAndSwap_u32( uint32_t volatile * pulDestination,
|
||||||
|
uint32_t ulExchange,
|
||||||
|
uint32_t ulComparand )
|
||||||
|
{
|
||||||
|
uint32_t ulReturnValue;
|
||||||
|
|
||||||
|
ATOMIC_ENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
if( *pulDestination == ulComparand )
|
||||||
|
{
|
||||||
|
*pulDestination = ulExchange;
|
||||||
|
ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ATOMIC_EXIT_CRITICAL();
|
||||||
|
|
||||||
|
return ulReturnValue;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Atomic swap (pointers)
|
||||||
|
*
|
||||||
|
* @brief Atomically sets the address pointed to by *ppvDestination to the value
|
||||||
|
* of *pvExchange.
|
||||||
|
*
|
||||||
|
* @param[in, out] ppvDestination Pointer to memory location from where a pointer
|
||||||
|
* value is to be loaded and written back to.
|
||||||
|
* @param[in] pvExchange Pointer value to be written to *ppvDestination.
|
||||||
|
*
|
||||||
|
* @return The initial value of *ppvDestination.
|
||||||
|
*/
|
||||||
|
static portFORCE_INLINE void * Atomic_SwapPointers_p32( void * volatile * ppvDestination,
|
||||||
|
void * pvExchange )
|
||||||
|
{
|
||||||
|
void * pReturnValue;
|
||||||
|
|
||||||
|
ATOMIC_ENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
pReturnValue = *ppvDestination;
|
||||||
|
*ppvDestination = pvExchange;
|
||||||
|
}
|
||||||
|
ATOMIC_EXIT_CRITICAL();
|
||||||
|
|
||||||
|
return pReturnValue;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Atomic compare-and-swap (pointers)
|
||||||
|
*
|
||||||
|
* @brief Performs an atomic compare-and-swap operation on the specified pointer
|
||||||
|
* values.
|
||||||
|
*
|
||||||
|
* @param[in, out] ppvDestination Pointer to memory location from where a pointer
|
||||||
|
* value is to be loaded and checked.
|
||||||
|
* @param[in] pvExchange If condition meets, write this value to memory.
|
||||||
|
* @param[in] pvComparand Swap condition.
|
||||||
|
*
|
||||||
|
* @return Unsigned integer of value 1 or 0. 1 for swapped, 0 for not swapped.
|
||||||
|
*
|
||||||
|
* @note This function only swaps *ppvDestination with pvExchange, if previous
|
||||||
|
* *ppvDestination value equals pvComparand.
|
||||||
|
*/
|
||||||
|
static portFORCE_INLINE uint32_t Atomic_CompareAndSwapPointers_p32( void * volatile * ppvDestination,
|
||||||
|
void * pvExchange,
|
||||||
|
void * pvComparand )
|
||||||
|
{
|
||||||
|
uint32_t ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE;
|
||||||
|
|
||||||
|
ATOMIC_ENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
if( *ppvDestination == pvComparand )
|
||||||
|
{
|
||||||
|
*ppvDestination = pvExchange;
|
||||||
|
ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ATOMIC_EXIT_CRITICAL();
|
||||||
|
|
||||||
|
return ulReturnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------- Arithmetic ------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Atomic add
|
||||||
|
*
|
||||||
|
* @brief Atomically adds count to the value of the specified pointer points to.
|
||||||
|
*
|
||||||
|
* @param[in,out] pulAddend Pointer to memory location from where value is to be
|
||||||
|
* loaded and written back to.
|
||||||
|
* @param[in] ulCount Value to be added to *pulAddend.
|
||||||
|
*
|
||||||
|
* @return previous *pulAddend value.
|
||||||
|
*/
|
||||||
|
static portFORCE_INLINE uint32_t Atomic_Add_u32( uint32_t volatile * pulAddend,
|
||||||
|
uint32_t ulCount )
|
||||||
|
{
|
||||||
|
uint32_t ulCurrent;
|
||||||
|
|
||||||
|
ATOMIC_ENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
ulCurrent = *pulAddend;
|
||||||
|
*pulAddend += ulCount;
|
||||||
|
}
|
||||||
|
ATOMIC_EXIT_CRITICAL();
|
||||||
|
|
||||||
|
return ulCurrent;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Atomic subtract
|
||||||
|
*
|
||||||
|
* @brief Atomically subtracts count from the value of the specified pointer
|
||||||
|
* pointers to.
|
||||||
|
*
|
||||||
|
* @param[in,out] pulAddend Pointer to memory location from where value is to be
|
||||||
|
* loaded and written back to.
|
||||||
|
* @param[in] ulCount Value to be subtract from *pulAddend.
|
||||||
|
*
|
||||||
|
* @return previous *pulAddend value.
|
||||||
|
*/
|
||||||
|
static portFORCE_INLINE uint32_t Atomic_Subtract_u32( uint32_t volatile * pulAddend,
|
||||||
|
uint32_t ulCount )
|
||||||
|
{
|
||||||
|
uint32_t ulCurrent;
|
||||||
|
|
||||||
|
ATOMIC_ENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
ulCurrent = *pulAddend;
|
||||||
|
*pulAddend -= ulCount;
|
||||||
|
}
|
||||||
|
ATOMIC_EXIT_CRITICAL();
|
||||||
|
|
||||||
|
return ulCurrent;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Atomic increment
|
||||||
|
*
|
||||||
|
* @brief Atomically increments the value of the specified pointer points to.
|
||||||
|
*
|
||||||
|
* @param[in,out] pulAddend Pointer to memory location from where value is to be
|
||||||
|
* loaded and written back to.
|
||||||
|
*
|
||||||
|
* @return *pulAddend value before increment.
|
||||||
|
*/
|
||||||
|
static portFORCE_INLINE uint32_t Atomic_Increment_u32( uint32_t volatile * pulAddend )
|
||||||
|
{
|
||||||
|
uint32_t ulCurrent;
|
||||||
|
|
||||||
|
ATOMIC_ENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
ulCurrent = *pulAddend;
|
||||||
|
*pulAddend += 1;
|
||||||
|
}
|
||||||
|
ATOMIC_EXIT_CRITICAL();
|
||||||
|
|
||||||
|
return ulCurrent;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Atomic decrement
|
||||||
|
*
|
||||||
|
* @brief Atomically decrements the value of the specified pointer points to
|
||||||
|
*
|
||||||
|
* @param[in,out] pulAddend Pointer to memory location from where value is to be
|
||||||
|
* loaded and written back to.
|
||||||
|
*
|
||||||
|
* @return *pulAddend value before decrement.
|
||||||
|
*/
|
||||||
|
static portFORCE_INLINE uint32_t Atomic_Decrement_u32( uint32_t volatile * pulAddend )
|
||||||
|
{
|
||||||
|
uint32_t ulCurrent;
|
||||||
|
|
||||||
|
ATOMIC_ENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
ulCurrent = *pulAddend;
|
||||||
|
*pulAddend -= 1;
|
||||||
|
}
|
||||||
|
ATOMIC_EXIT_CRITICAL();
|
||||||
|
|
||||||
|
return ulCurrent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------- Bitwise Logical ------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Atomic OR
|
||||||
|
*
|
||||||
|
* @brief Performs an atomic OR operation on the specified values.
|
||||||
|
*
|
||||||
|
* @param [in, out] pulDestination Pointer to memory location from where value is
|
||||||
|
* to be loaded and written back to.
|
||||||
|
* @param [in] ulValue Value to be ORed with *pulDestination.
|
||||||
|
*
|
||||||
|
* @return The original value of *pulDestination.
|
||||||
|
*/
|
||||||
|
static portFORCE_INLINE uint32_t Atomic_OR_u32( uint32_t volatile * pulDestination,
|
||||||
|
uint32_t ulValue )
|
||||||
|
{
|
||||||
|
uint32_t ulCurrent;
|
||||||
|
|
||||||
|
ATOMIC_ENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
ulCurrent = *pulDestination;
|
||||||
|
*pulDestination |= ulValue;
|
||||||
|
}
|
||||||
|
ATOMIC_EXIT_CRITICAL();
|
||||||
|
|
||||||
|
return ulCurrent;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Atomic AND
|
||||||
|
*
|
||||||
|
* @brief Performs an atomic AND operation on the specified values.
|
||||||
|
*
|
||||||
|
* @param [in, out] pulDestination Pointer to memory location from where value is
|
||||||
|
* to be loaded and written back to.
|
||||||
|
* @param [in] ulValue Value to be ANDed with *pulDestination.
|
||||||
|
*
|
||||||
|
* @return The original value of *pulDestination.
|
||||||
|
*/
|
||||||
|
static portFORCE_INLINE uint32_t Atomic_AND_u32( uint32_t volatile * pulDestination,
|
||||||
|
uint32_t ulValue )
|
||||||
|
{
|
||||||
|
uint32_t ulCurrent;
|
||||||
|
|
||||||
|
ATOMIC_ENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
ulCurrent = *pulDestination;
|
||||||
|
*pulDestination &= ulValue;
|
||||||
|
}
|
||||||
|
ATOMIC_EXIT_CRITICAL();
|
||||||
|
|
||||||
|
return ulCurrent;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Atomic NAND
|
||||||
|
*
|
||||||
|
* @brief Performs an atomic NAND operation on the specified values.
|
||||||
|
*
|
||||||
|
* @param [in, out] pulDestination Pointer to memory location from where value is
|
||||||
|
* to be loaded and written back to.
|
||||||
|
* @param [in] ulValue Value to be NANDed with *pulDestination.
|
||||||
|
*
|
||||||
|
* @return The original value of *pulDestination.
|
||||||
|
*/
|
||||||
|
static portFORCE_INLINE uint32_t Atomic_NAND_u32( uint32_t volatile * pulDestination,
|
||||||
|
uint32_t ulValue )
|
||||||
|
{
|
||||||
|
uint32_t ulCurrent;
|
||||||
|
|
||||||
|
ATOMIC_ENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
ulCurrent = *pulDestination;
|
||||||
|
*pulDestination = ~( ulCurrent & ulValue );
|
||||||
|
}
|
||||||
|
ATOMIC_EXIT_CRITICAL();
|
||||||
|
|
||||||
|
return ulCurrent;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Atomic XOR
|
||||||
|
*
|
||||||
|
* @brief Performs an atomic XOR operation on the specified values.
|
||||||
|
*
|
||||||
|
* @param [in, out] pulDestination Pointer to memory location from where value is
|
||||||
|
* to be loaded and written back to.
|
||||||
|
* @param [in] ulValue Value to be XORed with *pulDestination.
|
||||||
|
*
|
||||||
|
* @return The original value of *pulDestination.
|
||||||
|
*/
|
||||||
|
static portFORCE_INLINE uint32_t Atomic_XOR_u32( uint32_t volatile * pulDestination,
|
||||||
|
uint32_t ulValue )
|
||||||
|
{
|
||||||
|
uint32_t ulCurrent;
|
||||||
|
|
||||||
|
ATOMIC_ENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
ulCurrent = *pulDestination;
|
||||||
|
*pulDestination ^= ulValue;
|
||||||
|
}
|
||||||
|
ATOMIC_EXIT_CRITICAL();
|
||||||
|
|
||||||
|
return ulCurrent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
#endif /* ATOMIC_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -1,93 +1,52 @@
|
||||||
/*
|
/*
|
||||||
FreeRTOS V8.2.3 - Copyright (C) 2015 Real Time Engineers Ltd.
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
All rights reserved
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
This file is part of the FreeRTOS distribution.
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
* the Software without restriction, including without limitation the rights to
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
***************************************************************************
|
*
|
||||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
* copies or substantial portions of the Software.
|
||||||
>>! obliged to provide the source code for proprietary components !<<
|
*
|
||||||
>>! outside of the FreeRTOS kernel. !<<
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
***************************************************************************
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
link: http://www.freertos.org/a00114.html
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
***************************************************************************
|
* https://github.com/FreeRTOS
|
||||||
* *
|
*
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
*/
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
|
||||||
* platform software that is more than just the market leader, it *
|
|
||||||
* is the industry's de facto standard. *
|
|
||||||
* *
|
|
||||||
* Help yourself get started quickly while simultaneously helping *
|
|
||||||
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
|
||||||
* tutorial book, reference manual, or both: *
|
|
||||||
* http://www.FreeRTOS.org/Documentation *
|
|
||||||
* *
|
|
||||||
***************************************************************************
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
|
||||||
the FAQ page "My application does not run, what could be wrong?". Have you
|
|
||||||
defined configASSERT()?
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
|
||||||
embedded software for free we request you assist our global community by
|
|
||||||
participating in the support forum.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
|
||||||
be as productive as possible as early as possible. Now you can receive
|
|
||||||
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
|
||||||
Ltd, and the world's leading authority on the world's leading RTOS.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
|
||||||
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
|
||||||
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and commercial middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef DEPRECATED_DEFINITIONS_H
|
#ifndef DEPRECATED_DEFINITIONS_H
|
||||||
#define DEPRECATED_DEFINITIONS_H
|
#define DEPRECATED_DEFINITIONS_H
|
||||||
|
|
||||||
|
|
||||||
/* Each FreeRTOS port has a unique portmacro.h header file. Originally a
|
/* Each FreeRTOS port has a unique portmacro.h header file. Originally a
|
||||||
pre-processor definition was used to ensure the pre-processor found the correct
|
* pre-processor definition was used to ensure the pre-processor found the correct
|
||||||
portmacro.h file for the port being used. That scheme was deprecated in favour
|
* portmacro.h file for the port being used. That scheme was deprecated in favour
|
||||||
of setting the compiler's include path such that it found the correct
|
* of setting the compiler's include path such that it found the correct
|
||||||
portmacro.h file - removing the need for the constant and allowing the
|
* portmacro.h file - removing the need for the constant and allowing the
|
||||||
portmacro.h file to be located anywhere in relation to the port being used. The
|
* portmacro.h file to be located anywhere in relation to the port being used. The
|
||||||
definitions below remain in the code for backward compatibility only. New
|
* definitions below remain in the code for backward compatibility only. New
|
||||||
projects should not use them. */
|
* projects should not use them. */
|
||||||
|
|
||||||
#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT
|
#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT
|
||||||
#include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h"
|
#include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h"
|
||||||
typedef void ( __interrupt __far *pxISR )();
|
typedef void ( __interrupt __far * pxISR )();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT
|
#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT
|
||||||
#include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h"
|
#include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h"
|
||||||
typedef void ( __interrupt __far *pxISR )();
|
typedef void ( __interrupt __far * pxISR )();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef GCC_MEGA_AVR
|
#ifdef GCC_MEGA_AVR
|
||||||
|
@ -251,19 +210,21 @@ projects should not use them. */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef BCC_INDUSTRIAL_PC_PORT
|
#ifdef BCC_INDUSTRIAL_PC_PORT
|
||||||
/* A short file name has to be used in place of the normal
|
|
||||||
FreeRTOSConfig.h when using the Borland compiler. */
|
/* A short file name has to be used in place of the normal
|
||||||
|
* FreeRTOSConfig.h when using the Borland compiler. */
|
||||||
#include "frconfig.h"
|
#include "frconfig.h"
|
||||||
#include "..\portable\BCC\16BitDOS\PC\prtmacro.h"
|
#include "..\portable\BCC\16BitDOS\PC\prtmacro.h"
|
||||||
typedef void ( __interrupt __far *pxISR )();
|
typedef void ( __interrupt __far * pxISR )();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef BCC_FLASH_LITE_186_PORT
|
#ifdef BCC_FLASH_LITE_186_PORT
|
||||||
/* A short file name has to be used in place of the normal
|
|
||||||
FreeRTOSConfig.h when using the Borland compiler. */
|
/* A short file name has to be used in place of the normal
|
||||||
|
* FreeRTOSConfig.h when using the Borland compiler. */
|
||||||
#include "frconfig.h"
|
#include "frconfig.h"
|
||||||
#include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h"
|
#include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h"
|
||||||
typedef void ( __interrupt __far *pxISR )();
|
typedef void ( __interrupt __far * pxISR )();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
@ -318,4 +279,3 @@ projects should not use them. */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* DEPRECATED_DEFINITIONS_H */
|
#endif /* DEPRECATED_DEFINITIONS_H */
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,71 +1,30 @@
|
||||||
/*
|
/*
|
||||||
FreeRTOS V8.2.3 - Copyright (C) 2015 Real Time Engineers Ltd.
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
All rights reserved
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
This file is part of the FreeRTOS distribution.
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
* the Software without restriction, including without limitation the rights to
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
***************************************************************************
|
*
|
||||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
* copies or substantial portions of the Software.
|
||||||
>>! obliged to provide the source code for proprietary components !<<
|
*
|
||||||
>>! outside of the FreeRTOS kernel. !<<
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
***************************************************************************
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
link: http://www.freertos.org/a00114.html
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
***************************************************************************
|
* https://github.com/FreeRTOS
|
||||||
* *
|
*
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
*/
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
|
||||||
* platform software that is more than just the market leader, it *
|
|
||||||
* is the industry's de facto standard. *
|
|
||||||
* *
|
|
||||||
* Help yourself get started quickly while simultaneously helping *
|
|
||||||
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
|
||||||
* tutorial book, reference manual, or both: *
|
|
||||||
* http://www.FreeRTOS.org/Documentation *
|
|
||||||
* *
|
|
||||||
***************************************************************************
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
|
||||||
the FAQ page "My application does not run, what could be wrong?". Have you
|
|
||||||
defined configASSERT()?
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
|
||||||
embedded software for free we request you assist our global community by
|
|
||||||
participating in the support forum.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
|
||||||
be as productive as possible as early as possible. Now you can receive
|
|
||||||
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
|
||||||
Ltd, and the world's leading authority on the world's leading RTOS.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
|
||||||
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
|
||||||
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and commercial middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is the list implementation used by the scheduler. While it is tailored
|
* This is the list implementation used by the scheduler. While it is tailored
|
||||||
|
@ -74,7 +33,7 @@
|
||||||
*
|
*
|
||||||
* list_ts can only store pointers to list_item_ts. Each ListItem_t contains a
|
* list_ts can only store pointers to list_item_ts. Each ListItem_t contains a
|
||||||
* numeric value (xItemValue). Most of the time the lists are sorted in
|
* numeric value (xItemValue). Most of the time the lists are sorted in
|
||||||
* descending item value order.
|
* ascending item value order.
|
||||||
*
|
*
|
||||||
* Lists are created already containing one list item. The value of this
|
* Lists are created already containing one list item. The value of this
|
||||||
* item is the maximum possible that can be stored, it is therefore always at
|
* item is the maximum possible that can be stored, it is therefore always at
|
||||||
|
@ -95,13 +54,14 @@
|
||||||
* \ingroup FreeRTOSIntro
|
* \ingroup FreeRTOSIntro
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef INC_FREERTOS_H
|
|
||||||
#error FreeRTOS.h must be included before list.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef LIST_H
|
#ifndef LIST_H
|
||||||
#define LIST_H
|
#define LIST_H
|
||||||
|
|
||||||
|
#ifndef INC_FREERTOS_H
|
||||||
|
#error "FreeRTOS.h must be included before list.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The list structure members are modified from within interrupts, and therefore
|
* The list structure members are modified from within interrupts, and therefore
|
||||||
* by rights should be declared volatile. However, they are only modified in a
|
* by rights should be declared volatile. However, they are only modified in a
|
||||||
|
@ -134,16 +94,18 @@
|
||||||
#define configLIST_VOLATILE
|
#define configLIST_VOLATILE
|
||||||
#endif /* configSUPPORT_CROSS_MODULE_OPTIMISATION */
|
#endif /* configSUPPORT_CROSS_MODULE_OPTIMISATION */
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
/* Macros that can be used to place known values within the list structures,
|
/* Macros that can be used to place known values within the list structures,
|
||||||
then check that the known values do not get corrupted during the execution of
|
* then check that the known values do not get corrupted during the execution of
|
||||||
the application. These may catch the list data structures being overwritten in
|
* the application. These may catch the list data structures being overwritten in
|
||||||
memory. They will not catch data errors caused by incorrect configuration or
|
* memory. They will not catch data errors caused by incorrect configuration or
|
||||||
use of FreeRTOS.*/
|
* use of FreeRTOS.*/
|
||||||
#if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 )
|
#if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 )
|
||||||
/* Define the macros to do nothing. */
|
/* Define the macros to do nothing. */
|
||||||
#define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE
|
#define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE
|
||||||
#define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE
|
#define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE
|
||||||
|
@ -155,21 +117,21 @@ use of FreeRTOS.*/
|
||||||
#define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList )
|
#define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList )
|
||||||
#define listTEST_LIST_ITEM_INTEGRITY( pxItem )
|
#define listTEST_LIST_ITEM_INTEGRITY( pxItem )
|
||||||
#define listTEST_LIST_INTEGRITY( pxList )
|
#define listTEST_LIST_INTEGRITY( pxList )
|
||||||
#else
|
#else /* if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 ) */
|
||||||
/* Define macros that add new members into the list structures. */
|
/* Define macros that add new members into the list structures. */
|
||||||
#define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue1;
|
#define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue1;
|
||||||
#define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue2;
|
#define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue2;
|
||||||
#define listFIRST_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue1;
|
#define listFIRST_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue1;
|
||||||
#define listSECOND_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue2;
|
#define listSECOND_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue2;
|
||||||
|
|
||||||
/* Define macros that set the new structure members to known values. */
|
/* Define macros that set the new structure members to known values. */
|
||||||
#define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue1 = pdINTEGRITY_CHECK_VALUE
|
#define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue1 = pdINTEGRITY_CHECK_VALUE
|
||||||
#define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue2 = pdINTEGRITY_CHECK_VALUE
|
#define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue2 = pdINTEGRITY_CHECK_VALUE
|
||||||
#define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) ( pxList )->xListIntegrityValue1 = pdINTEGRITY_CHECK_VALUE
|
#define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) ( pxList )->xListIntegrityValue1 = pdINTEGRITY_CHECK_VALUE
|
||||||
#define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) ( pxList )->xListIntegrityValue2 = pdINTEGRITY_CHECK_VALUE
|
#define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) ( pxList )->xListIntegrityValue2 = pdINTEGRITY_CHECK_VALUE
|
||||||
|
|
||||||
/* Define macros that will assert if one of the structure members does not
|
/* Define macros that will assert if one of the structure members does not
|
||||||
contain its expected value. */
|
* contain its expected value. */
|
||||||
#define listTEST_LIST_ITEM_INTEGRITY( pxItem ) configASSERT( ( ( pxItem )->xListItemIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxItem )->xListItemIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) )
|
#define listTEST_LIST_ITEM_INTEGRITY( pxItem ) configASSERT( ( ( pxItem )->xListItemIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxItem )->xListItemIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) )
|
||||||
#define listTEST_LIST_INTEGRITY( pxList ) configASSERT( ( ( pxList )->xListIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxList )->xListIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) )
|
#define listTEST_LIST_INTEGRITY( pxList ) configASSERT( ( ( pxList )->xListIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxList )->xListIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) )
|
||||||
#endif /* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES */
|
#endif /* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES */
|
||||||
|
@ -178,37 +140,42 @@ use of FreeRTOS.*/
|
||||||
/*
|
/*
|
||||||
* Definition of the only type of object that a list can contain.
|
* Definition of the only type of object that a list can contain.
|
||||||
*/
|
*/
|
||||||
|
struct xLIST;
|
||||||
struct xLIST_ITEM
|
struct xLIST_ITEM
|
||||||
{
|
{
|
||||||
listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /**< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||||
configLIST_VOLATILE TickType_t xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */
|
configLIST_VOLATILE TickType_t xItemValue; /**< The value being listed. In most cases this is used to sort the list in ascending order. */
|
||||||
struct xLIST_ITEM * configLIST_VOLATILE pxNext; /*< Pointer to the next ListItem_t in the list. */
|
struct xLIST_ITEM * configLIST_VOLATILE pxNext; /**< Pointer to the next ListItem_t in the list. */
|
||||||
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /*< Pointer to the previous ListItem_t in the list. */
|
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /**< Pointer to the previous ListItem_t in the list. */
|
||||||
void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */
|
void * pvOwner; /**< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */
|
||||||
void * configLIST_VOLATILE pvContainer; /*< Pointer to the list in which this list item is placed (if any). */
|
struct xLIST * configLIST_VOLATILE pxContainer; /**< Pointer to the list in which this list item is placed (if any). */
|
||||||
listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE /**< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||||
};
|
};
|
||||||
typedef struct xLIST_ITEM ListItem_t; /* For some reason lint wants this as two separate definitions. */
|
typedef struct xLIST_ITEM ListItem_t;
|
||||||
|
|
||||||
struct xMINI_LIST_ITEM
|
#if ( configUSE_MINI_LIST_ITEM == 1 )
|
||||||
{
|
struct xMINI_LIST_ITEM
|
||||||
listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
{
|
||||||
|
listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /**< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||||
configLIST_VOLATILE TickType_t xItemValue;
|
configLIST_VOLATILE TickType_t xItemValue;
|
||||||
struct xLIST_ITEM * configLIST_VOLATILE pxNext;
|
struct xLIST_ITEM * configLIST_VOLATILE pxNext;
|
||||||
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;
|
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;
|
||||||
};
|
};
|
||||||
typedef struct xMINI_LIST_ITEM MiniListItem_t;
|
typedef struct xMINI_LIST_ITEM MiniListItem_t;
|
||||||
|
#else
|
||||||
|
typedef struct xLIST_ITEM MiniListItem_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Definition of the type of queue used by the scheduler.
|
* Definition of the type of queue used by the scheduler.
|
||||||
*/
|
*/
|
||||||
typedef struct xLIST
|
typedef struct xLIST
|
||||||
{
|
{
|
||||||
listFIRST_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
listFIRST_LIST_INTEGRITY_CHECK_VALUE /**< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||||
configLIST_VOLATILE UBaseType_t uxNumberOfItems;
|
configLIST_VOLATILE UBaseType_t uxNumberOfItems;
|
||||||
ListItem_t * configLIST_VOLATILE pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */
|
ListItem_t * configLIST_VOLATILE pxIndex; /**< Used to walk through the list. Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */
|
||||||
MiniListItem_t xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */
|
MiniListItem_t xListEnd; /**< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */
|
||||||
listSECOND_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
listSECOND_LIST_INTEGRITY_CHECK_VALUE /**< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||||
} List_t;
|
} List_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -224,14 +191,14 @@ typedef struct xLIST
|
||||||
* Access macro to get the owner of a list item. The owner of a list item
|
* Access macro to get the owner of a list item. The owner of a list item
|
||||||
* is the object (usually a TCB) that contains the list item.
|
* is the object (usually a TCB) that contains the list item.
|
||||||
*
|
*
|
||||||
* \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
|
* \page listGET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
#define listGET_LIST_ITEM_OWNER( pxListItem ) ( ( pxListItem )->pvOwner )
|
#define listGET_LIST_ITEM_OWNER( pxListItem ) ( ( pxListItem )->pvOwner )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Access macro to set the value of the list item. In most cases the value is
|
* Access macro to set the value of the list item. In most cases the value is
|
||||||
* used to sort the list in descending order.
|
* used to sort the list in ascending order.
|
||||||
*
|
*
|
||||||
* \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE
|
* \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
|
@ -266,7 +233,7 @@ typedef struct xLIST
|
||||||
#define listGET_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext )
|
#define listGET_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return the list item at the head of the list.
|
* Return the next list item.
|
||||||
*
|
*
|
||||||
* \page listGET_NEXT listGET_NEXT
|
* \page listGET_NEXT listGET_NEXT
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
|
@ -288,7 +255,7 @@ typedef struct xLIST
|
||||||
* \page listLIST_IS_EMPTY listLIST_IS_EMPTY
|
* \page listLIST_IS_EMPTY listLIST_IS_EMPTY
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
#define listLIST_IS_EMPTY( pxList ) ( ( BaseType_t ) ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) )
|
#define listLIST_IS_EMPTY( pxList ) ( ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) ? pdTRUE : pdFALSE )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Access macro to return the number of items in the list.
|
* Access macro to return the number of items in the list.
|
||||||
|
@ -315,19 +282,107 @@ typedef struct xLIST
|
||||||
* \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY
|
* \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \
|
#if ( configNUMBER_OF_CORES == 1 )
|
||||||
{ \
|
#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \
|
||||||
List_t * const pxConstList = ( pxList ); \
|
do { \
|
||||||
|
List_t * const pxConstList = ( pxList ); \
|
||||||
/* Increment the index to the next item and return the item, ensuring */ \
|
/* Increment the index to the next item and return the item, ensuring */ \
|
||||||
/* we don't return the marker used at the end of the list. */ \
|
/* we don't return the marker used at the end of the list. */ \
|
||||||
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
|
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
|
||||||
if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \
|
if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \
|
||||||
{ \
|
{ \
|
||||||
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
|
( pxConstList )->pxIndex = ( pxConstList )->xListEnd.pxNext; \
|
||||||
} \
|
} \
|
||||||
( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \
|
( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \
|
||||||
}
|
} while( 0 )
|
||||||
|
#else /* #if ( configNUMBER_OF_CORES == 1 ) */
|
||||||
|
|
||||||
|
/* This function is not required in SMP. FreeRTOS SMP scheduler doesn't use
|
||||||
|
* pxIndex and it should always point to the xListEnd. Not defining this macro
|
||||||
|
* here to prevent updating pxIndex.
|
||||||
|
*/
|
||||||
|
#endif /* #if ( configNUMBER_OF_CORES == 1 ) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Version of uxListRemove() that does not return a value. Provided as a slight
|
||||||
|
* optimisation for xTaskIncrementTick() by being inline.
|
||||||
|
*
|
||||||
|
* Remove an item from a list. The list item has a pointer to the list that
|
||||||
|
* it is in, so only the list item need be passed into the function.
|
||||||
|
*
|
||||||
|
* @param uxListRemove The item to be removed. The item will remove itself from
|
||||||
|
* the list pointed to by it's pxContainer parameter.
|
||||||
|
*
|
||||||
|
* @return The number of items that remain in the list after the list item has
|
||||||
|
* been removed.
|
||||||
|
*
|
||||||
|
* \page listREMOVE_ITEM listREMOVE_ITEM
|
||||||
|
* \ingroup LinkedList
|
||||||
|
*/
|
||||||
|
#define listREMOVE_ITEM( pxItemToRemove ) \
|
||||||
|
do { \
|
||||||
|
/* The list item knows which list it is in. Obtain the list from the list \
|
||||||
|
* item. */ \
|
||||||
|
List_t * const pxList = ( pxItemToRemove )->pxContainer; \
|
||||||
|
\
|
||||||
|
( pxItemToRemove )->pxNext->pxPrevious = ( pxItemToRemove )->pxPrevious; \
|
||||||
|
( pxItemToRemove )->pxPrevious->pxNext = ( pxItemToRemove )->pxNext; \
|
||||||
|
/* Make sure the index is left pointing to a valid item. */ \
|
||||||
|
if( pxList->pxIndex == ( pxItemToRemove ) ) \
|
||||||
|
{ \
|
||||||
|
pxList->pxIndex = ( pxItemToRemove )->pxPrevious; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
( pxItemToRemove )->pxContainer = NULL; \
|
||||||
|
( ( pxList )->uxNumberOfItems ) = ( UBaseType_t ) ( ( ( pxList )->uxNumberOfItems ) - 1U ); \
|
||||||
|
} while( 0 )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Inline version of vListInsertEnd() to provide slight optimisation for
|
||||||
|
* xTaskIncrementTick().
|
||||||
|
*
|
||||||
|
* Insert a list item into a list. The item will be inserted in a position
|
||||||
|
* such that it will be the last item within the list returned by multiple
|
||||||
|
* calls to listGET_OWNER_OF_NEXT_ENTRY.
|
||||||
|
*
|
||||||
|
* The list member pxIndex is used to walk through a list. Calling
|
||||||
|
* listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list.
|
||||||
|
* Placing an item in a list using vListInsertEnd effectively places the item
|
||||||
|
* in the list position pointed to by pxIndex. This means that every other
|
||||||
|
* item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before
|
||||||
|
* the pxIndex parameter again points to the item being inserted.
|
||||||
|
*
|
||||||
|
* @param pxList The list into which the item is to be inserted.
|
||||||
|
*
|
||||||
|
* @param pxNewListItem The list item to be inserted into the list.
|
||||||
|
*
|
||||||
|
* \page listINSERT_END listINSERT_END
|
||||||
|
* \ingroup LinkedList
|
||||||
|
*/
|
||||||
|
#define listINSERT_END( pxList, pxNewListItem ) \
|
||||||
|
do { \
|
||||||
|
ListItem_t * const pxIndex = ( pxList )->pxIndex; \
|
||||||
|
\
|
||||||
|
/* Only effective when configASSERT() is also defined, these tests may catch \
|
||||||
|
* the list data structures being overwritten in memory. They will not catch \
|
||||||
|
* data errors caused by incorrect configuration or use of FreeRTOS. */ \
|
||||||
|
listTEST_LIST_INTEGRITY( ( pxList ) ); \
|
||||||
|
listTEST_LIST_ITEM_INTEGRITY( ( pxNewListItem ) ); \
|
||||||
|
\
|
||||||
|
/* Insert a new list item into ( pxList ), but rather than sort the list, \
|
||||||
|
* makes the new list item the last item to be removed by a call to \
|
||||||
|
* listGET_OWNER_OF_NEXT_ENTRY(). */ \
|
||||||
|
( pxNewListItem )->pxNext = pxIndex; \
|
||||||
|
( pxNewListItem )->pxPrevious = pxIndex->pxPrevious; \
|
||||||
|
\
|
||||||
|
pxIndex->pxPrevious->pxNext = ( pxNewListItem ); \
|
||||||
|
pxIndex->pxPrevious = ( pxNewListItem ); \
|
||||||
|
\
|
||||||
|
/* Remember which list the item is in. */ \
|
||||||
|
( pxNewListItem )->pxContainer = ( pxList ); \
|
||||||
|
\
|
||||||
|
( ( pxList )->uxNumberOfItems ) = ( UBaseType_t ) ( ( ( pxList )->uxNumberOfItems ) + 1U ); \
|
||||||
|
} while( 0 )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Access function to obtain the owner of the first entry in a list. Lists
|
* Access function to obtain the owner of the first entry in a list. Lists
|
||||||
|
@ -345,7 +400,7 @@ List_t * const pxConstList = ( pxList ); \
|
||||||
* \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY
|
* \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
#define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( (&( ( pxList )->xListEnd ))->pxNext->pvOwner )
|
#define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( ( &( ( pxList )->xListEnd ) )->pxNext->pvOwner )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check to see if a list item is within a list. The list item maintains a
|
* Check to see if a list item is within a list. The list item maintains a
|
||||||
|
@ -356,7 +411,7 @@ List_t * const pxConstList = ( pxList ); \
|
||||||
* @param pxListItem The list item we want to know if is in the list.
|
* @param pxListItem The list item we want to know if is in the list.
|
||||||
* @return pdTRUE if the list item is in the list, otherwise pdFALSE.
|
* @return pdTRUE if the list item is in the list, otherwise pdFALSE.
|
||||||
*/
|
*/
|
||||||
#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( BaseType_t ) ( ( pxListItem )->pvContainer == ( void * ) ( pxList ) ) )
|
#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( ( pxListItem )->pxContainer == ( pxList ) ) ? ( pdTRUE ) : ( pdFALSE ) )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return the list a list item is contained within (referenced from).
|
* Return the list a list item is contained within (referenced from).
|
||||||
|
@ -364,7 +419,7 @@ List_t * const pxConstList = ( pxList ); \
|
||||||
* @param pxListItem The list item being queried.
|
* @param pxListItem The list item being queried.
|
||||||
* @return A pointer to the List_t object that references the pxListItem
|
* @return A pointer to the List_t object that references the pxListItem
|
||||||
*/
|
*/
|
||||||
#define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pvContainer )
|
#define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pxContainer )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This provides a crude means of knowing if a list has been initialised, as
|
* This provides a crude means of knowing if a list has been initialised, as
|
||||||
|
@ -398,7 +453,7 @@ void vListInitialiseItem( ListItem_t * const pxItem ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Insert a list item into a list. The item will be inserted into the list in
|
* Insert a list item into a list. The item will be inserted into the list in
|
||||||
* a position determined by its item value (descending item value order).
|
* a position determined by its item value (ascending item value order).
|
||||||
*
|
*
|
||||||
* @param pxList The list into which the item is to be inserted.
|
* @param pxList The list into which the item is to be inserted.
|
||||||
*
|
*
|
||||||
|
@ -407,19 +462,20 @@ void vListInitialiseItem( ListItem_t * const pxItem ) PRIVILEGED_FUNCTION;
|
||||||
* \page vListInsert vListInsert
|
* \page vListInsert vListInsert
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION;
|
void vListInsert( List_t * const pxList,
|
||||||
|
ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Insert a list item into a list. The item will be inserted in a position
|
* Insert a list item into a list. The item will be inserted in a position
|
||||||
* such that it will be the last item within the list returned by multiple
|
* such that it will be the last item within the list returned by multiple
|
||||||
* calls to listGET_OWNER_OF_NEXT_ENTRY.
|
* calls to listGET_OWNER_OF_NEXT_ENTRY.
|
||||||
*
|
*
|
||||||
* The list member pvIndex is used to walk through a list. Calling
|
* The list member pxIndex is used to walk through a list. Calling
|
||||||
* listGET_OWNER_OF_NEXT_ENTRY increments pvIndex to the next item in the list.
|
* listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list.
|
||||||
* Placing an item in a list using vListInsertEnd effectively places the item
|
* Placing an item in a list using vListInsertEnd effectively places the item
|
||||||
* in the list position pointed to by pvIndex. This means that every other
|
* in the list position pointed to by pxIndex. This means that every other
|
||||||
* item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before
|
* item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before
|
||||||
* the pvIndex parameter again points to the item being inserted.
|
* the pxIndex parameter again points to the item being inserted.
|
||||||
*
|
*
|
||||||
* @param pxList The list into which the item is to be inserted.
|
* @param pxList The list into which the item is to be inserted.
|
||||||
*
|
*
|
||||||
|
@ -428,7 +484,8 @@ void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIV
|
||||||
* \page vListInsertEnd vListInsertEnd
|
* \page vListInsertEnd vListInsertEnd
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION;
|
void vListInsertEnd( List_t * const pxList,
|
||||||
|
ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remove an item from a list. The list item has a pointer to the list that
|
* Remove an item from a list. The list item has a pointer to the list that
|
||||||
|
@ -445,9 +502,10 @@ void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) P
|
||||||
*/
|
*/
|
||||||
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) PRIVILEGED_FUNCTION;
|
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
#endif /* ifndef LIST_H */
|
||||||
|
|
|
@ -0,0 +1,967 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Message buffers build functionality on top of FreeRTOS stream buffers.
|
||||||
|
* Whereas stream buffers are used to send a continuous stream of data from one
|
||||||
|
* task or interrupt to another, message buffers are used to send variable
|
||||||
|
* length discrete messages from one task or interrupt to another. Their
|
||||||
|
* implementation is light weight, making them particularly suited for interrupt
|
||||||
|
* to task and core to core communication scenarios.
|
||||||
|
*
|
||||||
|
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||||
|
* implementation (so also the message buffer implementation, as message buffers
|
||||||
|
* are built on top of stream buffers) assumes there is only one task or
|
||||||
|
* interrupt that will write to the buffer (the writer), and only one task or
|
||||||
|
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||||
|
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||||
|
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||||
|
* multiple different readers. If there are to be multiple different writers
|
||||||
|
* then the application writer must place each call to a writing API function
|
||||||
|
* (such as xMessageBufferSend()) inside a critical section and set the send
|
||||||
|
* block time to 0. Likewise, if there are to be multiple different readers
|
||||||
|
* then the application writer must place each call to a reading API function
|
||||||
|
* (such as xMessageBufferRead()) inside a critical section and set the receive
|
||||||
|
* timeout to 0.
|
||||||
|
*
|
||||||
|
* Message buffers hold variable length messages. To enable that, when a
|
||||||
|
* message is written to the message buffer an additional sizeof( size_t ) bytes
|
||||||
|
* are also written to store the message's length (that happens internally, with
|
||||||
|
* the API function). sizeof( size_t ) is typically 4 bytes on a 32-bit
|
||||||
|
* architecture, so writing a 10 byte message to a message buffer on a 32-bit
|
||||||
|
* architecture will actually reduce the available space in the message buffer
|
||||||
|
* by 14 bytes (10 byte are used by the message, and 4 bytes to hold the length
|
||||||
|
* of the message).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FREERTOS_MESSAGE_BUFFER_H
|
||||||
|
#define FREERTOS_MESSAGE_BUFFER_H
|
||||||
|
|
||||||
|
#ifndef INC_FREERTOS_H
|
||||||
|
#error "include FreeRTOS.h must appear in source files before include message_buffer.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Message buffers are built onto of stream buffers. */
|
||||||
|
#include "stream_buffer.h"
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#if defined( __cplusplus )
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type by which message buffers are referenced. For example, a call to
|
||||||
|
* xMessageBufferCreate() returns an MessageBufferHandle_t variable that can
|
||||||
|
* then be used as a parameter to xMessageBufferSend(), xMessageBufferReceive(),
|
||||||
|
* etc. Message buffer is essentially built as a stream buffer hence its handle
|
||||||
|
* is also set to same type as a stream buffer handle.
|
||||||
|
*/
|
||||||
|
typedef StreamBufferHandle_t MessageBufferHandle_t;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message_buffer.h
|
||||||
|
*
|
||||||
|
* @code{c}
|
||||||
|
* MessageBufferHandle_t xMessageBufferCreate( size_t xBufferSizeBytes );
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* Creates a new message buffer using dynamically allocated memory. See
|
||||||
|
* xMessageBufferCreateStatic() for a version that uses statically allocated
|
||||||
|
* memory (memory that is allocated at compile time).
|
||||||
|
*
|
||||||
|
* configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 or left undefined in
|
||||||
|
* FreeRTOSConfig.h for xMessageBufferCreate() to be available.
|
||||||
|
* configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
|
||||||
|
* xMessageBufferCreate() to be available.
|
||||||
|
*
|
||||||
|
* @param xBufferSizeBytes The total number of bytes (not messages) the message
|
||||||
|
* buffer will be able to hold at any one time. When a message is written to
|
||||||
|
* the message buffer an additional sizeof( size_t ) bytes are also written to
|
||||||
|
* store the message's length. sizeof( size_t ) is typically 4 bytes on a
|
||||||
|
* 32-bit architecture, so on most 32-bit architectures a 10 byte message will
|
||||||
|
* take up 14 bytes of message buffer space.
|
||||||
|
*
|
||||||
|
* @param pxSendCompletedCallback Callback invoked when a send operation to the
|
||||||
|
* message buffer is complete. If the parameter is NULL or xMessageBufferCreate()
|
||||||
|
* is called without the parameter, then it will use the default implementation
|
||||||
|
* provided by sbSEND_COMPLETED macro. To enable the callback,
|
||||||
|
* configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h.
|
||||||
|
*
|
||||||
|
* @param pxReceiveCompletedCallback Callback invoked when a receive operation from
|
||||||
|
* the message buffer is complete. If the parameter is NULL or xMessageBufferCreate()
|
||||||
|
* is called without the parameter, it will use the default implementation provided
|
||||||
|
* by sbRECEIVE_COMPLETED macro. To enable the callback,
|
||||||
|
* configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h.
|
||||||
|
*
|
||||||
|
* @return If NULL is returned, then the message buffer cannot be created
|
||||||
|
* because there is insufficient heap memory available for FreeRTOS to allocate
|
||||||
|
* the message buffer data structures and storage area. A non-NULL value being
|
||||||
|
* returned indicates that the message buffer has been created successfully -
|
||||||
|
* the returned value should be stored as the handle to the created message
|
||||||
|
* buffer.
|
||||||
|
*
|
||||||
|
* Example use:
|
||||||
|
* @code{c}
|
||||||
|
*
|
||||||
|
* void vAFunction( void )
|
||||||
|
* {
|
||||||
|
* MessageBufferHandle_t xMessageBuffer;
|
||||||
|
* const size_t xMessageBufferSizeBytes = 100;
|
||||||
|
*
|
||||||
|
* // Create a message buffer that can hold 100 bytes. The memory used to hold
|
||||||
|
* // both the message buffer structure and the messages themselves is allocated
|
||||||
|
* // dynamically. Each message added to the buffer consumes an additional 4
|
||||||
|
* // bytes which are used to hold the length of the message.
|
||||||
|
* xMessageBuffer = xMessageBufferCreate( xMessageBufferSizeBytes );
|
||||||
|
*
|
||||||
|
* if( xMessageBuffer == NULL )
|
||||||
|
* {
|
||||||
|
* // There was not enough heap memory space available to create the
|
||||||
|
* // message buffer.
|
||||||
|
* }
|
||||||
|
* else
|
||||||
|
* {
|
||||||
|
* // The message buffer was created successfully and can now be used.
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* @endcode
|
||||||
|
* \defgroup xMessageBufferCreate xMessageBufferCreate
|
||||||
|
* \ingroup MessageBufferManagement
|
||||||
|
*/
|
||||||
|
#define xMessageBufferCreate( xBufferSizeBytes ) \
|
||||||
|
xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( size_t ) 0, sbTYPE_MESSAGE_BUFFER, NULL, NULL )
|
||||||
|
|
||||||
|
#if ( configUSE_SB_COMPLETED_CALLBACK == 1 )
|
||||||
|
#define xMessageBufferCreateWithCallback( xBufferSizeBytes, pxSendCompletedCallback, pxReceiveCompletedCallback ) \
|
||||||
|
xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( size_t ) 0, sbTYPE_MESSAGE_BUFFER, ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message_buffer.h
|
||||||
|
*
|
||||||
|
* @code{c}
|
||||||
|
* MessageBufferHandle_t xMessageBufferCreateStatic( size_t xBufferSizeBytes,
|
||||||
|
* uint8_t *pucMessageBufferStorageArea,
|
||||||
|
* StaticMessageBuffer_t *pxStaticMessageBuffer );
|
||||||
|
* @endcode
|
||||||
|
* Creates a new message buffer using statically allocated memory. See
|
||||||
|
* xMessageBufferCreate() for a version that uses dynamically allocated memory.
|
||||||
|
*
|
||||||
|
* configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
|
||||||
|
* xMessageBufferCreateStatic() to be available.
|
||||||
|
*
|
||||||
|
* @param xBufferSizeBytes The size, in bytes, of the buffer pointed to by the
|
||||||
|
* pucMessageBufferStorageArea parameter. When a message is written to the
|
||||||
|
* message buffer an additional sizeof( size_t ) bytes are also written to store
|
||||||
|
* the message's length. sizeof( size_t ) is typically 4 bytes on a 32-bit
|
||||||
|
* architecture, so on most 32-bit architecture a 10 byte message will take up
|
||||||
|
* 14 bytes of message buffer space. The maximum number of bytes that can be
|
||||||
|
* stored in the message buffer is actually (xBufferSizeBytes - 1).
|
||||||
|
*
|
||||||
|
* @param pucMessageBufferStorageArea Must point to a uint8_t array that is at
|
||||||
|
* least xBufferSizeBytes big. This is the array to which messages are
|
||||||
|
* copied when they are written to the message buffer.
|
||||||
|
*
|
||||||
|
* @param pxStaticMessageBuffer Must point to a variable of type
|
||||||
|
* StaticMessageBuffer_t, which will be used to hold the message buffer's data
|
||||||
|
* structure.
|
||||||
|
*
|
||||||
|
* @param pxSendCompletedCallback Callback invoked when a new message is sent to the message buffer.
|
||||||
|
* If the parameter is NULL or xMessageBufferCreate() is called without the parameter, then it will use the default
|
||||||
|
* implementation provided by sbSEND_COMPLETED macro. To enable the callback,
|
||||||
|
* configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h.
|
||||||
|
*
|
||||||
|
* @param pxReceiveCompletedCallback Callback invoked when a message is read from a
|
||||||
|
* message buffer. If the parameter is NULL or xMessageBufferCreate() is called without the parameter, it will
|
||||||
|
* use the default implementation provided by sbRECEIVE_COMPLETED macro. To enable the callback,
|
||||||
|
* configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h.
|
||||||
|
*
|
||||||
|
* @return If the message buffer is created successfully then a handle to the
|
||||||
|
* created message buffer is returned. If either pucMessageBufferStorageArea or
|
||||||
|
* pxStaticmessageBuffer are NULL then NULL is returned.
|
||||||
|
*
|
||||||
|
* Example use:
|
||||||
|
* @code{c}
|
||||||
|
*
|
||||||
|
* // Used to dimension the array used to hold the messages. The available space
|
||||||
|
* // will actually be one less than this, so 999.
|
||||||
|
#define STORAGE_SIZE_BYTES 1000
|
||||||
|
*
|
||||||
|
* // Defines the memory that will actually hold the messages within the message
|
||||||
|
* // buffer.
|
||||||
|
* static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ];
|
||||||
|
*
|
||||||
|
* // The variable used to hold the message buffer structure.
|
||||||
|
* StaticMessageBuffer_t xMessageBufferStruct;
|
||||||
|
*
|
||||||
|
* void MyFunction( void )
|
||||||
|
* {
|
||||||
|
* MessageBufferHandle_t xMessageBuffer;
|
||||||
|
*
|
||||||
|
* xMessageBuffer = xMessageBufferCreateStatic( sizeof( ucStorageBuffer ),
|
||||||
|
* ucStorageBuffer,
|
||||||
|
* &xMessageBufferStruct );
|
||||||
|
*
|
||||||
|
* // As neither the pucMessageBufferStorageArea or pxStaticMessageBuffer
|
||||||
|
* // parameters were NULL, xMessageBuffer will not be NULL, and can be used to
|
||||||
|
* // reference the created message buffer in other message buffer API calls.
|
||||||
|
*
|
||||||
|
* // Other code that uses the message buffer can go here.
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* @endcode
|
||||||
|
* \defgroup xMessageBufferCreateStatic xMessageBufferCreateStatic
|
||||||
|
* \ingroup MessageBufferManagement
|
||||||
|
*/
|
||||||
|
#define xMessageBufferCreateStatic( xBufferSizeBytes, pucMessageBufferStorageArea, pxStaticMessageBuffer ) \
|
||||||
|
xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), 0, sbTYPE_MESSAGE_BUFFER, ( pucMessageBufferStorageArea ), ( pxStaticMessageBuffer ), NULL, NULL )
|
||||||
|
|
||||||
|
#if ( configUSE_SB_COMPLETED_CALLBACK == 1 )
|
||||||
|
#define xMessageBufferCreateStaticWithCallback( xBufferSizeBytes, pucMessageBufferStorageArea, pxStaticMessageBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback ) \
|
||||||
|
xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), 0, sbTYPE_MESSAGE_BUFFER, ( pucMessageBufferStorageArea ), ( pxStaticMessageBuffer ), ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message_buffer.h
|
||||||
|
*
|
||||||
|
* @code{c}
|
||||||
|
* BaseType_t xMessageBufferGetStaticBuffers( MessageBufferHandle_t xMessageBuffer,
|
||||||
|
* uint8_t ** ppucMessageBufferStorageArea,
|
||||||
|
* StaticMessageBuffer_t ** ppxStaticMessageBuffer );
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* Retrieve pointers to a statically created message buffer's data structure
|
||||||
|
* buffer and storage area buffer. These are the same buffers that are supplied
|
||||||
|
* at the time of creation.
|
||||||
|
*
|
||||||
|
* configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
|
||||||
|
* xMessageBufferGetStaticBuffers() to be available.
|
||||||
|
*
|
||||||
|
* @param xMessageBuffer The message buffer for which to retrieve the buffers.
|
||||||
|
*
|
||||||
|
* @param ppucMessageBufferStorageArea Used to return a pointer to the
|
||||||
|
* message buffer's storage area buffer.
|
||||||
|
*
|
||||||
|
* @param ppxStaticMessageBuffer Used to return a pointer to the message
|
||||||
|
* buffer's data structure buffer.
|
||||||
|
*
|
||||||
|
* @return pdTRUE if buffers were retrieved, pdFALSE otherwise..
|
||||||
|
*
|
||||||
|
* \defgroup xMessageBufferGetStaticBuffers xMessageBufferGetStaticBuffers
|
||||||
|
* \ingroup MessageBufferManagement
|
||||||
|
*/
|
||||||
|
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
|
#define xMessageBufferGetStaticBuffers( xMessageBuffer, ppucMessageBufferStorageArea, ppxStaticMessageBuffer ) \
|
||||||
|
xStreamBufferGetStaticBuffers( ( xMessageBuffer ), ( ppucMessageBufferStorageArea ), ( ppxStaticMessageBuffer ) )
|
||||||
|
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message_buffer.h
|
||||||
|
*
|
||||||
|
* @code{c}
|
||||||
|
* size_t xMessageBufferSend( MessageBufferHandle_t xMessageBuffer,
|
||||||
|
* const void *pvTxData,
|
||||||
|
* size_t xDataLengthBytes,
|
||||||
|
* TickType_t xTicksToWait );
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* Sends a discrete message to the message buffer. The message can be any
|
||||||
|
* length that fits within the buffer's free space, and is copied into the
|
||||||
|
* buffer.
|
||||||
|
*
|
||||||
|
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||||
|
* implementation (so also the message buffer implementation, as message buffers
|
||||||
|
* are built on top of stream buffers) assumes there is only one task or
|
||||||
|
* interrupt that will write to the buffer (the writer), and only one task or
|
||||||
|
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||||
|
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||||
|
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||||
|
* multiple different readers. If there are to be multiple different writers
|
||||||
|
* then the application writer must place each call to a writing API function
|
||||||
|
* (such as xMessageBufferSend()) inside a critical section and set the send
|
||||||
|
* block time to 0. Likewise, if there are to be multiple different readers
|
||||||
|
* then the application writer must place each call to a reading API function
|
||||||
|
* (such as xMessageBufferRead()) inside a critical section and set the receive
|
||||||
|
* block time to 0.
|
||||||
|
*
|
||||||
|
* Use xMessageBufferSend() to write to a message buffer from a task. Use
|
||||||
|
* xMessageBufferSendFromISR() to write to a message buffer from an interrupt
|
||||||
|
* service routine (ISR).
|
||||||
|
*
|
||||||
|
* configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
|
||||||
|
* xMessageBufferSend() to be available.
|
||||||
|
*
|
||||||
|
* @param xMessageBuffer The handle of the message buffer to which a message is
|
||||||
|
* being sent.
|
||||||
|
*
|
||||||
|
* @param pvTxData A pointer to the message that is to be copied into the
|
||||||
|
* message buffer.
|
||||||
|
*
|
||||||
|
* @param xDataLengthBytes The length of the message. That is, the number of
|
||||||
|
* bytes to copy from pvTxData into the message buffer. When a message is
|
||||||
|
* written to the message buffer an additional sizeof( size_t ) bytes are also
|
||||||
|
* written to store the message's length. sizeof( size_t ) is typically 4 bytes
|
||||||
|
* on a 32-bit architecture, so on most 32-bit architecture setting
|
||||||
|
* xDataLengthBytes to 20 will reduce the free space in the message buffer by 24
|
||||||
|
* bytes (20 bytes of message data and 4 bytes to hold the message length).
|
||||||
|
*
|
||||||
|
* @param xTicksToWait The maximum amount of time the calling task should remain
|
||||||
|
* in the Blocked state to wait for enough space to become available in the
|
||||||
|
* message buffer, should the message buffer have insufficient space when
|
||||||
|
* xMessageBufferSend() is called. The calling task will never block if
|
||||||
|
* xTicksToWait is zero. The block time is specified in tick periods, so the
|
||||||
|
* absolute time it represents is dependent on the tick frequency. The macro
|
||||||
|
* pdMS_TO_TICKS() can be used to convert a time specified in milliseconds into
|
||||||
|
* a time specified in ticks. Setting xTicksToWait to portMAX_DELAY will cause
|
||||||
|
* the task to wait indefinitely (without timing out), provided
|
||||||
|
* INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. Tasks do not use any
|
||||||
|
* CPU time when they are in the Blocked state.
|
||||||
|
*
|
||||||
|
* @return The number of bytes written to the message buffer. If the call to
|
||||||
|
* xMessageBufferSend() times out before there was enough space to write the
|
||||||
|
* message into the message buffer then zero is returned. If the call did not
|
||||||
|
* time out then xDataLengthBytes is returned.
|
||||||
|
*
|
||||||
|
* Example use:
|
||||||
|
* @code{c}
|
||||||
|
* void vAFunction( MessageBufferHandle_t xMessageBuffer )
|
||||||
|
* {
|
||||||
|
* size_t xBytesSent;
|
||||||
|
* uint8_t ucArrayToSend[] = { 0, 1, 2, 3 };
|
||||||
|
* char *pcStringToSend = "String to send";
|
||||||
|
* const TickType_t x100ms = pdMS_TO_TICKS( 100 );
|
||||||
|
*
|
||||||
|
* // Send an array to the message buffer, blocking for a maximum of 100ms to
|
||||||
|
* // wait for enough space to be available in the message buffer.
|
||||||
|
* xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms );
|
||||||
|
*
|
||||||
|
* if( xBytesSent != sizeof( ucArrayToSend ) )
|
||||||
|
* {
|
||||||
|
* // The call to xMessageBufferSend() times out before there was enough
|
||||||
|
* // space in the buffer for the data to be written.
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // Send the string to the message buffer. Return immediately if there is
|
||||||
|
* // not enough space in the buffer.
|
||||||
|
* xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 );
|
||||||
|
*
|
||||||
|
* if( xBytesSent != strlen( pcStringToSend ) )
|
||||||
|
* {
|
||||||
|
* // The string could not be added to the message buffer because there was
|
||||||
|
* // not enough free space in the buffer.
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
* \defgroup xMessageBufferSend xMessageBufferSend
|
||||||
|
* \ingroup MessageBufferManagement
|
||||||
|
*/
|
||||||
|
#define xMessageBufferSend( xMessageBuffer, pvTxData, xDataLengthBytes, xTicksToWait ) \
|
||||||
|
xStreamBufferSend( ( xMessageBuffer ), ( pvTxData ), ( xDataLengthBytes ), ( xTicksToWait ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message_buffer.h
|
||||||
|
*
|
||||||
|
* @code{c}
|
||||||
|
* size_t xMessageBufferSendFromISR( MessageBufferHandle_t xMessageBuffer,
|
||||||
|
* const void *pvTxData,
|
||||||
|
* size_t xDataLengthBytes,
|
||||||
|
* BaseType_t *pxHigherPriorityTaskWoken );
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* Interrupt safe version of the API function that sends a discrete message to
|
||||||
|
* the message buffer. The message can be any length that fits within the
|
||||||
|
* buffer's free space, and is copied into the buffer.
|
||||||
|
*
|
||||||
|
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||||
|
* implementation (so also the message buffer implementation, as message buffers
|
||||||
|
* are built on top of stream buffers) assumes there is only one task or
|
||||||
|
* interrupt that will write to the buffer (the writer), and only one task or
|
||||||
|
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||||
|
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||||
|
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||||
|
* multiple different readers. If there are to be multiple different writers
|
||||||
|
* then the application writer must place each call to a writing API function
|
||||||
|
* (such as xMessageBufferSend()) inside a critical section and set the send
|
||||||
|
* block time to 0. Likewise, if there are to be multiple different readers
|
||||||
|
* then the application writer must place each call to a reading API function
|
||||||
|
* (such as xMessageBufferRead()) inside a critical section and set the receive
|
||||||
|
* block time to 0.
|
||||||
|
*
|
||||||
|
* Use xMessageBufferSend() to write to a message buffer from a task. Use
|
||||||
|
* xMessageBufferSendFromISR() to write to a message buffer from an interrupt
|
||||||
|
* service routine (ISR).
|
||||||
|
*
|
||||||
|
* configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
|
||||||
|
* xMessageBufferSendFromISR() to be available.
|
||||||
|
*
|
||||||
|
* @param xMessageBuffer The handle of the message buffer to which a message is
|
||||||
|
* being sent.
|
||||||
|
*
|
||||||
|
* @param pvTxData A pointer to the message that is to be copied into the
|
||||||
|
* message buffer.
|
||||||
|
*
|
||||||
|
* @param xDataLengthBytes The length of the message. That is, the number of
|
||||||
|
* bytes to copy from pvTxData into the message buffer. When a message is
|
||||||
|
* written to the message buffer an additional sizeof( size_t ) bytes are also
|
||||||
|
* written to store the message's length. sizeof( size_t ) is typically 4 bytes
|
||||||
|
* on a 32-bit architecture, so on most 32-bit architecture setting
|
||||||
|
* xDataLengthBytes to 20 will reduce the free space in the message buffer by 24
|
||||||
|
* bytes (20 bytes of message data and 4 bytes to hold the message length).
|
||||||
|
*
|
||||||
|
* @param pxHigherPriorityTaskWoken It is possible that a message buffer will
|
||||||
|
* have a task blocked on it waiting for data. Calling
|
||||||
|
* xMessageBufferSendFromISR() can make data available, and so cause a task that
|
||||||
|
* was waiting for data to leave the Blocked state. If calling
|
||||||
|
* xMessageBufferSendFromISR() causes a task to leave the Blocked state, and the
|
||||||
|
* unblocked task has a priority higher than the currently executing task (the
|
||||||
|
* task that was interrupted), then, internally, xMessageBufferSendFromISR()
|
||||||
|
* will set *pxHigherPriorityTaskWoken to pdTRUE. If
|
||||||
|
* xMessageBufferSendFromISR() sets this value to pdTRUE, then normally a
|
||||||
|
* context switch should be performed before the interrupt is exited. This will
|
||||||
|
* ensure that the interrupt returns directly to the highest priority Ready
|
||||||
|
* state task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it
|
||||||
|
* is passed into the function. See the code example below for an example.
|
||||||
|
*
|
||||||
|
* @return The number of bytes actually written to the message buffer. If the
|
||||||
|
* message buffer didn't have enough free space for the message to be stored
|
||||||
|
* then 0 is returned, otherwise xDataLengthBytes is returned.
|
||||||
|
*
|
||||||
|
* Example use:
|
||||||
|
* @code{c}
|
||||||
|
* // A message buffer that has already been created.
|
||||||
|
* MessageBufferHandle_t xMessageBuffer;
|
||||||
|
*
|
||||||
|
* void vAnInterruptServiceRoutine( void )
|
||||||
|
* {
|
||||||
|
* size_t xBytesSent;
|
||||||
|
* char *pcStringToSend = "String to send";
|
||||||
|
* BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
|
||||||
|
*
|
||||||
|
* // Attempt to send the string to the message buffer.
|
||||||
|
* xBytesSent = xMessageBufferSendFromISR( xMessageBuffer,
|
||||||
|
* ( void * ) pcStringToSend,
|
||||||
|
* strlen( pcStringToSend ),
|
||||||
|
* &xHigherPriorityTaskWoken );
|
||||||
|
*
|
||||||
|
* if( xBytesSent != strlen( pcStringToSend ) )
|
||||||
|
* {
|
||||||
|
* // The string could not be added to the message buffer because there was
|
||||||
|
* // not enough free space in the buffer.
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // If xHigherPriorityTaskWoken was set to pdTRUE inside
|
||||||
|
* // xMessageBufferSendFromISR() then a task that has a priority above the
|
||||||
|
* // priority of the currently executing task was unblocked and a context
|
||||||
|
* // switch should be performed to ensure the ISR returns to the unblocked
|
||||||
|
* // task. In most FreeRTOS ports this is done by simply passing
|
||||||
|
* // xHigherPriorityTaskWoken into portYIELD_FROM_ISR(), which will test the
|
||||||
|
* // variables value, and perform the context switch if necessary. Check the
|
||||||
|
* // documentation for the port in use for port specific instructions.
|
||||||
|
* portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
* \defgroup xMessageBufferSendFromISR xMessageBufferSendFromISR
|
||||||
|
* \ingroup MessageBufferManagement
|
||||||
|
*/
|
||||||
|
#define xMessageBufferSendFromISR( xMessageBuffer, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken ) \
|
||||||
|
xStreamBufferSendFromISR( ( xMessageBuffer ), ( pvTxData ), ( xDataLengthBytes ), ( pxHigherPriorityTaskWoken ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message_buffer.h
|
||||||
|
*
|
||||||
|
* @code{c}
|
||||||
|
* size_t xMessageBufferReceive( MessageBufferHandle_t xMessageBuffer,
|
||||||
|
* void *pvRxData,
|
||||||
|
* size_t xBufferLengthBytes,
|
||||||
|
* TickType_t xTicksToWait );
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* Receives a discrete message from a message buffer. Messages can be of
|
||||||
|
* variable length and are copied out of the buffer.
|
||||||
|
*
|
||||||
|
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||||
|
* implementation (so also the message buffer implementation, as message buffers
|
||||||
|
* are built on top of stream buffers) assumes there is only one task or
|
||||||
|
* interrupt that will write to the buffer (the writer), and only one task or
|
||||||
|
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||||
|
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||||
|
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||||
|
* multiple different readers. If there are to be multiple different writers
|
||||||
|
* then the application writer must place each call to a writing API function
|
||||||
|
* (such as xMessageBufferSend()) inside a critical section and set the send
|
||||||
|
* block time to 0. Likewise, if there are to be multiple different readers
|
||||||
|
* then the application writer must place each call to a reading API function
|
||||||
|
* (such as xMessageBufferRead()) inside a critical section and set the receive
|
||||||
|
* block time to 0.
|
||||||
|
*
|
||||||
|
* Use xMessageBufferReceive() to read from a message buffer from a task. Use
|
||||||
|
* xMessageBufferReceiveFromISR() to read from a message buffer from an
|
||||||
|
* interrupt service routine (ISR).
|
||||||
|
*
|
||||||
|
* configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
|
||||||
|
* xMessageBufferReceive() to be available.
|
||||||
|
*
|
||||||
|
* @param xMessageBuffer The handle of the message buffer from which a message
|
||||||
|
* is being received.
|
||||||
|
*
|
||||||
|
* @param pvRxData A pointer to the buffer into which the received message is
|
||||||
|
* to be copied.
|
||||||
|
*
|
||||||
|
* @param xBufferLengthBytes The length of the buffer pointed to by the pvRxData
|
||||||
|
* parameter. This sets the maximum length of the message that can be received.
|
||||||
|
* If xBufferLengthBytes is too small to hold the next message then the message
|
||||||
|
* will be left in the message buffer and 0 will be returned.
|
||||||
|
*
|
||||||
|
* @param xTicksToWait The maximum amount of time the task should remain in the
|
||||||
|
* Blocked state to wait for a message, should the message buffer be empty.
|
||||||
|
* xMessageBufferReceive() will return immediately if xTicksToWait is zero and
|
||||||
|
* the message buffer is empty. The block time is specified in tick periods, so
|
||||||
|
* the absolute time it represents is dependent on the tick frequency. The
|
||||||
|
* macro pdMS_TO_TICKS() can be used to convert a time specified in milliseconds
|
||||||
|
* into a time specified in ticks. Setting xTicksToWait to portMAX_DELAY will
|
||||||
|
* cause the task to wait indefinitely (without timing out), provided
|
||||||
|
* INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. Tasks do not use any
|
||||||
|
* CPU time when they are in the Blocked state.
|
||||||
|
*
|
||||||
|
* @return The length, in bytes, of the message read from the message buffer, if
|
||||||
|
* any. If xMessageBufferReceive() times out before a message became available
|
||||||
|
* then zero is returned. If the length of the message is greater than
|
||||||
|
* xBufferLengthBytes then the message will be left in the message buffer and
|
||||||
|
* zero is returned.
|
||||||
|
*
|
||||||
|
* Example use:
|
||||||
|
* @code{c}
|
||||||
|
* void vAFunction( MessageBuffer_t xMessageBuffer )
|
||||||
|
* {
|
||||||
|
* uint8_t ucRxData[ 20 ];
|
||||||
|
* size_t xReceivedBytes;
|
||||||
|
* const TickType_t xBlockTime = pdMS_TO_TICKS( 20 );
|
||||||
|
*
|
||||||
|
* // Receive the next message from the message buffer. Wait in the Blocked
|
||||||
|
* // state (so not using any CPU processing time) for a maximum of 100ms for
|
||||||
|
* // a message to become available.
|
||||||
|
* xReceivedBytes = xMessageBufferReceive( xMessageBuffer,
|
||||||
|
* ( void * ) ucRxData,
|
||||||
|
* sizeof( ucRxData ),
|
||||||
|
* xBlockTime );
|
||||||
|
*
|
||||||
|
* if( xReceivedBytes > 0 )
|
||||||
|
* {
|
||||||
|
* // A ucRxData contains a message that is xReceivedBytes long. Process
|
||||||
|
* // the message here....
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
* \defgroup xMessageBufferReceive xMessageBufferReceive
|
||||||
|
* \ingroup MessageBufferManagement
|
||||||
|
*/
|
||||||
|
#define xMessageBufferReceive( xMessageBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ) \
|
||||||
|
xStreamBufferReceive( ( xMessageBuffer ), ( pvRxData ), ( xBufferLengthBytes ), ( xTicksToWait ) )
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message_buffer.h
|
||||||
|
*
|
||||||
|
* @code{c}
|
||||||
|
* size_t xMessageBufferReceiveFromISR( MessageBufferHandle_t xMessageBuffer,
|
||||||
|
* void *pvRxData,
|
||||||
|
* size_t xBufferLengthBytes,
|
||||||
|
* BaseType_t *pxHigherPriorityTaskWoken );
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* An interrupt safe version of the API function that receives a discrete
|
||||||
|
* message from a message buffer. Messages can be of variable length and are
|
||||||
|
* copied out of the buffer.
|
||||||
|
*
|
||||||
|
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||||
|
* implementation (so also the message buffer implementation, as message buffers
|
||||||
|
* are built on top of stream buffers) assumes there is only one task or
|
||||||
|
* interrupt that will write to the buffer (the writer), and only one task or
|
||||||
|
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||||
|
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||||
|
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||||
|
* multiple different readers. If there are to be multiple different writers
|
||||||
|
* then the application writer must place each call to a writing API function
|
||||||
|
* (such as xMessageBufferSend()) inside a critical section and set the send
|
||||||
|
* block time to 0. Likewise, if there are to be multiple different readers
|
||||||
|
* then the application writer must place each call to a reading API function
|
||||||
|
* (such as xMessageBufferRead()) inside a critical section and set the receive
|
||||||
|
* block time to 0.
|
||||||
|
*
|
||||||
|
* Use xMessageBufferReceive() to read from a message buffer from a task. Use
|
||||||
|
* xMessageBufferReceiveFromISR() to read from a message buffer from an
|
||||||
|
* interrupt service routine (ISR).
|
||||||
|
*
|
||||||
|
* configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
|
||||||
|
* xMessageBufferReceiveFromISR() to be available.
|
||||||
|
*
|
||||||
|
* @param xMessageBuffer The handle of the message buffer from which a message
|
||||||
|
* is being received.
|
||||||
|
*
|
||||||
|
* @param pvRxData A pointer to the buffer into which the received message is
|
||||||
|
* to be copied.
|
||||||
|
*
|
||||||
|
* @param xBufferLengthBytes The length of the buffer pointed to by the pvRxData
|
||||||
|
* parameter. This sets the maximum length of the message that can be received.
|
||||||
|
* If xBufferLengthBytes is too small to hold the next message then the message
|
||||||
|
* will be left in the message buffer and 0 will be returned.
|
||||||
|
*
|
||||||
|
* @param pxHigherPriorityTaskWoken It is possible that a message buffer will
|
||||||
|
* have a task blocked on it waiting for space to become available. Calling
|
||||||
|
* xMessageBufferReceiveFromISR() can make space available, and so cause a task
|
||||||
|
* that is waiting for space to leave the Blocked state. If calling
|
||||||
|
* xMessageBufferReceiveFromISR() causes a task to leave the Blocked state, and
|
||||||
|
* the unblocked task has a priority higher than the currently executing task
|
||||||
|
* (the task that was interrupted), then, internally,
|
||||||
|
* xMessageBufferReceiveFromISR() will set *pxHigherPriorityTaskWoken to pdTRUE.
|
||||||
|
* If xMessageBufferReceiveFromISR() sets this value to pdTRUE, then normally a
|
||||||
|
* context switch should be performed before the interrupt is exited. That will
|
||||||
|
* ensure the interrupt returns directly to the highest priority Ready state
|
||||||
|
* task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it is
|
||||||
|
* passed into the function. See the code example below for an example.
|
||||||
|
*
|
||||||
|
* @return The length, in bytes, of the message read from the message buffer, if
|
||||||
|
* any.
|
||||||
|
*
|
||||||
|
* Example use:
|
||||||
|
* @code{c}
|
||||||
|
* // A message buffer that has already been created.
|
||||||
|
* MessageBuffer_t xMessageBuffer;
|
||||||
|
*
|
||||||
|
* void vAnInterruptServiceRoutine( void )
|
||||||
|
* {
|
||||||
|
* uint8_t ucRxData[ 20 ];
|
||||||
|
* size_t xReceivedBytes;
|
||||||
|
* BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
|
||||||
|
*
|
||||||
|
* // Receive the next message from the message buffer.
|
||||||
|
* xReceivedBytes = xMessageBufferReceiveFromISR( xMessageBuffer,
|
||||||
|
* ( void * ) ucRxData,
|
||||||
|
* sizeof( ucRxData ),
|
||||||
|
* &xHigherPriorityTaskWoken );
|
||||||
|
*
|
||||||
|
* if( xReceivedBytes > 0 )
|
||||||
|
* {
|
||||||
|
* // A ucRxData contains a message that is xReceivedBytes long. Process
|
||||||
|
* // the message here....
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // If xHigherPriorityTaskWoken was set to pdTRUE inside
|
||||||
|
* // xMessageBufferReceiveFromISR() then a task that has a priority above the
|
||||||
|
* // priority of the currently executing task was unblocked and a context
|
||||||
|
* // switch should be performed to ensure the ISR returns to the unblocked
|
||||||
|
* // task. In most FreeRTOS ports this is done by simply passing
|
||||||
|
* // xHigherPriorityTaskWoken into portYIELD_FROM_ISR(), which will test the
|
||||||
|
* // variables value, and perform the context switch if necessary. Check the
|
||||||
|
* // documentation for the port in use for port specific instructions.
|
||||||
|
* portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
* \defgroup xMessageBufferReceiveFromISR xMessageBufferReceiveFromISR
|
||||||
|
* \ingroup MessageBufferManagement
|
||||||
|
*/
|
||||||
|
#define xMessageBufferReceiveFromISR( xMessageBuffer, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken ) \
|
||||||
|
xStreamBufferReceiveFromISR( ( xMessageBuffer ), ( pvRxData ), ( xBufferLengthBytes ), ( pxHigherPriorityTaskWoken ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message_buffer.h
|
||||||
|
*
|
||||||
|
* @code{c}
|
||||||
|
* void vMessageBufferDelete( MessageBufferHandle_t xMessageBuffer );
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* Deletes a message buffer that was previously created using a call to
|
||||||
|
* xMessageBufferCreate() or xMessageBufferCreateStatic(). If the message
|
||||||
|
* buffer was created using dynamic memory (that is, by xMessageBufferCreate()),
|
||||||
|
* then the allocated memory is freed.
|
||||||
|
*
|
||||||
|
* A message buffer handle must not be used after the message buffer has been
|
||||||
|
* deleted.
|
||||||
|
*
|
||||||
|
* configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
|
||||||
|
* vMessageBufferDelete() to be available.
|
||||||
|
*
|
||||||
|
* @param xMessageBuffer The handle of the message buffer to be deleted.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define vMessageBufferDelete( xMessageBuffer ) \
|
||||||
|
vStreamBufferDelete( xMessageBuffer )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message_buffer.h
|
||||||
|
* @code{c}
|
||||||
|
* BaseType_t xMessageBufferIsFull( MessageBufferHandle_t xMessageBuffer );
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* Tests to see if a message buffer is full. A message buffer is full if it
|
||||||
|
* cannot accept any more messages, of any size, until space is made available
|
||||||
|
* by a message being removed from the message buffer.
|
||||||
|
*
|
||||||
|
* configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
|
||||||
|
* xMessageBufferIsFull() to be available.
|
||||||
|
*
|
||||||
|
* @param xMessageBuffer The handle of the message buffer being queried.
|
||||||
|
*
|
||||||
|
* @return If the message buffer referenced by xMessageBuffer is full then
|
||||||
|
* pdTRUE is returned. Otherwise pdFALSE is returned.
|
||||||
|
*/
|
||||||
|
#define xMessageBufferIsFull( xMessageBuffer ) \
|
||||||
|
xStreamBufferIsFull( xMessageBuffer )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message_buffer.h
|
||||||
|
* @code{c}
|
||||||
|
* BaseType_t xMessageBufferIsEmpty( MessageBufferHandle_t xMessageBuffer );
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* Tests to see if a message buffer is empty (does not contain any messages).
|
||||||
|
*
|
||||||
|
* configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
|
||||||
|
* xMessageBufferIsEmpty() to be available.
|
||||||
|
*
|
||||||
|
* @param xMessageBuffer The handle of the message buffer being queried.
|
||||||
|
*
|
||||||
|
* @return If the message buffer referenced by xMessageBuffer is empty then
|
||||||
|
* pdTRUE is returned. Otherwise pdFALSE is returned.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define xMessageBufferIsEmpty( xMessageBuffer ) \
|
||||||
|
xStreamBufferIsEmpty( xMessageBuffer )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message_buffer.h
|
||||||
|
* @code{c}
|
||||||
|
* BaseType_t xMessageBufferReset( MessageBufferHandle_t xMessageBuffer );
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* Resets a message buffer to its initial empty state, discarding any message it
|
||||||
|
* contained.
|
||||||
|
*
|
||||||
|
* A message buffer can only be reset if there are no tasks blocked on it.
|
||||||
|
*
|
||||||
|
* Use xMessageBufferReset() to reset a message buffer from a task.
|
||||||
|
* Use xMessageBufferResetFromISR() to reset a message buffer from an
|
||||||
|
* interrupt service routine (ISR).
|
||||||
|
*
|
||||||
|
* configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
|
||||||
|
* xMessageBufferReset() to be available.
|
||||||
|
*
|
||||||
|
* @param xMessageBuffer The handle of the message buffer being reset.
|
||||||
|
*
|
||||||
|
* @return If the message buffer was reset then pdPASS is returned. If the
|
||||||
|
* message buffer could not be reset because either there was a task blocked on
|
||||||
|
* the message queue to wait for space to become available, or to wait for a
|
||||||
|
* a message to be available, then pdFAIL is returned.
|
||||||
|
*
|
||||||
|
* \defgroup xMessageBufferReset xMessageBufferReset
|
||||||
|
* \ingroup MessageBufferManagement
|
||||||
|
*/
|
||||||
|
#define xMessageBufferReset( xMessageBuffer ) \
|
||||||
|
xStreamBufferReset( xMessageBuffer )
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message_buffer.h
|
||||||
|
* @code{c}
|
||||||
|
* BaseType_t xMessageBufferResetFromISR( MessageBufferHandle_t xMessageBuffer );
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* An interrupt safe version of the API function that resets the message buffer.
|
||||||
|
* Resets a message buffer to its initial empty state, discarding any message it
|
||||||
|
* contained.
|
||||||
|
*
|
||||||
|
* A message buffer can only be reset if there are no tasks blocked on it.
|
||||||
|
*
|
||||||
|
* Use xMessageBufferReset() to reset a message buffer from a task.
|
||||||
|
* Use xMessageBufferResetFromISR() to reset a message buffer from an
|
||||||
|
* interrupt service routine (ISR).
|
||||||
|
*
|
||||||
|
* configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
|
||||||
|
* xMessageBufferResetFromISR() to be available.
|
||||||
|
*
|
||||||
|
* @param xMessageBuffer The handle of the message buffer being reset.
|
||||||
|
*
|
||||||
|
* @return If the message buffer was reset then pdPASS is returned. If the
|
||||||
|
* message buffer could not be reset because either there was a task blocked on
|
||||||
|
* the message queue to wait for space to become available, or to wait for a
|
||||||
|
* a message to be available, then pdFAIL is returned.
|
||||||
|
*
|
||||||
|
* \defgroup xMessageBufferResetFromISR xMessageBufferResetFromISR
|
||||||
|
* \ingroup MessageBufferManagement
|
||||||
|
*/
|
||||||
|
#define xMessageBufferResetFromISR( xMessageBuffer ) \
|
||||||
|
xStreamBufferResetFromISR( xMessageBuffer )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message_buffer.h
|
||||||
|
* @code{c}
|
||||||
|
* size_t xMessageBufferSpaceAvailable( MessageBufferHandle_t xMessageBuffer );
|
||||||
|
* @endcode
|
||||||
|
* Returns the number of bytes of free space in the message buffer.
|
||||||
|
*
|
||||||
|
* configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
|
||||||
|
* xMessageBufferSpaceAvailable() to be available.
|
||||||
|
*
|
||||||
|
* @param xMessageBuffer The handle of the message buffer being queried.
|
||||||
|
*
|
||||||
|
* @return The number of bytes that can be written to the message buffer before
|
||||||
|
* the message buffer would be full. When a message is written to the message
|
||||||
|
* buffer an additional sizeof( size_t ) bytes are also written to store the
|
||||||
|
* message's length. sizeof( size_t ) is typically 4 bytes on a 32-bit
|
||||||
|
* architecture, so if xMessageBufferSpacesAvailable() returns 10, then the size
|
||||||
|
* of the largest message that can be written to the message buffer is 6 bytes.
|
||||||
|
*
|
||||||
|
* \defgroup xMessageBufferSpaceAvailable xMessageBufferSpaceAvailable
|
||||||
|
* \ingroup MessageBufferManagement
|
||||||
|
*/
|
||||||
|
#define xMessageBufferSpaceAvailable( xMessageBuffer ) \
|
||||||
|
xStreamBufferSpacesAvailable( xMessageBuffer )
|
||||||
|
#define xMessageBufferSpacesAvailable( xMessageBuffer ) \
|
||||||
|
xStreamBufferSpacesAvailable( xMessageBuffer ) /* Corrects typo in original macro name. */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message_buffer.h
|
||||||
|
* @code{c}
|
||||||
|
* size_t xMessageBufferNextLengthBytes( MessageBufferHandle_t xMessageBuffer );
|
||||||
|
* @endcode
|
||||||
|
* Returns the length (in bytes) of the next message in a message buffer.
|
||||||
|
* Useful if xMessageBufferReceive() returned 0 because the size of the buffer
|
||||||
|
* passed into xMessageBufferReceive() was too small to hold the next message.
|
||||||
|
*
|
||||||
|
* configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
|
||||||
|
* xMessageBufferNextLengthBytes() to be available.
|
||||||
|
*
|
||||||
|
* @param xMessageBuffer The handle of the message buffer being queried.
|
||||||
|
*
|
||||||
|
* @return The length (in bytes) of the next message in the message buffer, or 0
|
||||||
|
* if the message buffer is empty.
|
||||||
|
*
|
||||||
|
* \defgroup xMessageBufferNextLengthBytes xMessageBufferNextLengthBytes
|
||||||
|
* \ingroup MessageBufferManagement
|
||||||
|
*/
|
||||||
|
#define xMessageBufferNextLengthBytes( xMessageBuffer ) \
|
||||||
|
xStreamBufferNextMessageLengthBytes( xMessageBuffer )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message_buffer.h
|
||||||
|
*
|
||||||
|
* @code{c}
|
||||||
|
* BaseType_t xMessageBufferSendCompletedFromISR( MessageBufferHandle_t xMessageBuffer, BaseType_t *pxHigherPriorityTaskWoken );
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* For advanced users only.
|
||||||
|
*
|
||||||
|
* The sbSEND_COMPLETED() macro is called from within the FreeRTOS APIs when
|
||||||
|
* data is sent to a message buffer or stream buffer. If there was a task that
|
||||||
|
* was blocked on the message or stream buffer waiting for data to arrive then
|
||||||
|
* the sbSEND_COMPLETED() macro sends a notification to the task to remove it
|
||||||
|
* from the Blocked state. xMessageBufferSendCompletedFromISR() does the same
|
||||||
|
* thing. It is provided to enable application writers to implement their own
|
||||||
|
* version of sbSEND_COMPLETED(), and MUST NOT BE USED AT ANY OTHER TIME.
|
||||||
|
*
|
||||||
|
* See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for
|
||||||
|
* additional information.
|
||||||
|
*
|
||||||
|
* configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
|
||||||
|
* xMessageBufferSendCompletedFromISR() to be available.
|
||||||
|
*
|
||||||
|
* @param xMessageBuffer The handle of the stream buffer to which data was
|
||||||
|
* written.
|
||||||
|
*
|
||||||
|
* @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be
|
||||||
|
* initialised to pdFALSE before it is passed into
|
||||||
|
* xMessageBufferSendCompletedFromISR(). If calling
|
||||||
|
* xMessageBufferSendCompletedFromISR() removes a task from the Blocked state,
|
||||||
|
* and the task has a priority above the priority of the currently running task,
|
||||||
|
* then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a
|
||||||
|
* context switch should be performed before exiting the ISR.
|
||||||
|
*
|
||||||
|
* @return If a task was removed from the Blocked state then pdTRUE is returned.
|
||||||
|
* Otherwise pdFALSE is returned.
|
||||||
|
*
|
||||||
|
* \defgroup xMessageBufferSendCompletedFromISR xMessageBufferSendCompletedFromISR
|
||||||
|
* \ingroup StreamBufferManagement
|
||||||
|
*/
|
||||||
|
#define xMessageBufferSendCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) \
|
||||||
|
xStreamBufferSendCompletedFromISR( ( xMessageBuffer ), ( pxHigherPriorityTaskWoken ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message_buffer.h
|
||||||
|
*
|
||||||
|
* @code{c}
|
||||||
|
* BaseType_t xMessageBufferReceiveCompletedFromISR( MessageBufferHandle_t xMessageBuffer, BaseType_t *pxHigherPriorityTaskWoken );
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* For advanced users only.
|
||||||
|
*
|
||||||
|
* The sbRECEIVE_COMPLETED() macro is called from within the FreeRTOS APIs when
|
||||||
|
* data is read out of a message buffer or stream buffer. If there was a task
|
||||||
|
* that was blocked on the message or stream buffer waiting for data to arrive
|
||||||
|
* then the sbRECEIVE_COMPLETED() macro sends a notification to the task to
|
||||||
|
* remove it from the Blocked state. xMessageBufferReceiveCompletedFromISR()
|
||||||
|
* does the same thing. It is provided to enable application writers to
|
||||||
|
* implement their own version of sbRECEIVE_COMPLETED(), and MUST NOT BE USED AT
|
||||||
|
* ANY OTHER TIME.
|
||||||
|
*
|
||||||
|
* See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for
|
||||||
|
* additional information.
|
||||||
|
*
|
||||||
|
* configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
|
||||||
|
* xMessageBufferReceiveCompletedFromISR() to be available.
|
||||||
|
*
|
||||||
|
* @param xMessageBuffer The handle of the stream buffer from which data was
|
||||||
|
* read.
|
||||||
|
*
|
||||||
|
* @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be
|
||||||
|
* initialised to pdFALSE before it is passed into
|
||||||
|
* xMessageBufferReceiveCompletedFromISR(). If calling
|
||||||
|
* xMessageBufferReceiveCompletedFromISR() removes a task from the Blocked state,
|
||||||
|
* and the task has a priority above the priority of the currently running task,
|
||||||
|
* then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a
|
||||||
|
* context switch should be performed before exiting the ISR.
|
||||||
|
*
|
||||||
|
* @return If a task was removed from the Blocked state then pdTRUE is returned.
|
||||||
|
* Otherwise pdFALSE is returned.
|
||||||
|
*
|
||||||
|
* \defgroup xMessageBufferReceiveCompletedFromISR xMessageBufferReceiveCompletedFromISR
|
||||||
|
* \ingroup StreamBufferManagement
|
||||||
|
*/
|
||||||
|
#define xMessageBufferReceiveCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) \
|
||||||
|
xStreamBufferReceiveCompletedFromISR( ( xMessageBuffer ), ( pxHigherPriorityTaskWoken ) )
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#if defined( __cplusplus )
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
#endif /* !defined( FREERTOS_MESSAGE_BUFFER_H ) */
|
|
@ -0,0 +1,389 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When the MPU is used the standard (non MPU) API functions are mapped to
|
||||||
|
* equivalents that start "MPU_", the prototypes for which are defined in this
|
||||||
|
* header files. This will cause the application code to call the MPU_ version
|
||||||
|
* which wraps the non-MPU version with privilege promoting then demoting code,
|
||||||
|
* so the kernel code always runs will full privileges.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef MPU_PROTOTYPES_H
|
||||||
|
#define MPU_PROTOTYPES_H
|
||||||
|
|
||||||
|
typedef struct xTaskGenericNotifyParams
|
||||||
|
{
|
||||||
|
TaskHandle_t xTaskToNotify;
|
||||||
|
UBaseType_t uxIndexToNotify;
|
||||||
|
uint32_t ulValue;
|
||||||
|
eNotifyAction eAction;
|
||||||
|
uint32_t * pulPreviousNotificationValue;
|
||||||
|
} xTaskGenericNotifyParams_t;
|
||||||
|
|
||||||
|
typedef struct xTaskGenericNotifyWaitParams
|
||||||
|
{
|
||||||
|
UBaseType_t uxIndexToWaitOn;
|
||||||
|
uint32_t ulBitsToClearOnEntry;
|
||||||
|
uint32_t ulBitsToClearOnExit;
|
||||||
|
uint32_t * pulNotificationValue;
|
||||||
|
TickType_t xTicksToWait;
|
||||||
|
} xTaskGenericNotifyWaitParams_t;
|
||||||
|
|
||||||
|
typedef struct xTimerGenericCommandFromTaskParams
|
||||||
|
{
|
||||||
|
TimerHandle_t xTimer;
|
||||||
|
BaseType_t xCommandID;
|
||||||
|
TickType_t xOptionalValue;
|
||||||
|
BaseType_t * pxHigherPriorityTaskWoken;
|
||||||
|
TickType_t xTicksToWait;
|
||||||
|
} xTimerGenericCommandFromTaskParams_t;
|
||||||
|
|
||||||
|
typedef struct xEventGroupWaitBitsParams
|
||||||
|
{
|
||||||
|
EventGroupHandle_t xEventGroup;
|
||||||
|
EventBits_t uxBitsToWaitFor;
|
||||||
|
BaseType_t xClearOnExit;
|
||||||
|
BaseType_t xWaitForAllBits;
|
||||||
|
TickType_t xTicksToWait;
|
||||||
|
} xEventGroupWaitBitsParams_t;
|
||||||
|
|
||||||
|
/* MPU versions of task.h API functions. */
|
||||||
|
void MPU_vTaskDelay( const TickType_t xTicksToDelay ) FREERTOS_SYSTEM_CALL;
|
||||||
|
BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime,
|
||||||
|
const TickType_t xTimeIncrement ) FREERTOS_SYSTEM_CALL;
|
||||||
|
BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
||||||
|
UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
||||||
|
eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
||||||
|
void MPU_vTaskGetInfo( TaskHandle_t xTask,
|
||||||
|
TaskStatus_t * pxTaskStatus,
|
||||||
|
BaseType_t xGetFreeStackSpace,
|
||||||
|
eTaskState eState ) FREERTOS_SYSTEM_CALL;
|
||||||
|
void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) FREERTOS_SYSTEM_CALL;
|
||||||
|
void MPU_vTaskResume( TaskHandle_t xTaskToResume ) FREERTOS_SYSTEM_CALL;
|
||||||
|
TickType_t MPU_xTaskGetTickCount( void ) FREERTOS_SYSTEM_CALL;
|
||||||
|
UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) FREERTOS_SYSTEM_CALL;
|
||||||
|
UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
||||||
|
configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
||||||
|
void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask,
|
||||||
|
TaskHookFunction_t pxHookFunction ) FREERTOS_SYSTEM_CALL;
|
||||||
|
TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
||||||
|
void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet,
|
||||||
|
BaseType_t xIndex,
|
||||||
|
void * pvValue ) FREERTOS_SYSTEM_CALL;
|
||||||
|
void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery,
|
||||||
|
BaseType_t xIndex ) FREERTOS_SYSTEM_CALL;
|
||||||
|
TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) FREERTOS_SYSTEM_CALL;
|
||||||
|
UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray,
|
||||||
|
const UBaseType_t uxArraySize,
|
||||||
|
configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) FREERTOS_SYSTEM_CALL;
|
||||||
|
configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
||||||
|
configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
||||||
|
configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) FREERTOS_SYSTEM_CALL;
|
||||||
|
configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) FREERTOS_SYSTEM_CALL;
|
||||||
|
BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify,
|
||||||
|
UBaseType_t uxIndexToNotify,
|
||||||
|
uint32_t ulValue,
|
||||||
|
eNotifyAction eAction,
|
||||||
|
uint32_t * pulPreviousNotificationValue ) FREERTOS_SYSTEM_CALL;
|
||||||
|
BaseType_t MPU_xTaskGenericNotifyEntry( const xTaskGenericNotifyParams_t * pxParams ) FREERTOS_SYSTEM_CALL;
|
||||||
|
BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn,
|
||||||
|
uint32_t ulBitsToClearOnEntry,
|
||||||
|
uint32_t ulBitsToClearOnExit,
|
||||||
|
uint32_t * pulNotificationValue,
|
||||||
|
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||||
|
BaseType_t MPU_xTaskGenericNotifyWaitEntry( const xTaskGenericNotifyWaitParams_t * pxParams ) FREERTOS_SYSTEM_CALL;
|
||||||
|
uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn,
|
||||||
|
BaseType_t xClearCountOnExit,
|
||||||
|
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||||
|
BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask,
|
||||||
|
UBaseType_t uxIndexToClear ) FREERTOS_SYSTEM_CALL;
|
||||||
|
uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask,
|
||||||
|
UBaseType_t uxIndexToClear,
|
||||||
|
uint32_t ulBitsToClear ) FREERTOS_SYSTEM_CALL;
|
||||||
|
void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) FREERTOS_SYSTEM_CALL;
|
||||||
|
BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut,
|
||||||
|
TickType_t * const pxTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||||
|
TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) FREERTOS_SYSTEM_CALL;
|
||||||
|
BaseType_t MPU_xTaskGetSchedulerState( void ) FREERTOS_SYSTEM_CALL;
|
||||||
|
|
||||||
|
/* Privileged only wrappers for Task APIs. These are needed so that
|
||||||
|
* the application can use opaque handles maintained in mpu_wrappers.c
|
||||||
|
* with all the APIs. */
|
||||||
|
BaseType_t MPU_xTaskCreate( TaskFunction_t pxTaskCode,
|
||||||
|
const char * const pcName,
|
||||||
|
const configSTACK_DEPTH_TYPE uxStackDepth,
|
||||||
|
void * const pvParameters,
|
||||||
|
UBaseType_t uxPriority,
|
||||||
|
TaskHandle_t * const pxCreatedTask ) PRIVILEGED_FUNCTION;
|
||||||
|
TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode,
|
||||||
|
const char * const pcName,
|
||||||
|
const configSTACK_DEPTH_TYPE uxStackDepth,
|
||||||
|
void * const pvParameters,
|
||||||
|
UBaseType_t uxPriority,
|
||||||
|
StackType_t * const puxStackBuffer,
|
||||||
|
StaticTask_t * const pxTaskBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
void MPU_vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION;
|
||||||
|
void MPU_vTaskPrioritySet( TaskHandle_t xTask,
|
||||||
|
UBaseType_t uxNewPriority ) PRIVILEGED_FUNCTION;
|
||||||
|
TaskHandle_t MPU_xTaskGetHandle( const char * pcNameToQuery ) PRIVILEGED_FUNCTION;
|
||||||
|
BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask,
|
||||||
|
void * pvParameter ) PRIVILEGED_FUNCTION;
|
||||||
|
char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION;
|
||||||
|
BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition,
|
||||||
|
TaskHandle_t * pxCreatedTask ) PRIVILEGED_FUNCTION;
|
||||||
|
BaseType_t MPU_xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition,
|
||||||
|
TaskHandle_t * pxCreatedTask ) PRIVILEGED_FUNCTION;
|
||||||
|
void MPU_vTaskAllocateMPURegions( TaskHandle_t xTaskToModify,
|
||||||
|
const MemoryRegion_t * const xRegions ) PRIVILEGED_FUNCTION;
|
||||||
|
BaseType_t MPU_xTaskGetStaticBuffers( TaskHandle_t xTask,
|
||||||
|
StackType_t ** ppuxStackBuffer,
|
||||||
|
StaticTask_t ** ppxTaskBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
UBaseType_t MPU_uxTaskPriorityGetFromISR( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
||||||
|
UBaseType_t MPU_uxTaskBasePriorityGet( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
||||||
|
UBaseType_t MPU_uxTaskBasePriorityGetFromISR( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
||||||
|
BaseType_t MPU_xTaskResumeFromISR( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION;
|
||||||
|
TaskHookFunction_t MPU_xTaskGetApplicationTaskTagFromISR( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
||||||
|
BaseType_t MPU_xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify,
|
||||||
|
UBaseType_t uxIndexToNotify,
|
||||||
|
uint32_t ulValue,
|
||||||
|
eNotifyAction eAction,
|
||||||
|
uint32_t * pulPreviousNotificationValue,
|
||||||
|
BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||||
|
void MPU_vTaskGenericNotifyGiveFromISR( TaskHandle_t xTaskToNotify,
|
||||||
|
UBaseType_t uxIndexToNotify,
|
||||||
|
BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/* MPU versions of queue.h API functions. */
|
||||||
|
BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue,
|
||||||
|
const void * const pvItemToQueue,
|
||||||
|
TickType_t xTicksToWait,
|
||||||
|
const BaseType_t xCopyPosition ) FREERTOS_SYSTEM_CALL;
|
||||||
|
BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue,
|
||||||
|
void * const pvBuffer,
|
||||||
|
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||||
|
BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue,
|
||||||
|
void * const pvBuffer,
|
||||||
|
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||||
|
BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue,
|
||||||
|
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||||
|
UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
||||||
|
UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
||||||
|
TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) FREERTOS_SYSTEM_CALL;
|
||||||
|
BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex,
|
||||||
|
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||||
|
BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) FREERTOS_SYSTEM_CALL;
|
||||||
|
void MPU_vQueueAddToRegistry( QueueHandle_t xQueue,
|
||||||
|
const char * pcName ) FREERTOS_SYSTEM_CALL;
|
||||||
|
void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
||||||
|
const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
||||||
|
BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore,
|
||||||
|
QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL;
|
||||||
|
QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet,
|
||||||
|
const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||||
|
void MPU_vQueueSetQueueNumber( QueueHandle_t xQueue,
|
||||||
|
UBaseType_t uxQueueNumber ) FREERTOS_SYSTEM_CALL;
|
||||||
|
UBaseType_t MPU_uxQueueGetQueueNumber( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
||||||
|
uint8_t MPU_ucQueueGetQueueType( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
||||||
|
|
||||||
|
/* Privileged only wrappers for Queue APIs. These are needed so that
|
||||||
|
* the application can use opaque handles maintained in mpu_wrappers.c
|
||||||
|
* with all the APIs. */
|
||||||
|
void MPU_vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;
|
||||||
|
QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) PRIVILEGED_FUNCTION;
|
||||||
|
QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType,
|
||||||
|
StaticQueue_t * pxStaticQueue ) PRIVILEGED_FUNCTION;
|
||||||
|
QueueHandle_t MPU_xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount,
|
||||||
|
const UBaseType_t uxInitialCount ) PRIVILEGED_FUNCTION;
|
||||||
|
QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount,
|
||||||
|
const UBaseType_t uxInitialCount,
|
||||||
|
StaticQueue_t * pxStaticQueue ) PRIVILEGED_FUNCTION;
|
||||||
|
QueueHandle_t MPU_xQueueGenericCreate( const UBaseType_t uxQueueLength,
|
||||||
|
const UBaseType_t uxItemSize,
|
||||||
|
const uint8_t ucQueueType ) PRIVILEGED_FUNCTION;
|
||||||
|
QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength,
|
||||||
|
const UBaseType_t uxItemSize,
|
||||||
|
uint8_t * pucQueueStorage,
|
||||||
|
StaticQueue_t * pxStaticQueue,
|
||||||
|
const uint8_t ucQueueType ) PRIVILEGED_FUNCTION;
|
||||||
|
QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ) PRIVILEGED_FUNCTION;
|
||||||
|
BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore,
|
||||||
|
QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION;
|
||||||
|
BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue,
|
||||||
|
BaseType_t xNewQueue ) PRIVILEGED_FUNCTION;
|
||||||
|
BaseType_t MPU_xQueueGenericGetStaticBuffers( QueueHandle_t xQueue,
|
||||||
|
uint8_t ** ppucQueueStorage,
|
||||||
|
StaticQueue_t ** ppxStaticQueue ) PRIVILEGED_FUNCTION;
|
||||||
|
BaseType_t MPU_xQueueGenericSendFromISR( QueueHandle_t xQueue,
|
||||||
|
const void * const pvItemToQueue,
|
||||||
|
BaseType_t * const pxHigherPriorityTaskWoken,
|
||||||
|
const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION;
|
||||||
|
BaseType_t MPU_xQueueGiveFromISR( QueueHandle_t xQueue,
|
||||||
|
BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||||
|
BaseType_t MPU_xQueuePeekFromISR( QueueHandle_t xQueue,
|
||||||
|
void * const pvBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
BaseType_t MPU_xQueueReceiveFromISR( QueueHandle_t xQueue,
|
||||||
|
void * const pvBuffer,
|
||||||
|
BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||||
|
BaseType_t MPU_xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;
|
||||||
|
BaseType_t MPU_xQueueIsQueueFullFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;
|
||||||
|
UBaseType_t MPU_uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;
|
||||||
|
TaskHandle_t MPU_xQueueGetMutexHolderFromISR( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION;
|
||||||
|
QueueSetMemberHandle_t MPU_xQueueSelectFromSetFromISR( QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/* MPU versions of timers.h API functions. */
|
||||||
|
void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
|
||||||
|
void MPU_vTimerSetTimerID( TimerHandle_t xTimer,
|
||||||
|
void * pvNewID ) FREERTOS_SYSTEM_CALL;
|
||||||
|
BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
|
||||||
|
TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) FREERTOS_SYSTEM_CALL;
|
||||||
|
BaseType_t MPU_xTimerGenericCommandFromTask( TimerHandle_t xTimer,
|
||||||
|
const BaseType_t xCommandID,
|
||||||
|
const TickType_t xOptionalValue,
|
||||||
|
BaseType_t * const pxHigherPriorityTaskWoken,
|
||||||
|
const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||||
|
BaseType_t MPU_xTimerGenericCommandFromTaskEntry( const xTimerGenericCommandFromTaskParams_t * pxParams ) FREERTOS_SYSTEM_CALL;
|
||||||
|
const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
|
||||||
|
void MPU_vTimerSetReloadMode( TimerHandle_t xTimer,
|
||||||
|
const BaseType_t uxAutoReload ) FREERTOS_SYSTEM_CALL;
|
||||||
|
BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
|
||||||
|
UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
|
||||||
|
TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
|
||||||
|
TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
|
||||||
|
|
||||||
|
/* Privileged only wrappers for Timer APIs. These are needed so that
|
||||||
|
* the application can use opaque handles maintained in mpu_wrappers.c
|
||||||
|
* with all the APIs. */
|
||||||
|
TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName,
|
||||||
|
const TickType_t xTimerPeriodInTicks,
|
||||||
|
const UBaseType_t uxAutoReload,
|
||||||
|
void * const pvTimerID,
|
||||||
|
TimerCallbackFunction_t pxCallbackFunction ) PRIVILEGED_FUNCTION;
|
||||||
|
TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName,
|
||||||
|
const TickType_t xTimerPeriodInTicks,
|
||||||
|
const UBaseType_t uxAutoReload,
|
||||||
|
void * const pvTimerID,
|
||||||
|
TimerCallbackFunction_t pxCallbackFunction,
|
||||||
|
StaticTimer_t * pxTimerBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
BaseType_t MPU_xTimerGetStaticBuffer( TimerHandle_t xTimer,
|
||||||
|
StaticTimer_t ** ppxTimerBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
BaseType_t MPU_xTimerGenericCommandFromISR( TimerHandle_t xTimer,
|
||||||
|
const BaseType_t xCommandID,
|
||||||
|
const TickType_t xOptionalValue,
|
||||||
|
BaseType_t * const pxHigherPriorityTaskWoken,
|
||||||
|
const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/* MPU versions of event_group.h API functions. */
|
||||||
|
EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
|
||||||
|
const EventBits_t uxBitsToWaitFor,
|
||||||
|
const BaseType_t xClearOnExit,
|
||||||
|
const BaseType_t xWaitForAllBits,
|
||||||
|
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||||
|
EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) FREERTOS_SYSTEM_CALL;
|
||||||
|
EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup,
|
||||||
|
const EventBits_t uxBitsToClear ) FREERTOS_SYSTEM_CALL;
|
||||||
|
EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup,
|
||||||
|
const EventBits_t uxBitsToSet ) FREERTOS_SYSTEM_CALL;
|
||||||
|
EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup,
|
||||||
|
const EventBits_t uxBitsToSet,
|
||||||
|
const EventBits_t uxBitsToWaitFor,
|
||||||
|
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||||
|
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||||
|
UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) FREERTOS_SYSTEM_CALL;
|
||||||
|
void MPU_vEventGroupSetNumber( void * xEventGroup,
|
||||||
|
UBaseType_t uxEventGroupNumber ) FREERTOS_SYSTEM_CALL;
|
||||||
|
#endif /* ( configUSE_TRACE_FACILITY == 1 )*/
|
||||||
|
|
||||||
|
/* Privileged only wrappers for Event Group APIs. These are needed so that
|
||||||
|
* the application can use opaque handles maintained in mpu_wrappers.c
|
||||||
|
* with all the APIs. */
|
||||||
|
EventGroupHandle_t MPU_xEventGroupCreate( void ) PRIVILEGED_FUNCTION;
|
||||||
|
EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;
|
||||||
|
BaseType_t MPU_xEventGroupGetStaticBuffer( EventGroupHandle_t xEventGroup,
|
||||||
|
StaticEventGroup_t ** ppxEventGroupBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
BaseType_t MPU_xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup,
|
||||||
|
const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;
|
||||||
|
BaseType_t MPU_xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup,
|
||||||
|
const EventBits_t uxBitsToSet,
|
||||||
|
BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||||
|
EventBits_t MPU_xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/* MPU versions of message/stream_buffer.h API functions. */
|
||||||
|
size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
|
||||||
|
const void * pvTxData,
|
||||||
|
size_t xDataLengthBytes,
|
||||||
|
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||||
|
size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
|
||||||
|
void * pvRxData,
|
||||||
|
size_t xBufferLengthBytes,
|
||||||
|
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||||
|
BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
|
||||||
|
BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
|
||||||
|
size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
|
||||||
|
size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
|
||||||
|
BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer,
|
||||||
|
size_t xTriggerLevel ) FREERTOS_SYSTEM_CALL;
|
||||||
|
size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
|
||||||
|
|
||||||
|
/* Privileged only wrappers for Stream Buffer APIs. These are needed so that
|
||||||
|
* the application can use opaque handles maintained in mpu_wrappers.c
|
||||||
|
* with all the APIs. */
|
||||||
|
StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes,
|
||||||
|
size_t xTriggerLevelBytes,
|
||||||
|
BaseType_t xStreamBufferType,
|
||||||
|
StreamBufferCallbackFunction_t pxSendCompletedCallback,
|
||||||
|
StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) PRIVILEGED_FUNCTION;
|
||||||
|
StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,
|
||||||
|
size_t xTriggerLevelBytes,
|
||||||
|
BaseType_t xStreamBufferType,
|
||||||
|
uint8_t * const pucStreamBufferStorageArea,
|
||||||
|
StaticStreamBuffer_t * const pxStaticStreamBuffer,
|
||||||
|
StreamBufferCallbackFunction_t pxSendCompletedCallback,
|
||||||
|
StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) PRIVILEGED_FUNCTION;
|
||||||
|
void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
BaseType_t MPU_xStreamBufferGetStaticBuffers( StreamBufferHandle_t xStreamBuffers,
|
||||||
|
uint8_t * ppucStreamBufferStorageArea,
|
||||||
|
StaticStreamBuffer_t * ppxStaticStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
size_t MPU_xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||||
|
const void * pvTxData,
|
||||||
|
size_t xDataLengthBytes,
|
||||||
|
BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||||
|
size_t MPU_xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||||
|
void * pvRxData,
|
||||||
|
size_t xBufferLengthBytes,
|
||||||
|
BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||||
|
BaseType_t MPU_xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||||
|
BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||||
|
BaseType_t MPU_xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||||
|
BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||||
|
BaseType_t MPU_xStreamBufferResetFromISR( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
#endif /* MPU_PROTOTYPES_H */
|
|
@ -0,0 +1,105 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MPU_SYSCALL_NUMBERS_H
|
||||||
|
#define MPU_SYSCALL_NUMBERS_H
|
||||||
|
|
||||||
|
/* Numbers assigned to various system calls. */
|
||||||
|
#define SYSTEM_CALL_xTaskGenericNotify 0
|
||||||
|
#define SYSTEM_CALL_xTaskGenericNotifyWait 1
|
||||||
|
#define SYSTEM_CALL_xTimerGenericCommandFromTask 2
|
||||||
|
#define SYSTEM_CALL_xEventGroupWaitBits 3
|
||||||
|
#define SYSTEM_CALL_xTaskDelayUntil 4
|
||||||
|
#define SYSTEM_CALL_xTaskAbortDelay 5
|
||||||
|
#define SYSTEM_CALL_vTaskDelay 6
|
||||||
|
#define SYSTEM_CALL_uxTaskPriorityGet 7
|
||||||
|
#define SYSTEM_CALL_eTaskGetState 8
|
||||||
|
#define SYSTEM_CALL_vTaskGetInfo 9
|
||||||
|
#define SYSTEM_CALL_xTaskGetIdleTaskHandle 10
|
||||||
|
#define SYSTEM_CALL_vTaskSuspend 11
|
||||||
|
#define SYSTEM_CALL_vTaskResume 12
|
||||||
|
#define SYSTEM_CALL_xTaskGetTickCount 13
|
||||||
|
#define SYSTEM_CALL_uxTaskGetNumberOfTasks 14
|
||||||
|
#define SYSTEM_CALL_ulTaskGetRunTimeCounter 15
|
||||||
|
#define SYSTEM_CALL_ulTaskGetRunTimePercent 16
|
||||||
|
#define SYSTEM_CALL_ulTaskGetIdleRunTimePercent 17
|
||||||
|
#define SYSTEM_CALL_ulTaskGetIdleRunTimeCounter 18
|
||||||
|
#define SYSTEM_CALL_vTaskSetApplicationTaskTag 19
|
||||||
|
#define SYSTEM_CALL_xTaskGetApplicationTaskTag 20
|
||||||
|
#define SYSTEM_CALL_vTaskSetThreadLocalStoragePointer 21
|
||||||
|
#define SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer 22
|
||||||
|
#define SYSTEM_CALL_uxTaskGetSystemState 23
|
||||||
|
#define SYSTEM_CALL_uxTaskGetStackHighWaterMark 24
|
||||||
|
#define SYSTEM_CALL_uxTaskGetStackHighWaterMark2 25
|
||||||
|
#define SYSTEM_CALL_xTaskGetCurrentTaskHandle 26
|
||||||
|
#define SYSTEM_CALL_xTaskGetSchedulerState 27
|
||||||
|
#define SYSTEM_CALL_vTaskSetTimeOutState 28
|
||||||
|
#define SYSTEM_CALL_xTaskCheckForTimeOut 29
|
||||||
|
#define SYSTEM_CALL_ulTaskGenericNotifyTake 30
|
||||||
|
#define SYSTEM_CALL_xTaskGenericNotifyStateClear 31
|
||||||
|
#define SYSTEM_CALL_ulTaskGenericNotifyValueClear 32
|
||||||
|
#define SYSTEM_CALL_xQueueGenericSend 33
|
||||||
|
#define SYSTEM_CALL_uxQueueMessagesWaiting 34
|
||||||
|
#define SYSTEM_CALL_uxQueueSpacesAvailable 35
|
||||||
|
#define SYSTEM_CALL_xQueueReceive 36
|
||||||
|
#define SYSTEM_CALL_xQueuePeek 37
|
||||||
|
#define SYSTEM_CALL_xQueueSemaphoreTake 38
|
||||||
|
#define SYSTEM_CALL_xQueueGetMutexHolder 39
|
||||||
|
#define SYSTEM_CALL_xQueueTakeMutexRecursive 40
|
||||||
|
#define SYSTEM_CALL_xQueueGiveMutexRecursive 41
|
||||||
|
#define SYSTEM_CALL_xQueueSelectFromSet 42
|
||||||
|
#define SYSTEM_CALL_xQueueAddToSet 43
|
||||||
|
#define SYSTEM_CALL_vQueueAddToRegistry 44
|
||||||
|
#define SYSTEM_CALL_vQueueUnregisterQueue 45
|
||||||
|
#define SYSTEM_CALL_pcQueueGetName 46
|
||||||
|
#define SYSTEM_CALL_pvTimerGetTimerID 47
|
||||||
|
#define SYSTEM_CALL_vTimerSetTimerID 48
|
||||||
|
#define SYSTEM_CALL_xTimerIsTimerActive 49
|
||||||
|
#define SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle 50
|
||||||
|
#define SYSTEM_CALL_pcTimerGetName 51
|
||||||
|
#define SYSTEM_CALL_vTimerSetReloadMode 52
|
||||||
|
#define SYSTEM_CALL_xTimerGetReloadMode 53
|
||||||
|
#define SYSTEM_CALL_uxTimerGetReloadMode 54
|
||||||
|
#define SYSTEM_CALL_xTimerGetPeriod 55
|
||||||
|
#define SYSTEM_CALL_xTimerGetExpiryTime 56
|
||||||
|
#define SYSTEM_CALL_xEventGroupClearBits 57
|
||||||
|
#define SYSTEM_CALL_xEventGroupSetBits 58
|
||||||
|
#define SYSTEM_CALL_xEventGroupSync 59
|
||||||
|
#define SYSTEM_CALL_uxEventGroupGetNumber 60
|
||||||
|
#define SYSTEM_CALL_vEventGroupSetNumber 61
|
||||||
|
#define SYSTEM_CALL_xStreamBufferSend 62
|
||||||
|
#define SYSTEM_CALL_xStreamBufferReceive 63
|
||||||
|
#define SYSTEM_CALL_xStreamBufferIsFull 64
|
||||||
|
#define SYSTEM_CALL_xStreamBufferIsEmpty 65
|
||||||
|
#define SYSTEM_CALL_xStreamBufferSpacesAvailable 66
|
||||||
|
#define SYSTEM_CALL_xStreamBufferBytesAvailable 67
|
||||||
|
#define SYSTEM_CALL_xStreamBufferSetTriggerLevel 68
|
||||||
|
#define SYSTEM_CALL_xStreamBufferNextMessageLengthBytes 69
|
||||||
|
#define NUM_SYSTEM_CALLS 70 /* Total number of system calls. */
|
||||||
|
|
||||||
|
#endif /* MPU_SYSCALL_NUMBERS_H */
|
|
@ -1,177 +1,276 @@
|
||||||
/*
|
/*
|
||||||
FreeRTOS V8.2.3 - Copyright (C) 2015 Real Time Engineers Ltd.
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
All rights reserved
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
This file is part of the FreeRTOS distribution.
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
* the Software without restriction, including without limitation the rights to
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
***************************************************************************
|
*
|
||||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
* copies or substantial portions of the Software.
|
||||||
>>! obliged to provide the source code for proprietary components !<<
|
*
|
||||||
>>! outside of the FreeRTOS kernel. !<<
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
***************************************************************************
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
link: http://www.freertos.org/a00114.html
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
***************************************************************************
|
* https://github.com/FreeRTOS
|
||||||
* *
|
*
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
*/
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
|
||||||
* platform software that is more than just the market leader, it *
|
|
||||||
* is the industry's de facto standard. *
|
|
||||||
* *
|
|
||||||
* Help yourself get started quickly while simultaneously helping *
|
|
||||||
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
|
||||||
* tutorial book, reference manual, or both: *
|
|
||||||
* http://www.FreeRTOS.org/Documentation *
|
|
||||||
* *
|
|
||||||
***************************************************************************
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
|
||||||
the FAQ page "My application does not run, what could be wrong?". Have you
|
|
||||||
defined configASSERT()?
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
|
||||||
embedded software for free we request you assist our global community by
|
|
||||||
participating in the support forum.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
|
||||||
be as productive as possible as early as possible. Now you can receive
|
|
||||||
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
|
||||||
Ltd, and the world's leading authority on the world's leading RTOS.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
|
||||||
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
|
||||||
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and commercial middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MPU_WRAPPERS_H
|
#ifndef MPU_WRAPPERS_H
|
||||||
#define MPU_WRAPPERS_H
|
#define MPU_WRAPPERS_H
|
||||||
|
|
||||||
/* This file redefines API functions to be called through a wrapper macro, but
|
/* This file redefines API functions to be called through a wrapper macro, but
|
||||||
only for ports that are using the MPU. */
|
* only for ports that are using the MPU. */
|
||||||
#ifdef portUSING_MPU_WRAPPERS
|
#if ( portUSING_MPU_WRAPPERS == 1 )
|
||||||
|
|
||||||
/* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is
|
/* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is
|
||||||
included from queue.c or task.c to prevent it from having an effect within
|
* included from queue.c or task.c to prevent it from having an effect within
|
||||||
those files. */
|
* those files. */
|
||||||
#ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
#ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||||
|
|
||||||
#define xTaskGenericCreate MPU_xTaskGenericCreate
|
/*
|
||||||
#define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions
|
* Map standard (non MPU) API functions to equivalents that start
|
||||||
#define vTaskDelete MPU_vTaskDelete
|
* "MPU_". This will cause the application code to call the MPU_
|
||||||
#define vTaskDelayUntil MPU_vTaskDelayUntil
|
* version, which wraps the non-MPU version with privilege promoting
|
||||||
|
* then demoting code, so the kernel code always runs will full
|
||||||
|
* privileges.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Map standard task.h API functions to the MPU equivalents. */
|
||||||
#define vTaskDelay MPU_vTaskDelay
|
#define vTaskDelay MPU_vTaskDelay
|
||||||
|
#define xTaskDelayUntil MPU_xTaskDelayUntil
|
||||||
|
#define xTaskAbortDelay MPU_xTaskAbortDelay
|
||||||
#define uxTaskPriorityGet MPU_uxTaskPriorityGet
|
#define uxTaskPriorityGet MPU_uxTaskPriorityGet
|
||||||
#define vTaskPrioritySet MPU_vTaskPrioritySet
|
|
||||||
#define eTaskGetState MPU_eTaskGetState
|
#define eTaskGetState MPU_eTaskGetState
|
||||||
|
#define vTaskGetInfo MPU_vTaskGetInfo
|
||||||
#define vTaskSuspend MPU_vTaskSuspend
|
#define vTaskSuspend MPU_vTaskSuspend
|
||||||
#define vTaskResume MPU_vTaskResume
|
#define vTaskResume MPU_vTaskResume
|
||||||
#define vTaskSuspendAll MPU_vTaskSuspendAll
|
|
||||||
#define xTaskResumeAll MPU_xTaskResumeAll
|
|
||||||
#define xTaskGetTickCount MPU_xTaskGetTickCount
|
#define xTaskGetTickCount MPU_xTaskGetTickCount
|
||||||
#define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks
|
#define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks
|
||||||
#define vTaskList MPU_vTaskList
|
#define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark
|
||||||
#define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats
|
#define uxTaskGetStackHighWaterMark2 MPU_uxTaskGetStackHighWaterMark2
|
||||||
#define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag
|
#define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag
|
||||||
#define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag
|
#define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag
|
||||||
#define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook
|
#define vTaskSetThreadLocalStoragePointer MPU_vTaskSetThreadLocalStoragePointer
|
||||||
#define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark
|
#define pvTaskGetThreadLocalStoragePointer MPU_pvTaskGetThreadLocalStoragePointer
|
||||||
#define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle
|
|
||||||
#define xTaskGetSchedulerState MPU_xTaskGetSchedulerState
|
|
||||||
#define xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle
|
#define xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle
|
||||||
#define uxTaskGetSystemState MPU_uxTaskGetSystemState
|
#define uxTaskGetSystemState MPU_uxTaskGetSystemState
|
||||||
|
#define ulTaskGetIdleRunTimeCounter MPU_ulTaskGetIdleRunTimeCounter
|
||||||
|
#define ulTaskGetIdleRunTimePercent MPU_ulTaskGetIdleRunTimePercent
|
||||||
#define xTaskGenericNotify MPU_xTaskGenericNotify
|
#define xTaskGenericNotify MPU_xTaskGenericNotify
|
||||||
#define xTaskNotifyWait MPU_xTaskNotifyWait
|
#define xTaskGenericNotifyWait MPU_xTaskGenericNotifyWait
|
||||||
#define ulTaskNotifyTake MPU_ulTaskNotifyTake
|
#define ulTaskGenericNotifyTake MPU_ulTaskGenericNotifyTake
|
||||||
|
#define xTaskGenericNotifyStateClear MPU_xTaskGenericNotifyStateClear
|
||||||
|
#define ulTaskGenericNotifyValueClear MPU_ulTaskGenericNotifyValueClear
|
||||||
|
#define vTaskSetTimeOutState MPU_vTaskSetTimeOutState
|
||||||
|
#define xTaskCheckForTimeOut MPU_xTaskCheckForTimeOut
|
||||||
|
#define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle
|
||||||
|
#define xTaskGetSchedulerState MPU_xTaskGetSchedulerState
|
||||||
|
|
||||||
#define xQueueGenericCreate MPU_xQueueGenericCreate
|
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
|
||||||
#define xQueueCreateMutex MPU_xQueueCreateMutex
|
#define ulTaskGetRunTimeCounter MPU_ulTaskGetRunTimeCounter
|
||||||
#define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive
|
#define ulTaskGetRunTimePercent MPU_ulTaskGetRunTimePercent
|
||||||
#define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive
|
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||||
#define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore
|
|
||||||
|
/* Privileged only wrappers for Task APIs. These are needed so that
|
||||||
|
* the application can use opaque handles maintained in mpu_wrappers.c
|
||||||
|
* with all the APIs. */
|
||||||
|
#define xTaskCreate MPU_xTaskCreate
|
||||||
|
#define xTaskCreateStatic MPU_xTaskCreateStatic
|
||||||
|
#define vTaskDelete MPU_vTaskDelete
|
||||||
|
#define vTaskPrioritySet MPU_vTaskPrioritySet
|
||||||
|
#define xTaskGetHandle MPU_xTaskGetHandle
|
||||||
|
#define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook
|
||||||
|
|
||||||
|
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
|
||||||
|
#define pcTaskGetName MPU_pcTaskGetName
|
||||||
|
#define xTaskCreateRestricted MPU_xTaskCreateRestricted
|
||||||
|
#define xTaskCreateRestrictedStatic MPU_xTaskCreateRestrictedStatic
|
||||||
|
#define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions
|
||||||
|
#define xTaskGetStaticBuffers MPU_xTaskGetStaticBuffers
|
||||||
|
#define uxTaskPriorityGetFromISR MPU_uxTaskPriorityGetFromISR
|
||||||
|
#define uxTaskBasePriorityGet MPU_uxTaskBasePriorityGet
|
||||||
|
#define uxTaskBasePriorityGetFromISR MPU_uxTaskBasePriorityGetFromISR
|
||||||
|
#define xTaskResumeFromISR MPU_xTaskResumeFromISR
|
||||||
|
#define xTaskGetApplicationTaskTagFromISR MPU_xTaskGetApplicationTaskTagFromISR
|
||||||
|
#define xTaskGenericNotifyFromISR MPU_xTaskGenericNotifyFromISR
|
||||||
|
#define vTaskGenericNotifyGiveFromISR MPU_vTaskGenericNotifyGiveFromISR
|
||||||
|
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||||
|
|
||||||
|
/* Map standard queue.h API functions to the MPU equivalents. */
|
||||||
#define xQueueGenericSend MPU_xQueueGenericSend
|
#define xQueueGenericSend MPU_xQueueGenericSend
|
||||||
#define xQueueAltGenericSend MPU_xQueueAltGenericSend
|
#define xQueueReceive MPU_xQueueReceive
|
||||||
#define xQueueAltGenericReceive MPU_xQueueAltGenericReceive
|
#define xQueuePeek MPU_xQueuePeek
|
||||||
#define xQueueGenericReceive MPU_xQueueGenericReceive
|
#define xQueueSemaphoreTake MPU_xQueueSemaphoreTake
|
||||||
#define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting
|
#define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting
|
||||||
#define vQueueDelete MPU_vQueueDelete
|
#define uxQueueSpacesAvailable MPU_uxQueueSpacesAvailable
|
||||||
#define xQueueGenericReset MPU_xQueueGenericReset
|
#define xQueueGetMutexHolder MPU_xQueueGetMutexHolder
|
||||||
#define xQueueCreateSet MPU_xQueueCreateSet
|
#define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive
|
||||||
#define xQueueSelectFromSet MPU_xQueueSelectFromSet
|
#define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive
|
||||||
#define xQueueAddToSet MPU_xQueueAddToSet
|
#define xQueueAddToSet MPU_xQueueAddToSet
|
||||||
#define xQueueRemoveFromSet MPU_xQueueRemoveFromSet
|
#define xQueueSelectFromSet MPU_xQueueSelectFromSet
|
||||||
#define xQueueGetMutexHolder MPU_xQueueGetMutexHolder
|
|
||||||
#define xQueueGetMutexHolder MPU_xQueueGetMutexHolder
|
|
||||||
|
|
||||||
#define pvPortMalloc MPU_pvPortMalloc
|
#if ( configQUEUE_REGISTRY_SIZE > 0 )
|
||||||
#define vPortFree MPU_vPortFree
|
|
||||||
#define xPortGetFreeHeapSize MPU_xPortGetFreeHeapSize
|
|
||||||
#define vPortInitialiseBlocks MPU_vPortInitialiseBlocks
|
|
||||||
#define xPortGetMinimumEverFreeHeapSize MPU_xPortGetMinimumEverFreeHeapSize
|
|
||||||
|
|
||||||
#if configQUEUE_REGISTRY_SIZE > 0
|
|
||||||
#define vQueueAddToRegistry MPU_vQueueAddToRegistry
|
#define vQueueAddToRegistry MPU_vQueueAddToRegistry
|
||||||
#define vQueueUnregisterQueue MPU_vQueueUnregisterQueue
|
#define vQueueUnregisterQueue MPU_vQueueUnregisterQueue
|
||||||
#endif
|
#define pcQueueGetName MPU_pcQueueGetName
|
||||||
|
#endif /* #if ( configQUEUE_REGISTRY_SIZE > 0 ) */
|
||||||
|
|
||||||
#define xTimerCreate MPU_xTimerCreate
|
/* Privileged only wrappers for Queue APIs. These are needed so that
|
||||||
|
* the application can use opaque handles maintained in mpu_wrappers.c
|
||||||
|
* with all the APIs. */
|
||||||
|
#define vQueueDelete MPU_vQueueDelete
|
||||||
|
#define xQueueCreateMutex MPU_xQueueCreateMutex
|
||||||
|
#define xQueueCreateMutexStatic MPU_xQueueCreateMutexStatic
|
||||||
|
#define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore
|
||||||
|
#define xQueueCreateCountingSemaphoreStatic MPU_xQueueCreateCountingSemaphoreStatic
|
||||||
|
#define xQueueGenericCreate MPU_xQueueGenericCreate
|
||||||
|
#define xQueueGenericCreateStatic MPU_xQueueGenericCreateStatic
|
||||||
|
#define xQueueGenericReset MPU_xQueueGenericReset
|
||||||
|
#define xQueueCreateSet MPU_xQueueCreateSet
|
||||||
|
#define xQueueRemoveFromSet MPU_xQueueRemoveFromSet
|
||||||
|
|
||||||
|
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
|
||||||
|
#define xQueueGenericGetStaticBuffers MPU_xQueueGenericGetStaticBuffers
|
||||||
|
#define xQueueGenericSendFromISR MPU_xQueueGenericSendFromISR
|
||||||
|
#define xQueueGiveFromISR MPU_xQueueGiveFromISR
|
||||||
|
#define xQueuePeekFromISR MPU_xQueuePeekFromISR
|
||||||
|
#define xQueueReceiveFromISR MPU_xQueueReceiveFromISR
|
||||||
|
#define xQueueIsQueueEmptyFromISR MPU_xQueueIsQueueEmptyFromISR
|
||||||
|
#define xQueueIsQueueFullFromISR MPU_xQueueIsQueueFullFromISR
|
||||||
|
#define uxQueueMessagesWaitingFromISR MPU_uxQueueMessagesWaitingFromISR
|
||||||
|
#define xQueueGetMutexHolderFromISR MPU_xQueueGetMutexHolderFromISR
|
||||||
|
#define xQueueSelectFromSetFromISR MPU_xQueueSelectFromSetFromISR
|
||||||
|
#endif /* if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||||
|
|
||||||
|
/* Map standard timer.h API functions to the MPU equivalents. */
|
||||||
#define pvTimerGetTimerID MPU_pvTimerGetTimerID
|
#define pvTimerGetTimerID MPU_pvTimerGetTimerID
|
||||||
#define vTimerSetTimerID MPU_vTimerSetTimerID
|
#define vTimerSetTimerID MPU_vTimerSetTimerID
|
||||||
#define xTimerIsTimerActive MPU_xTimerIsTimerActive
|
#define xTimerIsTimerActive MPU_xTimerIsTimerActive
|
||||||
#define xTimerGetTimerDaemonTaskHandle MPU_xTimerGetTimerDaemonTaskHandle
|
#define xTimerGetTimerDaemonTaskHandle MPU_xTimerGetTimerDaemonTaskHandle
|
||||||
#define xTimerPendFunctionCall MPU_xTimerPendFunctionCall
|
#define xTimerGenericCommandFromTask MPU_xTimerGenericCommandFromTask
|
||||||
#define pcTimerGetTimerName MPU_pcTimerGetTimerName
|
#define pcTimerGetName MPU_pcTimerGetName
|
||||||
#define xTimerGenericCommand MPU_xTimerGenericCommand
|
#define vTimerSetReloadMode MPU_vTimerSetReloadMode
|
||||||
|
#define uxTimerGetReloadMode MPU_uxTimerGetReloadMode
|
||||||
|
#define xTimerGetPeriod MPU_xTimerGetPeriod
|
||||||
|
#define xTimerGetExpiryTime MPU_xTimerGetExpiryTime
|
||||||
|
|
||||||
#define xEventGroupCreate MPU_xEventGroupCreate
|
/* Privileged only wrappers for Timer APIs. These are needed so that
|
||||||
|
* the application can use opaque handles maintained in mpu_wrappers.c
|
||||||
|
* with all the APIs. */
|
||||||
|
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
|
||||||
|
#define xTimerGetReloadMode MPU_xTimerGetReloadMode
|
||||||
|
#define xTimerCreate MPU_xTimerCreate
|
||||||
|
#define xTimerCreateStatic MPU_xTimerCreateStatic
|
||||||
|
#define xTimerGetStaticBuffer MPU_xTimerGetStaticBuffer
|
||||||
|
#define xTimerGenericCommandFromISR MPU_xTimerGenericCommandFromISR
|
||||||
|
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||||
|
|
||||||
|
/* Map standard event_group.h API functions to the MPU equivalents. */
|
||||||
#define xEventGroupWaitBits MPU_xEventGroupWaitBits
|
#define xEventGroupWaitBits MPU_xEventGroupWaitBits
|
||||||
#define xEventGroupClearBits MPU_xEventGroupClearBits
|
#define xEventGroupClearBits MPU_xEventGroupClearBits
|
||||||
#define xEventGroupSetBits MPU_xEventGroupSetBits
|
#define xEventGroupSetBits MPU_xEventGroupSetBits
|
||||||
#define xEventGroupSync MPU_xEventGroupSync
|
#define xEventGroupSync MPU_xEventGroupSync
|
||||||
|
|
||||||
|
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||||
|
#define uxEventGroupGetNumber MPU_uxEventGroupGetNumber
|
||||||
|
#define vEventGroupSetNumber MPU_vEventGroupSetNumber
|
||||||
|
#endif /* #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */
|
||||||
|
|
||||||
|
/* Privileged only wrappers for Event Group APIs. These are needed so that
|
||||||
|
* the application can use opaque handles maintained in mpu_wrappers.c
|
||||||
|
* with all the APIs. */
|
||||||
|
#define xEventGroupCreate MPU_xEventGroupCreate
|
||||||
|
#define xEventGroupCreateStatic MPU_xEventGroupCreateStatic
|
||||||
#define vEventGroupDelete MPU_vEventGroupDelete
|
#define vEventGroupDelete MPU_vEventGroupDelete
|
||||||
|
|
||||||
/* Remove the privileged function macro. */
|
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
|
||||||
#define PRIVILEGED_FUNCTION
|
#define xEventGroupGetStaticBuffer MPU_xEventGroupGetStaticBuffer
|
||||||
|
#define xEventGroupClearBitsFromISR MPU_xEventGroupClearBitsFromISR
|
||||||
|
#define xEventGroupSetBitsFromISR MPU_xEventGroupSetBitsFromISR
|
||||||
|
#define xEventGroupGetBitsFromISR MPU_xEventGroupGetBitsFromISR
|
||||||
|
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||||
|
|
||||||
#else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
|
/* Map standard message/stream_buffer.h API functions to the MPU
|
||||||
|
* equivalents. */
|
||||||
|
#define xStreamBufferSend MPU_xStreamBufferSend
|
||||||
|
#define xStreamBufferReceive MPU_xStreamBufferReceive
|
||||||
|
#define xStreamBufferIsFull MPU_xStreamBufferIsFull
|
||||||
|
#define xStreamBufferIsEmpty MPU_xStreamBufferIsEmpty
|
||||||
|
#define xStreamBufferSpacesAvailable MPU_xStreamBufferSpacesAvailable
|
||||||
|
#define xStreamBufferBytesAvailable MPU_xStreamBufferBytesAvailable
|
||||||
|
#define xStreamBufferSetTriggerLevel MPU_xStreamBufferSetTriggerLevel
|
||||||
|
#define xStreamBufferNextMessageLengthBytes MPU_xStreamBufferNextMessageLengthBytes
|
||||||
|
|
||||||
/* Ensure API functions go in the privileged execution section. */
|
/* Privileged only wrappers for Stream Buffer APIs. These are needed so that
|
||||||
#define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions")))
|
* the application can use opaque handles maintained in mpu_wrappers.c
|
||||||
#define PRIVILEGED_DATA __attribute__((section("privileged_data")))
|
* with all the APIs. */
|
||||||
|
|
||||||
|
#define xStreamBufferGenericCreate MPU_xStreamBufferGenericCreate
|
||||||
|
#define xStreamBufferGenericCreateStatic MPU_xStreamBufferGenericCreateStatic
|
||||||
|
#define vStreamBufferDelete MPU_vStreamBufferDelete
|
||||||
|
#define xStreamBufferReset MPU_xStreamBufferReset
|
||||||
|
|
||||||
|
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
|
||||||
|
#define xStreamBufferGetStaticBuffers MPU_xStreamBufferGetStaticBuffers
|
||||||
|
#define xStreamBufferSendFromISR MPU_xStreamBufferSendFromISR
|
||||||
|
#define xStreamBufferReceiveFromISR MPU_xStreamBufferReceiveFromISR
|
||||||
|
#define xStreamBufferSendCompletedFromISR MPU_xStreamBufferSendCompletedFromISR
|
||||||
|
#define xStreamBufferReceiveCompletedFromISR MPU_xStreamBufferReceiveCompletedFromISR
|
||||||
|
#define xStreamBufferResetFromISR MPU_xStreamBufferResetFromISR
|
||||||
|
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||||
|
|
||||||
|
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
|
||||||
|
|
||||||
|
#define vGrantAccessToTask( xTask, xTaskToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xTaskToGrantAccess ) )
|
||||||
|
#define vRevokeAccessToTask( xTask, xTaskToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xTaskToRevokeAccess ) )
|
||||||
|
|
||||||
|
#define vGrantAccessToSemaphore( xTask, xSemaphoreToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xSemaphoreToGrantAccess ) )
|
||||||
|
#define vRevokeAccessToSemaphore( xTask, xSemaphoreToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xSemaphoreToRevokeAccess ) )
|
||||||
|
|
||||||
|
#define vGrantAccessToQueue( xTask, xQueueToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xQueueToGrantAccess ) )
|
||||||
|
#define vRevokeAccessToQueue( xTask, xQueueToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xQueueToRevokeAccess ) )
|
||||||
|
|
||||||
|
#define vGrantAccessToQueueSet( xTask, xQueueSetToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xQueueSetToGrantAccess ) )
|
||||||
|
#define vRevokeAccessToQueueSet( xTask, xQueueSetToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xQueueSetToRevokeAccess ) )
|
||||||
|
|
||||||
|
#define vGrantAccessToEventGroup( xTask, xEventGroupToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xEventGroupToGrantAccess ) )
|
||||||
|
#define vRevokeAccessToEventGroup( xTask, xEventGroupToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xEventGroupToRevokeAccess ) )
|
||||||
|
|
||||||
|
#define vGrantAccessToStreamBuffer( xTask, xStreamBufferToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xStreamBufferToGrantAccess ) )
|
||||||
|
#define vRevokeAccessToStreamBuffer( xTask, xStreamBufferToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xStreamBufferToRevokeAccess ) )
|
||||||
|
|
||||||
|
#define vGrantAccessToMessageBuffer( xTask, xMessageBufferToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xMessageBufferToGrantAccess ) )
|
||||||
|
#define vRevokeAccessToMessageBuffer( xTask, xMessageBufferToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xMessageBufferToRevokeAccess ) )
|
||||||
|
|
||||||
|
#define vGrantAccessToTimer( xTask, xTimerToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xTimerToGrantAccess ) )
|
||||||
|
#define vRevokeAccessToTimer( xTask, xTimerToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xTimerToRevokeAccess ) )
|
||||||
|
|
||||||
|
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
|
||||||
|
|
||||||
#endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
|
#endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
|
||||||
|
|
||||||
|
#define PRIVILEGED_FUNCTION __attribute__( ( section( "privileged_functions" ) ) )
|
||||||
|
#define PRIVILEGED_DATA __attribute__( ( section( "privileged_data" ) ) )
|
||||||
|
#define FREERTOS_SYSTEM_CALL __attribute__( ( section( "freertos_system_calls" ) ) )
|
||||||
|
|
||||||
#else /* portUSING_MPU_WRAPPERS */
|
#else /* portUSING_MPU_WRAPPERS */
|
||||||
|
|
||||||
#define PRIVILEGED_FUNCTION
|
#define PRIVILEGED_FUNCTION
|
||||||
#define PRIVILEGED_DATA
|
#define PRIVILEGED_DATA
|
||||||
#define portUSING_MPU_WRAPPERS 0
|
#define FREERTOS_SYSTEM_CALL
|
||||||
|
|
||||||
#endif /* portUSING_MPU_WRAPPERS */
|
#endif /* portUSING_MPU_WRAPPERS */
|
||||||
|
|
||||||
|
|
||||||
#endif /* MPU_WRAPPERS_H */
|
#endif /* MPU_WRAPPERS_H */
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INC_NEWLIB_FREERTOS_H
|
||||||
|
#define INC_NEWLIB_FREERTOS_H
|
||||||
|
|
||||||
|
/* Note Newlib support has been included by popular demand, but is not
|
||||||
|
* used by the FreeRTOS maintainers themselves. FreeRTOS is not
|
||||||
|
* responsible for resulting newlib operation. User must be familiar with
|
||||||
|
* newlib and must provide system-wide implementations of the necessary
|
||||||
|
* stubs. Be warned that (at the time of writing) the current newlib design
|
||||||
|
* implements a system-wide malloc() that must be provided with locks.
|
||||||
|
*
|
||||||
|
* See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html
|
||||||
|
* for additional information. */
|
||||||
|
|
||||||
|
#include <reent.h>
|
||||||
|
|
||||||
|
#define configUSE_C_RUNTIME_TLS_SUPPORT 1
|
||||||
|
|
||||||
|
#ifndef configTLS_BLOCK_TYPE
|
||||||
|
#define configTLS_BLOCK_TYPE struct _reent
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configINIT_TLS_BLOCK
|
||||||
|
#define configINIT_TLS_BLOCK( xTLSBlock, pxTopOfStack ) _REENT_INIT_PTR( &( xTLSBlock ) )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configSET_TLS_BLOCK
|
||||||
|
#define configSET_TLS_BLOCK( xTLSBlock ) ( _impure_ptr = &( xTLSBlock ) )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configDEINIT_TLS_BLOCK
|
||||||
|
#define configDEINIT_TLS_BLOCK( xTLSBlock ) _reclaim_reent( &( xTLSBlock ) )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* INC_NEWLIB_FREERTOS_H */
|
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INC_PICOLIBC_FREERTOS_H
|
||||||
|
#define INC_PICOLIBC_FREERTOS_H
|
||||||
|
|
||||||
|
/* Use picolibc TLS support to allocate space for __thread variables,
|
||||||
|
* initialize them at thread creation and set the TLS context at
|
||||||
|
* thread switch time.
|
||||||
|
*
|
||||||
|
* See the picolibc TLS docs:
|
||||||
|
* https://github.com/picolibc/picolibc/blob/main/doc/tls.md
|
||||||
|
* for additional information. */
|
||||||
|
|
||||||
|
#include <picotls.h>
|
||||||
|
|
||||||
|
#define configUSE_C_RUNTIME_TLS_SUPPORT 1
|
||||||
|
|
||||||
|
#define configTLS_BLOCK_TYPE void *
|
||||||
|
|
||||||
|
#define picolibcTLS_SIZE ( ( portPOINTER_SIZE_TYPE ) _tls_size() )
|
||||||
|
#define picolibcSTACK_ALIGNMENT_MASK ( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK )
|
||||||
|
|
||||||
|
#if __PICOLIBC_MAJOR__ > 1 || __PICOLIBC_MINOR__ >= 8
|
||||||
|
|
||||||
|
/* Picolibc 1.8 and newer have explicit alignment values provided
|
||||||
|
* by the _tls_align() inline */
|
||||||
|
#define picolibcTLS_ALIGNMENT_MASK ( ( portPOINTER_SIZE_TYPE ) ( _tls_align() - 1 ) )
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* For older Picolibc versions, use the general port alignment value */
|
||||||
|
#define picolibcTLS_ALIGNMENT_MASK ( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Allocate thread local storage block off the end of the
|
||||||
|
* stack. The picolibcTLS_SIZE macro returns the size (in
|
||||||
|
* bytes) of the total TLS area used by the application.
|
||||||
|
* Calculate the top of stack address. */
|
||||||
|
#if ( portSTACK_GROWTH < 0 )
|
||||||
|
|
||||||
|
#define configINIT_TLS_BLOCK( xTLSBlock, pxTopOfStack ) \
|
||||||
|
do { \
|
||||||
|
xTLSBlock = ( void * ) ( ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) - \
|
||||||
|
picolibcTLS_SIZE ) & \
|
||||||
|
~picolibcTLS_ALIGNMENT_MASK ); \
|
||||||
|
pxTopOfStack = ( StackType_t * ) ( ( ( ( portPOINTER_SIZE_TYPE ) xTLSBlock ) - 1 ) & \
|
||||||
|
~picolibcSTACK_ALIGNMENT_MASK ); \
|
||||||
|
_init_tls( xTLSBlock ); \
|
||||||
|
} while( 0 )
|
||||||
|
#else /* portSTACK_GROWTH */
|
||||||
|
#define configINIT_TLS_BLOCK( xTLSBlock, pxTopOfStack ) \
|
||||||
|
do { \
|
||||||
|
xTLSBlock = ( void * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack + \
|
||||||
|
picolibcTLS_ALIGNMENT_MASK ) & ~picolibcTLS_ALIGNMENT_MASK ); \
|
||||||
|
pxTopOfStack = ( StackType_t * ) ( ( ( ( ( portPOINTER_SIZE_TYPE ) xTLSBlock ) + \
|
||||||
|
picolibcTLS_SIZE ) + picolibcSTACK_ALIGNMENT_MASK ) & \
|
||||||
|
~picolibcSTACK_ALIGNMENT_MASK ); \
|
||||||
|
_init_tls( xTLSBlock ); \
|
||||||
|
} while( 0 )
|
||||||
|
#endif /* portSTACK_GROWTH */
|
||||||
|
|
||||||
|
#define configSET_TLS_BLOCK( xTLSBlock ) _set_tls( xTLSBlock )
|
||||||
|
|
||||||
|
#define configDEINIT_TLS_BLOCK( xTLSBlock )
|
||||||
|
|
||||||
|
#endif /* INC_PICOLIBC_FREERTOS_H */
|
|
@ -1,156 +1,161 @@
|
||||||
/*
|
/*
|
||||||
FreeRTOS V8.2.3 - Copyright (C) 2015 Real Time Engineers Ltd.
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
All rights reserved
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
This file is part of the FreeRTOS distribution.
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
* the Software without restriction, including without limitation the rights to
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
***************************************************************************
|
*
|
||||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
* copies or substantial portions of the Software.
|
||||||
>>! obliged to provide the source code for proprietary components !<<
|
*
|
||||||
>>! outside of the FreeRTOS kernel. !<<
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
***************************************************************************
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
link: http://www.freertos.org/a00114.html
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
***************************************************************************
|
* https://github.com/FreeRTOS
|
||||||
* *
|
*
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
*/
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
|
||||||
* platform software that is more than just the market leader, it *
|
|
||||||
* is the industry's de facto standard. *
|
|
||||||
* *
|
|
||||||
* Help yourself get started quickly while simultaneously helping *
|
|
||||||
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
|
||||||
* tutorial book, reference manual, or both: *
|
|
||||||
* http://www.FreeRTOS.org/Documentation *
|
|
||||||
* *
|
|
||||||
***************************************************************************
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
|
||||||
the FAQ page "My application does not run, what could be wrong?". Have you
|
|
||||||
defined configASSERT()?
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
|
||||||
embedded software for free we request you assist our global community by
|
|
||||||
participating in the support forum.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
|
||||||
be as productive as possible as early as possible. Now you can receive
|
|
||||||
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
|
||||||
Ltd, and the world's leading authority on the world's leading RTOS.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
|
||||||
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
|
||||||
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and commercial middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Portable layer API. Each function must be defined for each port.
|
* Portable layer API. Each function must be defined for each port.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
#ifndef PORTABLE_H
|
#ifndef PORTABLE_H
|
||||||
#define PORTABLE_H
|
#define PORTABLE_H
|
||||||
|
|
||||||
/* Each FreeRTOS port has a unique portmacro.h header file. Originally a
|
/* Each FreeRTOS port has a unique portmacro.h header file. Originally a
|
||||||
pre-processor definition was used to ensure the pre-processor found the correct
|
* pre-processor definition was used to ensure the pre-processor found the correct
|
||||||
portmacro.h file for the port being used. That scheme was deprecated in favour
|
* portmacro.h file for the port being used. That scheme was deprecated in favour
|
||||||
of setting the compiler's include path such that it found the correct
|
* of setting the compiler's include path such that it found the correct
|
||||||
portmacro.h file - removing the need for the constant and allowing the
|
* portmacro.h file - removing the need for the constant and allowing the
|
||||||
portmacro.h file to be located anywhere in relation to the port being used.
|
* portmacro.h file to be located anywhere in relation to the port being used.
|
||||||
Purely for reasons of backward compatibility the old method is still valid, but
|
* Purely for reasons of backward compatibility the old method is still valid, but
|
||||||
to make it clear that new projects should not use it, support for the port
|
* to make it clear that new projects should not use it, support for the port
|
||||||
specific constants has been moved into the deprecated_definitions.h header
|
* specific constants has been moved into the deprecated_definitions.h header
|
||||||
file. */
|
* file. */
|
||||||
#include "deprecated_definitions.h"
|
#include "deprecated_definitions.h"
|
||||||
|
|
||||||
/* If portENTER_CRITICAL is not defined then including deprecated_definitions.h
|
/* If portENTER_CRITICAL is not defined then including deprecated_definitions.h
|
||||||
did not result in a portmacro.h header file being included - and it should be
|
* did not result in a portmacro.h header file being included - and it should be
|
||||||
included here. In this case the path to the correct portmacro.h header file
|
* included here. In this case the path to the correct portmacro.h header file
|
||||||
must be set in the compiler's include path. */
|
* must be set in the compiler's include path. */
|
||||||
#ifndef portENTER_CRITICAL
|
#ifndef portENTER_CRITICAL
|
||||||
#include "portmacro.h"
|
#include "portmacro.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if portBYTE_ALIGNMENT == 32
|
#if portBYTE_ALIGNMENT == 32
|
||||||
#define portBYTE_ALIGNMENT_MASK ( 0x001f )
|
#define portBYTE_ALIGNMENT_MASK ( 0x001f )
|
||||||
#endif
|
#elif portBYTE_ALIGNMENT == 16
|
||||||
|
|
||||||
#if portBYTE_ALIGNMENT == 16
|
|
||||||
#define portBYTE_ALIGNMENT_MASK ( 0x000f )
|
#define portBYTE_ALIGNMENT_MASK ( 0x000f )
|
||||||
#endif
|
#elif portBYTE_ALIGNMENT == 8
|
||||||
|
|
||||||
#if portBYTE_ALIGNMENT == 8
|
|
||||||
#define portBYTE_ALIGNMENT_MASK ( 0x0007 )
|
#define portBYTE_ALIGNMENT_MASK ( 0x0007 )
|
||||||
#endif
|
#elif portBYTE_ALIGNMENT == 4
|
||||||
|
|
||||||
#if portBYTE_ALIGNMENT == 4
|
|
||||||
#define portBYTE_ALIGNMENT_MASK ( 0x0003 )
|
#define portBYTE_ALIGNMENT_MASK ( 0x0003 )
|
||||||
#endif
|
#elif portBYTE_ALIGNMENT == 2
|
||||||
|
|
||||||
#if portBYTE_ALIGNMENT == 2
|
|
||||||
#define portBYTE_ALIGNMENT_MASK ( 0x0001 )
|
#define portBYTE_ALIGNMENT_MASK ( 0x0001 )
|
||||||
#endif
|
#elif portBYTE_ALIGNMENT == 1
|
||||||
|
|
||||||
#if portBYTE_ALIGNMENT == 1
|
|
||||||
#define portBYTE_ALIGNMENT_MASK ( 0x0000 )
|
#define portBYTE_ALIGNMENT_MASK ( 0x0000 )
|
||||||
#endif
|
#else /* if portBYTE_ALIGNMENT == 32 */
|
||||||
|
|
||||||
#ifndef portBYTE_ALIGNMENT_MASK
|
|
||||||
#error "Invalid portBYTE_ALIGNMENT definition"
|
#error "Invalid portBYTE_ALIGNMENT definition"
|
||||||
|
#endif /* if portBYTE_ALIGNMENT == 32 */
|
||||||
|
|
||||||
|
#ifndef portUSING_MPU_WRAPPERS
|
||||||
|
#define portUSING_MPU_WRAPPERS 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef portNUM_CONFIGURABLE_REGIONS
|
#ifndef portNUM_CONFIGURABLE_REGIONS
|
||||||
#define portNUM_CONFIGURABLE_REGIONS 1
|
#define portNUM_CONFIGURABLE_REGIONS 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifndef portHAS_STACK_OVERFLOW_CHECKING
|
||||||
extern "C" {
|
#define portHAS_STACK_OVERFLOW_CHECKING 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef portARCH_NAME
|
||||||
|
#define portARCH_NAME NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configSTACK_DEPTH_TYPE
|
||||||
|
#define configSTACK_DEPTH_TYPE StackType_t
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configSTACK_ALLOCATION_FROM_SEPARATE_HEAP
|
||||||
|
/* Defaults to 0 for backward compatibility. */
|
||||||
|
#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "mpu_wrappers.h"
|
#include "mpu_wrappers.h"
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup the stack of a new task so it is ready to be placed under the
|
* Setup the stack of a new task so it is ready to be placed under the
|
||||||
* scheduler control. The registers have to be placed on the stack in
|
* scheduler control. The registers have to be placed on the stack in
|
||||||
* the order that the port expects to find them.
|
* the order that the port expects to find them.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#if( portUSING_MPU_WRAPPERS == 1 )
|
#if ( portUSING_MPU_WRAPPERS == 1 )
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION;
|
#if ( portHAS_STACK_OVERFLOW_CHECKING == 1 )
|
||||||
#else
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION;
|
StackType_t * pxEndOfStack,
|
||||||
#endif
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters,
|
||||||
|
BaseType_t xRunPrivileged,
|
||||||
|
xMPU_SETTINGS * xMPUSettings ) PRIVILEGED_FUNCTION;
|
||||||
|
#else
|
||||||
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters,
|
||||||
|
BaseType_t xRunPrivileged,
|
||||||
|
xMPU_SETTINGS * xMPUSettings ) PRIVILEGED_FUNCTION;
|
||||||
|
#endif /* if ( portHAS_STACK_OVERFLOW_CHECKING == 1 ) */
|
||||||
|
#else /* if ( portUSING_MPU_WRAPPERS == 1 ) */
|
||||||
|
#if ( portHAS_STACK_OVERFLOW_CHECKING == 1 )
|
||||||
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
StackType_t * pxEndOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters ) PRIVILEGED_FUNCTION;
|
||||||
|
#else
|
||||||
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters ) PRIVILEGED_FUNCTION;
|
||||||
|
#endif
|
||||||
|
#endif /* if ( portUSING_MPU_WRAPPERS == 1 ) */
|
||||||
|
|
||||||
/* Used by heap_5.c. */
|
/* Used by heap_5.c to define the start address and size of each memory region
|
||||||
|
* that together comprise the total FreeRTOS heap space. */
|
||||||
typedef struct HeapRegion
|
typedef struct HeapRegion
|
||||||
{
|
{
|
||||||
uint8_t *pucStartAddress;
|
uint8_t * pucStartAddress;
|
||||||
size_t xSizeInBytes;
|
size_t xSizeInBytes;
|
||||||
} HeapRegion_t;
|
} HeapRegion_t;
|
||||||
|
|
||||||
|
/* Used to pass information about the heap out of vPortGetHeapStats(). */
|
||||||
|
typedef struct xHeapStats
|
||||||
|
{
|
||||||
|
size_t xAvailableHeapSpaceInBytes; /* The total heap size currently available - this is the sum of all the free blocks, not the largest block that can be allocated. */
|
||||||
|
size_t xSizeOfLargestFreeBlockInBytes; /* The maximum size, in bytes, of all the free blocks within the heap at the time vPortGetHeapStats() is called. */
|
||||||
|
size_t xSizeOfSmallestFreeBlockInBytes; /* The minimum size, in bytes, of all the free blocks within the heap at the time vPortGetHeapStats() is called. */
|
||||||
|
size_t xNumberOfFreeBlocks; /* The number of free memory blocks within the heap at the time vPortGetHeapStats() is called. */
|
||||||
|
size_t xMinimumEverFreeBytesRemaining; /* The minimum amount of total free memory (sum of all free blocks) there has been in the heap since the system booted. */
|
||||||
|
size_t xNumberOfSuccessfulAllocations; /* The number of calls to pvPortMalloc() that have returned a valid memory block. */
|
||||||
|
size_t xNumberOfSuccessfulFrees; /* The number of calls to vPortFree() that has successfully freed a block of memory. */
|
||||||
|
} HeapStats_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Used to define multiple heap regions for use by heap_5.c. This function
|
* Used to define multiple heap regions for use by heap_5.c. This function
|
||||||
* must be called before any calls to pvPortMalloc() - not creating a task,
|
* must be called before any calls to pvPortMalloc() - not creating a task,
|
||||||
|
@ -164,16 +169,50 @@ typedef struct HeapRegion
|
||||||
*/
|
*/
|
||||||
void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) PRIVILEGED_FUNCTION;
|
void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a HeapStats_t structure filled with information about the current
|
||||||
|
* heap state.
|
||||||
|
*/
|
||||||
|
void vPortGetHeapStats( HeapStats_t * pxHeapStats );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Map to the memory management routines required for the port.
|
* Map to the memory management routines required for the port.
|
||||||
*/
|
*/
|
||||||
void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION;
|
void * pvPortMalloc( size_t xWantedSize ) PRIVILEGED_FUNCTION;
|
||||||
void vPortFree( void *pv ) PRIVILEGED_FUNCTION;
|
void * pvPortCalloc( size_t xNum,
|
||||||
|
size_t xSize ) PRIVILEGED_FUNCTION;
|
||||||
|
void vPortFree( void * pv ) PRIVILEGED_FUNCTION;
|
||||||
void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION;
|
void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION;
|
||||||
size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION;
|
size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION;
|
||||||
size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION;
|
size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
#if ( configSTACK_ALLOCATION_FROM_SEPARATE_HEAP == 1 )
|
||||||
|
void * pvPortMallocStack( size_t xSize ) PRIVILEGED_FUNCTION;
|
||||||
|
void vPortFreeStack( void * pv ) PRIVILEGED_FUNCTION;
|
||||||
|
#else
|
||||||
|
#define pvPortMallocStack pvPortMalloc
|
||||||
|
#define vPortFreeStack vPortFree
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function resets the internal state of the heap module. It must be called
|
||||||
|
* by the application before restarting the scheduler.
|
||||||
|
*/
|
||||||
|
void vPortHeapResetState( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
#if ( configUSE_MALLOC_FAILED_HOOK == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* task.h
|
||||||
|
* @code{c}
|
||||||
|
* void vApplicationMallocFailedHook( void )
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* This hook function is called when allocation failed.
|
||||||
|
*/
|
||||||
|
void vApplicationMallocFailedHook( void );
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup the hardware ready for the scheduler to take control. This generally
|
* Setup the hardware ready for the scheduler to take control. This generally
|
||||||
* sets up a tick interrupt and sets timers for the correct tick frequency.
|
* sets up a tick interrupt and sets timers for the correct tick frequency.
|
||||||
|
@ -194,14 +233,49 @@ void vPortEndScheduler( void ) PRIVILEGED_FUNCTION;
|
||||||
* Fills the xMPUSettings structure with the memory region information
|
* Fills the xMPUSettings structure with the memory region information
|
||||||
* contained in xRegions.
|
* contained in xRegions.
|
||||||
*/
|
*/
|
||||||
#if( portUSING_MPU_WRAPPERS == 1 )
|
#if ( portUSING_MPU_WRAPPERS == 1 )
|
||||||
struct xMEMORY_REGION;
|
struct xMEMORY_REGION;
|
||||||
void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint16_t usStackDepth ) PRIVILEGED_FUNCTION;
|
void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
|
||||||
|
const struct xMEMORY_REGION * const xRegions,
|
||||||
|
StackType_t * pxBottomOfStack,
|
||||||
|
configSTACK_DEPTH_TYPE uxStackDepth ) PRIVILEGED_FUNCTION;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
/**
|
||||||
}
|
* @brief Checks if the calling task is authorized to access the given buffer.
|
||||||
|
*
|
||||||
|
* @param pvBuffer The buffer which the calling task wants to access.
|
||||||
|
* @param ulBufferLength The length of the pvBuffer.
|
||||||
|
* @param ulAccessRequested The permissions that the calling task wants.
|
||||||
|
*
|
||||||
|
* @return pdTRUE if the calling task is authorized to access the buffer,
|
||||||
|
* pdFALSE otherwise.
|
||||||
|
*/
|
||||||
|
#if ( portUSING_MPU_WRAPPERS == 1 )
|
||||||
|
BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer,
|
||||||
|
uint32_t ulBufferLength,
|
||||||
|
uint32_t ulAccessRequested ) PRIVILEGED_FUNCTION;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks if the calling task is authorized to access the given kernel object.
|
||||||
|
*
|
||||||
|
* @param lInternalIndexOfKernelObject The index of the kernel object in the kernel
|
||||||
|
* object handle pool.
|
||||||
|
*
|
||||||
|
* @return pdTRUE if the calling task is authorized to access the kernel object,
|
||||||
|
* pdFALSE otherwise.
|
||||||
|
*/
|
||||||
|
#if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||||
|
|
||||||
|
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
#endif /* PORTABLE_H */
|
#endif /* PORTABLE_H */
|
||||||
|
|
||||||
|
|
|
@ -1,71 +1,30 @@
|
||||||
/*
|
/*
|
||||||
FreeRTOS V8.2.3 - Copyright (C) 2015 Real Time Engineers Ltd.
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
All rights reserved
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
This file is part of the FreeRTOS distribution.
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
* the Software without restriction, including without limitation the rights to
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
***************************************************************************
|
*
|
||||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
* copies or substantial portions of the Software.
|
||||||
>>! obliged to provide the source code for proprietary components !<<
|
*
|
||||||
>>! outside of the FreeRTOS kernel. !<<
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
***************************************************************************
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
link: http://www.freertos.org/a00114.html
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
***************************************************************************
|
* https://github.com/FreeRTOS
|
||||||
* *
|
*
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
*/
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
|
||||||
* platform software that is more than just the market leader, it *
|
|
||||||
* is the industry's de facto standard. *
|
|
||||||
* *
|
|
||||||
* Help yourself get started quickly while simultaneously helping *
|
|
||||||
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
|
||||||
* tutorial book, reference manual, or both: *
|
|
||||||
* http://www.FreeRTOS.org/Documentation *
|
|
||||||
* *
|
|
||||||
***************************************************************************
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
|
||||||
the FAQ page "My application does not run, what could be wrong?". Have you
|
|
||||||
defined configASSERT()?
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
|
||||||
embedded software for free we request you assist our global community by
|
|
||||||
participating in the support forum.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
|
||||||
be as productive as possible as early as possible. Now you can receive
|
|
||||||
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
|
||||||
Ltd, and the world's leading authority on the world's leading RTOS.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
|
||||||
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
|
||||||
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and commercial middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PROJDEFS_H
|
#ifndef PROJDEFS_H
|
||||||
#define PROJDEFS_H
|
#define PROJDEFS_H
|
||||||
|
@ -74,13 +33,28 @@
|
||||||
* Defines the prototype to which task functions must conform. Defined in this
|
* Defines the prototype to which task functions must conform. Defined in this
|
||||||
* file to ensure the type is known before portable.h is included.
|
* file to ensure the type is known before portable.h is included.
|
||||||
*/
|
*/
|
||||||
typedef void (*TaskFunction_t)( void * );
|
typedef void (* TaskFunction_t)( void * arg );
|
||||||
|
|
||||||
/* Converts a time in milliseconds to a time in ticks. */
|
/* Converts a time in milliseconds to a time in ticks. This macro can be
|
||||||
#define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) ( ( ( TickType_t ) ( xTimeInMs ) * ( TickType_t ) configTICK_RATE_HZ ) / ( TickType_t ) 1000 ) )
|
* overridden by a macro of the same name defined in FreeRTOSConfig.h in case the
|
||||||
|
* definition here is not suitable for your application. */
|
||||||
|
#ifndef pdMS_TO_TICKS
|
||||||
|
#define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) ( ( ( uint64_t ) ( xTimeInMs ) * ( uint64_t ) configTICK_RATE_HZ ) / ( uint64_t ) 1000U ) )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Converts a time in ticks to a time in milliseconds. This macro can be
|
||||||
|
* overridden by a macro of the same name defined in FreeRTOSConfig.h in case the
|
||||||
|
* definition here is not suitable for your application. */
|
||||||
|
#ifndef pdTICKS_TO_MS
|
||||||
|
#define pdTICKS_TO_MS( xTimeInTicks ) ( ( TickType_t ) ( ( ( uint64_t ) ( xTimeInTicks ) * ( uint64_t ) 1000U ) / ( uint64_t ) configTICK_RATE_HZ ) )
|
||||||
|
#endif
|
||||||
|
|
||||||
#define pdFALSE ( ( BaseType_t ) 0 )
|
#define pdFALSE ( ( BaseType_t ) 0 )
|
||||||
#define pdTRUE ( ( BaseType_t ) 1 )
|
#define pdTRUE ( ( BaseType_t ) 1 )
|
||||||
|
#define pdFALSE_SIGNED ( ( BaseType_t ) 0 )
|
||||||
|
#define pdTRUE_SIGNED ( ( BaseType_t ) 1 )
|
||||||
|
#define pdFALSE_UNSIGNED ( ( UBaseType_t ) 0 )
|
||||||
|
#define pdTRUE_UNSIGNED ( ( UBaseType_t ) 1 )
|
||||||
|
|
||||||
#define pdPASS ( pdTRUE )
|
#define pdPASS ( pdTRUE )
|
||||||
#define pdFAIL ( pdFALSE )
|
#define pdFAIL ( pdFALSE )
|
||||||
|
@ -97,16 +71,21 @@ typedef void (*TaskFunction_t)( void * );
|
||||||
#define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0
|
#define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if( configUSE_16_BIT_TICKS == 1 )
|
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||||
#define pdINTEGRITY_CHECK_VALUE 0x5a5a
|
#define pdINTEGRITY_CHECK_VALUE 0x5a5a
|
||||||
#else
|
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||||
#define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5aUL
|
#define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5aUL
|
||||||
|
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_64_BITS )
|
||||||
|
#define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5a5a5a5a5aULL
|
||||||
|
#else
|
||||||
|
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The following errno values are used by FreeRTOS+ components, not FreeRTOS
|
/* The following errno values are used by FreeRTOS+ components, not FreeRTOS
|
||||||
itself. */
|
* itself. */
|
||||||
#define pdFREERTOS_ERRNO_NONE 0 /* No errors */
|
#define pdFREERTOS_ERRNO_NONE 0 /* No errors */
|
||||||
#define pdFREERTOS_ERRNO_ENOENT 2 /* No such file or directory */
|
#define pdFREERTOS_ERRNO_ENOENT 2 /* No such file or directory */
|
||||||
|
#define pdFREERTOS_ERRNO_EINTR 4 /* Interrupted system call */
|
||||||
#define pdFREERTOS_ERRNO_EIO 5 /* I/O error */
|
#define pdFREERTOS_ERRNO_EIO 5 /* I/O error */
|
||||||
#define pdFREERTOS_ERRNO_ENXIO 6 /* No such device or address */
|
#define pdFREERTOS_ERRNO_ENXIO 6 /* No such device or address */
|
||||||
#define pdFREERTOS_ERRNO_EBADF 9 /* Bad file number */
|
#define pdFREERTOS_ERRNO_EBADF 9 /* Bad file number */
|
||||||
|
@ -132,6 +111,7 @@ itself. */
|
||||||
#define pdFREERTOS_ERRNO_ENOTEMPTY 90 /* Directory not empty */
|
#define pdFREERTOS_ERRNO_ENOTEMPTY 90 /* Directory not empty */
|
||||||
#define pdFREERTOS_ERRNO_ENAMETOOLONG 91 /* File or path name too long */
|
#define pdFREERTOS_ERRNO_ENAMETOOLONG 91 /* File or path name too long */
|
||||||
#define pdFREERTOS_ERRNO_EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
|
#define pdFREERTOS_ERRNO_EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
|
||||||
|
#define pdFREERTOS_ERRNO_EAFNOSUPPORT 97 /* Address family not supported by protocol */
|
||||||
#define pdFREERTOS_ERRNO_ENOBUFS 105 /* No buffer space available */
|
#define pdFREERTOS_ERRNO_ENOBUFS 105 /* No buffer space available */
|
||||||
#define pdFREERTOS_ERRNO_ENOPROTOOPT 109 /* Protocol not available */
|
#define pdFREERTOS_ERRNO_ENOPROTOOPT 109 /* Protocol not available */
|
||||||
#define pdFREERTOS_ERRNO_EADDRINUSE 112 /* Address already in use */
|
#define pdFREERTOS_ERRNO_EADDRINUSE 112 /* Address already in use */
|
||||||
|
@ -146,11 +126,13 @@ itself. */
|
||||||
#define pdFREERTOS_ERRNO_ECANCELED 140 /* Operation canceled. */
|
#define pdFREERTOS_ERRNO_ECANCELED 140 /* Operation canceled. */
|
||||||
|
|
||||||
/* The following endian values are used by FreeRTOS+ components, not FreeRTOS
|
/* The following endian values are used by FreeRTOS+ components, not FreeRTOS
|
||||||
itself. */
|
* itself. */
|
||||||
#define pdFREERTOS_LITTLE_ENDIAN 0
|
#define pdFREERTOS_LITTLE_ENDIAN 0
|
||||||
#define pdFREERTOS_BIG_ENDIAN 1
|
#define pdFREERTOS_BIG_ENDIAN 1
|
||||||
|
|
||||||
|
/* Re-defining endian values for generic naming. */
|
||||||
|
#define pdLITTLE_ENDIAN pdFREERTOS_LITTLE_ENDIAN
|
||||||
|
#define pdBIG_ENDIAN pdFREERTOS_BIG_ENDIAN
|
||||||
|
|
||||||
|
|
||||||
#endif /* PROJDEFS_H */
|
#endif /* PROJDEFS_H */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,141 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef STACK_MACROS_H
|
||||||
|
#define STACK_MACROS_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call the stack overflow hook function if the stack of the task being swapped
|
||||||
|
* out is currently overflowed, or looks like it might have overflowed in the
|
||||||
|
* past.
|
||||||
|
*
|
||||||
|
* Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check
|
||||||
|
* the current stack state only - comparing the current top of stack value to
|
||||||
|
* the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1
|
||||||
|
* will also cause the last few stack bytes to be checked to ensure the value
|
||||||
|
* to which the bytes were set when the task was created have not been
|
||||||
|
* overwritten. Note this second test does not guarantee that an overflowed
|
||||||
|
* stack will always be recognised.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* portSTACK_LIMIT_PADDING is a number of extra words to consider to be in
|
||||||
|
* use on the stack.
|
||||||
|
*/
|
||||||
|
#ifndef portSTACK_LIMIT_PADDING
|
||||||
|
#define portSTACK_LIMIT_PADDING 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) )
|
||||||
|
|
||||||
|
/* Only the current stack state is to be checked. */
|
||||||
|
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||||
|
do { \
|
||||||
|
/* Is the currently saved stack pointer within the stack limit? */ \
|
||||||
|
if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack + portSTACK_LIMIT_PADDING ) \
|
||||||
|
{ \
|
||||||
|
char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \
|
||||||
|
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \
|
||||||
|
} \
|
||||||
|
} while( 0 )
|
||||||
|
|
||||||
|
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) )
|
||||||
|
|
||||||
|
/* Only the current stack state is to be checked. */
|
||||||
|
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||||
|
do { \
|
||||||
|
\
|
||||||
|
/* Is the currently saved stack pointer within the stack limit? */ \
|
||||||
|
if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack - portSTACK_LIMIT_PADDING ) \
|
||||||
|
{ \
|
||||||
|
char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \
|
||||||
|
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \
|
||||||
|
} \
|
||||||
|
} while( 0 )
|
||||||
|
|
||||||
|
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) )
|
||||||
|
|
||||||
|
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||||
|
do { \
|
||||||
|
const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \
|
||||||
|
const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5U; \
|
||||||
|
\
|
||||||
|
if( ( pulStack[ 0 ] != ulCheckValue ) || \
|
||||||
|
( pulStack[ 1 ] != ulCheckValue ) || \
|
||||||
|
( pulStack[ 2 ] != ulCheckValue ) || \
|
||||||
|
( pulStack[ 3 ] != ulCheckValue ) ) \
|
||||||
|
{ \
|
||||||
|
char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \
|
||||||
|
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \
|
||||||
|
} \
|
||||||
|
} while( 0 )
|
||||||
|
|
||||||
|
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) )
|
||||||
|
|
||||||
|
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||||
|
do { \
|
||||||
|
int8_t * pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \
|
||||||
|
static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||||
|
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||||
|
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||||
|
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||||
|
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \
|
||||||
|
\
|
||||||
|
\
|
||||||
|
pcEndOfStack -= sizeof( ucExpectedStackBytes ); \
|
||||||
|
\
|
||||||
|
/* Has the extremity of the task stack ever been written over? */ \
|
||||||
|
if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \
|
||||||
|
{ \
|
||||||
|
char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \
|
||||||
|
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \
|
||||||
|
} \
|
||||||
|
} while( 0 )
|
||||||
|
|
||||||
|
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Remove stack overflow macro if not being used. */
|
||||||
|
#ifndef taskCHECK_FOR_STACK_OVERFLOW
|
||||||
|
#define taskCHECK_FOR_STACK_OVERFLOW()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* STACK_MACROS_H */
|
|
@ -1,3 +1,30 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef FREERTOS_STDINT
|
#ifndef FREERTOS_STDINT
|
||||||
#define FREERTOS_STDINT
|
#define FREERTOS_STDINT
|
||||||
|
@ -10,7 +37,7 @@
|
||||||
* To use this file:
|
* To use this file:
|
||||||
*
|
*
|
||||||
* 1) Copy this file into the directory that contains your FreeRTOSConfig.h
|
* 1) Copy this file into the directory that contains your FreeRTOSConfig.h
|
||||||
* header file, as that directory will already be in the compilers include
|
* header file, as that directory will already be in the compiler's include
|
||||||
* path.
|
* path.
|
||||||
*
|
*
|
||||||
* 2) Rename the copied file stdint.h.
|
* 2) Rename the copied file stdint.h.
|
||||||
|
@ -24,4 +51,8 @@ typedef unsigned short uint16_t;
|
||||||
typedef long int32_t;
|
typedef long int32_t;
|
||||||
typedef unsigned long uint32_t;
|
typedef unsigned long uint32_t;
|
||||||
|
|
||||||
|
#ifndef SIZE_MAX
|
||||||
|
#define SIZE_MAX ( ( size_t ) -1 )
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* FREERTOS_STDINT */
|
#endif /* FREERTOS_STDINT */
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,71 +1,30 @@
|
||||||
/*
|
/*
|
||||||
FreeRTOS V8.2.3 - Copyright (C) 2015 Real Time Engineers Ltd.
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
All rights reserved
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
This file is part of the FreeRTOS distribution.
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
* the Software without restriction, including without limitation the rights to
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
***************************************************************************
|
*
|
||||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
* copies or substantial portions of the Software.
|
||||||
>>! obliged to provide the source code for proprietary components !<<
|
*
|
||||||
>>! outside of the FreeRTOS kernel. !<<
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
***************************************************************************
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
link: http://www.freertos.org/a00114.html
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
***************************************************************************
|
* https://github.com/FreeRTOS
|
||||||
* *
|
*
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
*/
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
|
||||||
* platform software that is more than just the market leader, it *
|
|
||||||
* is the industry's de facto standard. *
|
|
||||||
* *
|
|
||||||
* Help yourself get started quickly while simultaneously helping *
|
|
||||||
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
|
||||||
* tutorial book, reference manual, or both: *
|
|
||||||
* http://www.FreeRTOS.org/Documentation *
|
|
||||||
* *
|
|
||||||
***************************************************************************
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
|
||||||
the FAQ page "My application does not run, what could be wrong?". Have you
|
|
||||||
defined configASSERT()?
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
|
||||||
embedded software for free we request you assist our global community by
|
|
||||||
participating in the support forum.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
|
||||||
be as productive as possible as early as possible. Now you can receive
|
|
||||||
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
|
||||||
Ltd, and the world's leading authority on the world's leading RTOS.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
|
||||||
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
|
||||||
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and commercial middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef TIMERS_H
|
#ifndef TIMERS_H
|
||||||
|
@ -75,24 +34,24 @@
|
||||||
#error "include FreeRTOS.h must appear in source files before include timers.h"
|
#error "include FreeRTOS.h must appear in source files before include timers.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*lint -e537 This headers are only multiply included if the application code
|
|
||||||
happens to also be including task.h. */
|
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
/*lint +e537 */
|
|
||||||
|
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* MACROS AND DEFINITIONS
|
* MACROS AND DEFINITIONS
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/* IDs for commands that can be sent/received on the timer queue. These are to
|
/* IDs for commands that can be sent/received on the timer queue. These are to
|
||||||
be used solely through the macros that make up the public software timer API,
|
* be used solely through the macros that make up the public software timer API,
|
||||||
as defined below. The commands that are sent from interrupts must use the
|
* as defined below. The commands that are sent from interrupts must use the
|
||||||
highest numbers as tmrFIRST_FROM_ISR_COMMAND is used to determine if the task
|
* highest numbers as tmrFIRST_FROM_ISR_COMMAND is used to determine if the task
|
||||||
or interrupt version of the queue send function should be used. */
|
* or interrupt version of the queue send function should be used. */
|
||||||
#define tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR ( ( BaseType_t ) -2 )
|
#define tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR ( ( BaseType_t ) -2 )
|
||||||
#define tmrCOMMAND_EXECUTE_CALLBACK ( ( BaseType_t ) -1 )
|
#define tmrCOMMAND_EXECUTE_CALLBACK ( ( BaseType_t ) -1 )
|
||||||
#define tmrCOMMAND_START_DONT_TRACE ( ( BaseType_t ) 0 )
|
#define tmrCOMMAND_START_DONT_TRACE ( ( BaseType_t ) 0 )
|
||||||
|
@ -115,29 +74,39 @@ or interrupt version of the queue send function should be used. */
|
||||||
* reference the subject timer in calls to other software timer API functions
|
* reference the subject timer in calls to other software timer API functions
|
||||||
* (for example, xTimerStart(), xTimerReset(), etc.).
|
* (for example, xTimerStart(), xTimerReset(), etc.).
|
||||||
*/
|
*/
|
||||||
typedef void * TimerHandle_t;
|
struct tmrTimerControl; /* The old naming convention is used to prevent breaking kernel aware debuggers. */
|
||||||
|
typedef struct tmrTimerControl * TimerHandle_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Defines the prototype to which timer callback functions must conform.
|
* Defines the prototype to which timer callback functions must conform.
|
||||||
*/
|
*/
|
||||||
typedef void (*TimerCallbackFunction_t)( TimerHandle_t xTimer );
|
typedef void (* TimerCallbackFunction_t)( TimerHandle_t xTimer );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Defines the prototype to which functions used with the
|
* Defines the prototype to which functions used with the
|
||||||
* xTimerPendFunctionCallFromISR() function must conform.
|
* xTimerPendFunctionCallFromISR() function must conform.
|
||||||
*/
|
*/
|
||||||
typedef void (*PendedFunction_t)( void *, uint32_t );
|
typedef void (* PendedFunction_t)( void * arg1,
|
||||||
|
uint32_t arg2 );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TimerHandle_t xTimerCreate( const char * const pcTimerName,
|
* TimerHandle_t xTimerCreate( const char * const pcTimerName,
|
||||||
* TickType_t xTimerPeriodInTicks,
|
* TickType_t xTimerPeriodInTicks,
|
||||||
* UBaseType_t uxAutoReload,
|
* BaseType_t xAutoReload,
|
||||||
* void * pvTimerID,
|
* void * pvTimerID,
|
||||||
* TimerCallbackFunction_t pxCallbackFunction );
|
* TimerCallbackFunction_t pxCallbackFunction );
|
||||||
*
|
*
|
||||||
* Creates a new software timer instance. This allocates the storage required
|
* Creates a new software timer instance, and returns a handle by which the
|
||||||
* by the new timer, initialises the new timers internal state, and returns a
|
* created software timer can be referenced.
|
||||||
* handle by which the new timer can be referenced.
|
*
|
||||||
|
* Internally, within the FreeRTOS implementation, software timers use a block
|
||||||
|
* of memory, in which the timer data structure is stored. If a software timer
|
||||||
|
* is created using xTimerCreate() then the required memory is automatically
|
||||||
|
* dynamically allocated inside the xTimerCreate() function. (see
|
||||||
|
* https://www.FreeRTOS.org/a00111.html). If a software timer is created using
|
||||||
|
* xTimerCreateStatic() then the application writer must provide the memory that
|
||||||
|
* will get used by the software timer. xTimerCreateStatic() therefore allows a
|
||||||
|
* software timer to be created without using any dynamic memory allocation.
|
||||||
*
|
*
|
||||||
* Timers are created in the dormant state. The xTimerStart(), xTimerReset(),
|
* Timers are created in the dormant state. The xTimerStart(), xTimerReset(),
|
||||||
* xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and
|
* xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and
|
||||||
|
@ -154,11 +123,11 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
|
||||||
* after 100 ticks, then xTimerPeriodInTicks should be set to 100.
|
* after 100 ticks, then xTimerPeriodInTicks should be set to 100.
|
||||||
* Alternatively, if the timer must expire after 500ms, then xPeriod can be set
|
* Alternatively, if the timer must expire after 500ms, then xPeriod can be set
|
||||||
* to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than or
|
* to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than or
|
||||||
* equal to 1000.
|
* equal to 1000. Time timer period must be greater than 0.
|
||||||
*
|
*
|
||||||
* @param uxAutoReload If uxAutoReload is set to pdTRUE then the timer will
|
* @param xAutoReload If xAutoReload is set to pdTRUE then the timer will
|
||||||
* expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter.
|
* expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter.
|
||||||
* If uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and
|
* If xAutoReload is set to pdFALSE then the timer will be a one-shot timer and
|
||||||
* enter the dormant state after it expires.
|
* enter the dormant state after it expires.
|
||||||
*
|
*
|
||||||
* @param pvTimerID An identifier that is assigned to the timer being created.
|
* @param pvTimerID An identifier that is assigned to the timer being created.
|
||||||
|
@ -171,9 +140,9 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
|
||||||
* which is "void vCallbackFunction( TimerHandle_t xTimer );".
|
* which is "void vCallbackFunction( TimerHandle_t xTimer );".
|
||||||
*
|
*
|
||||||
* @return If the timer is successfully created then a handle to the newly
|
* @return If the timer is successfully created then a handle to the newly
|
||||||
* created timer is returned. If the timer cannot be created (because either
|
* created timer is returned. If the timer cannot be created because there is
|
||||||
* there is insufficient FreeRTOS heap remaining to allocate the timer
|
* insufficient FreeRTOS heap remaining to allocate the timer
|
||||||
* structures, or the timer period was set to 0) then NULL is returned.
|
* structures then NULL is returned.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
* @verbatim
|
* @verbatim
|
||||||
|
@ -222,7 +191,7 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
|
||||||
* for( x = 0; x < NUM_TIMERS; x++ )
|
* for( x = 0; x < NUM_TIMERS; x++ )
|
||||||
* {
|
* {
|
||||||
* xTimers[ x ] = xTimerCreate( "Timer", // Just a text name, not used by the kernel.
|
* xTimers[ x ] = xTimerCreate( "Timer", // Just a text name, not used by the kernel.
|
||||||
* ( 100 * x ), // The timer period in ticks.
|
* ( 100 * ( x + 1 ) ), // The timer period in ticks.
|
||||||
* pdTRUE, // The timers will auto-reload themselves when they expire.
|
* pdTRUE, // The timers will auto-reload themselves when they expire.
|
||||||
* ( void * ) x, // Assign each timer a unique id equal to its array index.
|
* ( void * ) x, // Assign each timer a unique id equal to its array index.
|
||||||
* vTimerCallback // Each timer calls the same callback when it expires.
|
* vTimerCallback // Each timer calls the same callback when it expires.
|
||||||
|
@ -250,14 +219,151 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
|
||||||
*
|
*
|
||||||
* // Starting the scheduler will start the timers running as they have already
|
* // Starting the scheduler will start the timers running as they have already
|
||||||
* // been set into the active state.
|
* // been set into the active state.
|
||||||
* xTaskStartScheduler();
|
* vTaskStartScheduler();
|
||||||
*
|
*
|
||||||
* // Should not reach here.
|
* // Should not reach here.
|
||||||
* for( ;; );
|
* for( ;; );
|
||||||
* }
|
* }
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
TimerHandle_t xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||||
|
TimerHandle_t xTimerCreate( const char * const pcTimerName,
|
||||||
|
const TickType_t xTimerPeriodInTicks,
|
||||||
|
const BaseType_t xAutoReload,
|
||||||
|
void * const pvTimerID,
|
||||||
|
TimerCallbackFunction_t pxCallbackFunction ) PRIVILEGED_FUNCTION;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TimerHandle_t xTimerCreateStatic(const char * const pcTimerName,
|
||||||
|
* TickType_t xTimerPeriodInTicks,
|
||||||
|
* BaseType_t xAutoReload,
|
||||||
|
* void * pvTimerID,
|
||||||
|
* TimerCallbackFunction_t pxCallbackFunction,
|
||||||
|
* StaticTimer_t *pxTimerBuffer );
|
||||||
|
*
|
||||||
|
* Creates a new software timer instance, and returns a handle by which the
|
||||||
|
* created software timer can be referenced.
|
||||||
|
*
|
||||||
|
* Internally, within the FreeRTOS implementation, software timers use a block
|
||||||
|
* of memory, in which the timer data structure is stored. If a software timer
|
||||||
|
* is created using xTimerCreate() then the required memory is automatically
|
||||||
|
* dynamically allocated inside the xTimerCreate() function. (see
|
||||||
|
* https://www.FreeRTOS.org/a00111.html). If a software timer is created using
|
||||||
|
* xTimerCreateStatic() then the application writer must provide the memory that
|
||||||
|
* will get used by the software timer. xTimerCreateStatic() therefore allows a
|
||||||
|
* software timer to be created without using any dynamic memory allocation.
|
||||||
|
*
|
||||||
|
* Timers are created in the dormant state. The xTimerStart(), xTimerReset(),
|
||||||
|
* xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and
|
||||||
|
* xTimerChangePeriodFromISR() API functions can all be used to transition a
|
||||||
|
* timer into the active state.
|
||||||
|
*
|
||||||
|
* @param pcTimerName A text name that is assigned to the timer. This is done
|
||||||
|
* purely to assist debugging. The kernel itself only ever references a timer
|
||||||
|
* by its handle, and never by its name.
|
||||||
|
*
|
||||||
|
* @param xTimerPeriodInTicks The timer period. The time is defined in tick
|
||||||
|
* periods so the constant portTICK_PERIOD_MS can be used to convert a time that
|
||||||
|
* has been specified in milliseconds. For example, if the timer must expire
|
||||||
|
* after 100 ticks, then xTimerPeriodInTicks should be set to 100.
|
||||||
|
* Alternatively, if the timer must expire after 500ms, then xPeriod can be set
|
||||||
|
* to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than or
|
||||||
|
* equal to 1000. The timer period must be greater than 0.
|
||||||
|
*
|
||||||
|
* @param xAutoReload If xAutoReload is set to pdTRUE then the timer will
|
||||||
|
* expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter.
|
||||||
|
* If xAutoReload is set to pdFALSE then the timer will be a one-shot timer and
|
||||||
|
* enter the dormant state after it expires.
|
||||||
|
*
|
||||||
|
* @param pvTimerID An identifier that is assigned to the timer being created.
|
||||||
|
* Typically this would be used in the timer callback function to identify which
|
||||||
|
* timer expired when the same callback function is assigned to more than one
|
||||||
|
* timer.
|
||||||
|
*
|
||||||
|
* @param pxCallbackFunction The function to call when the timer expires.
|
||||||
|
* Callback functions must have the prototype defined by TimerCallbackFunction_t,
|
||||||
|
* which is "void vCallbackFunction( TimerHandle_t xTimer );".
|
||||||
|
*
|
||||||
|
* @param pxTimerBuffer Must point to a variable of type StaticTimer_t, which
|
||||||
|
* will be then be used to hold the software timer's data structures, removing
|
||||||
|
* the need for the memory to be allocated dynamically.
|
||||||
|
*
|
||||||
|
* @return If the timer is created then a handle to the created timer is
|
||||||
|
* returned. If pxTimerBuffer was NULL then NULL is returned.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
* @verbatim
|
||||||
|
*
|
||||||
|
* // The buffer used to hold the software timer's data structure.
|
||||||
|
* static StaticTimer_t xTimerBuffer;
|
||||||
|
*
|
||||||
|
* // A variable that will be incremented by the software timer's callback
|
||||||
|
* // function.
|
||||||
|
* UBaseType_t uxVariableToIncrement = 0;
|
||||||
|
*
|
||||||
|
* // A software timer callback function that increments a variable passed to
|
||||||
|
* // it when the software timer was created. After the 5th increment the
|
||||||
|
* // callback function stops the software timer.
|
||||||
|
* static void prvTimerCallback( TimerHandle_t xExpiredTimer )
|
||||||
|
* {
|
||||||
|
* UBaseType_t *puxVariableToIncrement;
|
||||||
|
* BaseType_t xReturned;
|
||||||
|
*
|
||||||
|
* // Obtain the address of the variable to increment from the timer ID.
|
||||||
|
* puxVariableToIncrement = ( UBaseType_t * ) pvTimerGetTimerID( xExpiredTimer );
|
||||||
|
*
|
||||||
|
* // Increment the variable to show the timer callback has executed.
|
||||||
|
* ( *puxVariableToIncrement )++;
|
||||||
|
*
|
||||||
|
* // If this callback has executed the required number of times, stop the
|
||||||
|
* // timer.
|
||||||
|
* if( *puxVariableToIncrement == 5 )
|
||||||
|
* {
|
||||||
|
* // This is called from a timer callback so must not block.
|
||||||
|
* xTimerStop( xExpiredTimer, staticDONT_BLOCK );
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* void main( void )
|
||||||
|
* {
|
||||||
|
* // Create the software time. xTimerCreateStatic() has an extra parameter
|
||||||
|
* // than the normal xTimerCreate() API function. The parameter is a pointer
|
||||||
|
* // to the StaticTimer_t structure that will hold the software timer
|
||||||
|
* // structure. If the parameter is passed as NULL then the structure will be
|
||||||
|
* // allocated dynamically, just as if xTimerCreate() had been called.
|
||||||
|
* xTimer = xTimerCreateStatic( "T1", // Text name for the task. Helps debugging only. Not used by FreeRTOS.
|
||||||
|
* xTimerPeriod, // The period of the timer in ticks.
|
||||||
|
* pdTRUE, // This is an auto-reload timer.
|
||||||
|
* ( void * ) &uxVariableToIncrement, // A variable incremented by the software timer's callback function
|
||||||
|
* prvTimerCallback, // The function to execute when the timer expires.
|
||||||
|
* &xTimerBuffer ); // The buffer that will hold the software timer structure.
|
||||||
|
*
|
||||||
|
* // The scheduler has not started yet so a block time is not used.
|
||||||
|
* xReturned = xTimerStart( xTimer, 0 );
|
||||||
|
*
|
||||||
|
* // ...
|
||||||
|
* // Create tasks here.
|
||||||
|
* // ...
|
||||||
|
*
|
||||||
|
* // Starting the scheduler will start the timers running as they have already
|
||||||
|
* // been set into the active state.
|
||||||
|
* vTaskStartScheduler();
|
||||||
|
*
|
||||||
|
* // Should not reach here.
|
||||||
|
* for( ;; );
|
||||||
|
* }
|
||||||
|
* @endverbatim
|
||||||
|
*/
|
||||||
|
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
|
TimerHandle_t xTimerCreateStatic( const char * const pcTimerName,
|
||||||
|
const TickType_t xTimerPeriodInTicks,
|
||||||
|
const BaseType_t xAutoReload,
|
||||||
|
void * const pvTimerID,
|
||||||
|
TimerCallbackFunction_t pxCallbackFunction,
|
||||||
|
StaticTimer_t * pxTimerBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* void *pvTimerGetTimerID( TimerHandle_t xTimer );
|
* void *pvTimerGetTimerID( TimerHandle_t xTimer );
|
||||||
|
@ -279,7 +385,7 @@ TimerHandle_t xTimerCreate( const char * const pcTimerName, const TickType_t xTi
|
||||||
*
|
*
|
||||||
* See the xTimerCreate() API function example usage scenario.
|
* See the xTimerCreate() API function example usage scenario.
|
||||||
*/
|
*/
|
||||||
void *pvTimerGetTimerID( const TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
|
void * pvTimerGetTimerID( const TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID );
|
* void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID );
|
||||||
|
@ -300,7 +406,8 @@ void *pvTimerGetTimerID( const TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
|
||||||
*
|
*
|
||||||
* See the xTimerCreate() API function example usage scenario.
|
* See the xTimerCreate() API function example usage scenario.
|
||||||
*/
|
*/
|
||||||
void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) PRIVILEGED_FUNCTION;
|
void vTimerSetTimerID( TimerHandle_t xTimer,
|
||||||
|
void * pvNewID ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer );
|
* BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer );
|
||||||
|
@ -342,9 +449,6 @@ BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
|
||||||
/**
|
/**
|
||||||
* TaskHandle_t xTimerGetTimerDaemonTaskHandle( void );
|
* TaskHandle_t xTimerGetTimerDaemonTaskHandle( void );
|
||||||
*
|
*
|
||||||
* xTimerGetTimerDaemonTaskHandle() is only available if
|
|
||||||
* INCLUDE_xTimerGetTimerDaemonTaskHandle is set to 1 in FreeRTOSConfig.h.
|
|
||||||
*
|
|
||||||
* Simply returns the handle of the timer service/daemon task. It it not valid
|
* Simply returns the handle of the timer service/daemon task. It it not valid
|
||||||
* to call xTimerGetTimerDaemonTaskHandle() before the scheduler has been started.
|
* to call xTimerGetTimerDaemonTaskHandle() before the scheduler has been started.
|
||||||
*/
|
*/
|
||||||
|
@ -400,7 +504,8 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;
|
||||||
* See the xTimerCreate() API function example usage scenario.
|
* See the xTimerCreate() API function example usage scenario.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#define xTimerStart( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) )
|
#define xTimerStart( xTimer, xTicksToWait ) \
|
||||||
|
xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BaseType_t xTimerStop( TimerHandle_t xTimer, TickType_t xTicksToWait );
|
* BaseType_t xTimerStop( TimerHandle_t xTimer, TickType_t xTicksToWait );
|
||||||
|
@ -442,7 +547,8 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;
|
||||||
* See the xTimerCreate() API function example usage scenario.
|
* See the xTimerCreate() API function example usage scenario.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#define xTimerStop( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0U, NULL, ( xTicksToWait ) )
|
#define xTimerStop( xTimer, xTicksToWait ) \
|
||||||
|
xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0U, NULL, ( xTicksToWait ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BaseType_t xTimerChangePeriod( TimerHandle_t xTimer,
|
* BaseType_t xTimerChangePeriod( TimerHandle_t xTimer,
|
||||||
|
@ -522,7 +628,8 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;
|
||||||
* }
|
* }
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
#define xTimerChangePeriod( xTimer, xNewPeriod, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), NULL, ( xTicksToWait ) )
|
#define xTimerChangePeriod( xTimer, xNewPeriod, xTicksToWait ) \
|
||||||
|
xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), NULL, ( xTicksToWait ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BaseType_t xTimerDelete( TimerHandle_t xTimer, TickType_t xTicksToWait );
|
* BaseType_t xTimerDelete( TimerHandle_t xTimer, TickType_t xTicksToWait );
|
||||||
|
@ -560,7 +667,8 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;
|
||||||
*
|
*
|
||||||
* See the xTimerChangePeriod() API function example usage scenario.
|
* See the xTimerChangePeriod() API function example usage scenario.
|
||||||
*/
|
*/
|
||||||
#define xTimerDelete( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_DELETE, 0U, NULL, ( xTicksToWait ) )
|
#define xTimerDelete( xTimer, xTicksToWait ) \
|
||||||
|
xTimerGenericCommand( ( xTimer ), tmrCOMMAND_DELETE, 0U, NULL, ( xTicksToWait ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xTicksToWait );
|
* BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xTicksToWait );
|
||||||
|
@ -677,14 +785,15 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;
|
||||||
*
|
*
|
||||||
* // Starting the scheduler will start the timer running as it has already
|
* // Starting the scheduler will start the timer running as it has already
|
||||||
* // been set into the active state.
|
* // been set into the active state.
|
||||||
* xTaskStartScheduler();
|
* vTaskStartScheduler();
|
||||||
*
|
*
|
||||||
* // Should not reach here.
|
* // Should not reach here.
|
||||||
* for( ;; );
|
* for( ;; );
|
||||||
* }
|
* }
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
#define xTimerReset( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) )
|
#define xTimerReset( xTimer, xTicksToWait ) \
|
||||||
|
xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BaseType_t xTimerStartFromISR( TimerHandle_t xTimer,
|
* BaseType_t xTimerStartFromISR( TimerHandle_t xTimer,
|
||||||
|
@ -770,7 +879,8 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;
|
||||||
* }
|
* }
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
#define xTimerStartFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U )
|
#define xTimerStartFromISR( xTimer, pxHigherPriorityTaskWoken ) \
|
||||||
|
xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BaseType_t xTimerStopFromISR( TimerHandle_t xTimer,
|
* BaseType_t xTimerStopFromISR( TimerHandle_t xTimer,
|
||||||
|
@ -833,7 +943,8 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;
|
||||||
* }
|
* }
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
#define xTimerStopFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP_FROM_ISR, 0, ( pxHigherPriorityTaskWoken ), 0U )
|
#define xTimerStopFromISR( xTimer, pxHigherPriorityTaskWoken ) \
|
||||||
|
xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP_FROM_ISR, 0, ( pxHigherPriorityTaskWoken ), 0U )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BaseType_t xTimerChangePeriodFromISR( TimerHandle_t xTimer,
|
* BaseType_t xTimerChangePeriodFromISR( TimerHandle_t xTimer,
|
||||||
|
@ -906,7 +1017,8 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;
|
||||||
* }
|
* }
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
#define xTimerChangePeriodFromISR( xTimer, xNewPeriod, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD_FROM_ISR, ( xNewPeriod ), ( pxHigherPriorityTaskWoken ), 0U )
|
#define xTimerChangePeriodFromISR( xTimer, xNewPeriod, pxHigherPriorityTaskWoken ) \
|
||||||
|
xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD_FROM_ISR, ( xNewPeriod ), ( pxHigherPriorityTaskWoken ), 0U )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BaseType_t xTimerResetFromISR( TimerHandle_t xTimer,
|
* BaseType_t xTimerResetFromISR( TimerHandle_t xTimer,
|
||||||
|
@ -992,7 +1104,8 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;
|
||||||
* }
|
* }
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
#define xTimerResetFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U )
|
#define xTimerResetFromISR( xTimer, pxHigherPriorityTaskWoken ) \
|
||||||
|
xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U )
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1083,9 +1196,14 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;
|
||||||
* }
|
* }
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
#if ( INCLUDE_xTimerPendFunctionCall == 1 )
|
||||||
|
BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend,
|
||||||
|
void * pvParameter1,
|
||||||
|
uint32_t ulParameter2,
|
||||||
|
BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend,
|
* BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend,
|
||||||
* void *pvParameter1,
|
* void *pvParameter1,
|
||||||
* uint32_t ulParameter2,
|
* uint32_t ulParameter2,
|
||||||
|
@ -1117,10 +1235,15 @@ BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void
|
||||||
* timer daemon task, otherwise pdFALSE is returned.
|
* timer daemon task, otherwise pdFALSE is returned.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
#if ( INCLUDE_xTimerPendFunctionCall == 1 )
|
||||||
|
BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend,
|
||||||
|
void * pvParameter1,
|
||||||
|
uint32_t ulParameter2,
|
||||||
|
TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* const char * const pcTimerGetTimerName( TimerHandle_t xTimer );
|
* const char * const pcTimerGetName( TimerHandle_t xTimer );
|
||||||
*
|
*
|
||||||
* Returns the name that was assigned to a timer when the timer was created.
|
* Returns the name that was assigned to a timer when the timer was created.
|
||||||
*
|
*
|
||||||
|
@ -1128,19 +1251,181 @@ BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvPar
|
||||||
*
|
*
|
||||||
* @return The name assigned to the timer specified by the xTimer parameter.
|
* @return The name assigned to the timer specified by the xTimer parameter.
|
||||||
*/
|
*/
|
||||||
const char * pcTimerGetTimerName( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
const char * pcTimerGetName( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* void vTimerSetReloadMode( TimerHandle_t xTimer, const BaseType_t xAutoReload );
|
||||||
|
*
|
||||||
|
* Updates a timer to be either an auto-reload timer, in which case the timer
|
||||||
|
* automatically resets itself each time it expires, or a one-shot timer, in
|
||||||
|
* which case the timer will only expire once unless it is manually restarted.
|
||||||
|
*
|
||||||
|
* @param xTimer The handle of the timer being updated.
|
||||||
|
*
|
||||||
|
* @param xAutoReload If xAutoReload is set to pdTRUE then the timer will
|
||||||
|
* expire repeatedly with a frequency set by the timer's period (see the
|
||||||
|
* xTimerPeriodInTicks parameter of the xTimerCreate() API function). If
|
||||||
|
* xAutoReload is set to pdFALSE then the timer will be a one-shot timer and
|
||||||
|
* enter the dormant state after it expires.
|
||||||
|
*/
|
||||||
|
void vTimerSetReloadMode( TimerHandle_t xTimer,
|
||||||
|
const BaseType_t xAutoReload ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BaseType_t xTimerGetReloadMode( TimerHandle_t xTimer );
|
||||||
|
*
|
||||||
|
* Queries a timer to determine if it is an auto-reload timer, in which case the timer
|
||||||
|
* automatically resets itself each time it expires, or a one-shot timer, in
|
||||||
|
* which case the timer will only expire once unless it is manually restarted.
|
||||||
|
*
|
||||||
|
* @param xTimer The handle of the timer being queried.
|
||||||
|
*
|
||||||
|
* @return If the timer is an auto-reload timer then pdTRUE is returned, otherwise
|
||||||
|
* pdFALSE is returned.
|
||||||
|
*/
|
||||||
|
BaseType_t xTimerGetReloadMode( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UBaseType_t uxTimerGetReloadMode( TimerHandle_t xTimer );
|
||||||
|
*
|
||||||
|
* Queries a timer to determine if it is an auto-reload timer, in which case the timer
|
||||||
|
* automatically resets itself each time it expires, or a one-shot timer, in
|
||||||
|
* which case the timer will only expire once unless it is manually restarted.
|
||||||
|
*
|
||||||
|
* @param xTimer The handle of the timer being queried.
|
||||||
|
*
|
||||||
|
* @return If the timer is an auto-reload timer then pdTRUE is returned, otherwise
|
||||||
|
* pdFALSE is returned.
|
||||||
|
*/
|
||||||
|
UBaseType_t uxTimerGetReloadMode( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TickType_t xTimerGetPeriod( TimerHandle_t xTimer );
|
||||||
|
*
|
||||||
|
* Returns the period of a timer.
|
||||||
|
*
|
||||||
|
* @param xTimer The handle of the timer being queried.
|
||||||
|
*
|
||||||
|
* @return The period of the timer in ticks.
|
||||||
|
*/
|
||||||
|
TickType_t xTimerGetPeriod( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer );
|
||||||
|
*
|
||||||
|
* Returns the time in ticks at which the timer will expire. If this is less
|
||||||
|
* than the current tick count then the expiry time has overflowed from the
|
||||||
|
* current time.
|
||||||
|
*
|
||||||
|
* @param xTimer The handle of the timer being queried.
|
||||||
|
*
|
||||||
|
* @return If the timer is running then the time in ticks at which the timer
|
||||||
|
* will next expire is returned. If the timer is not running then the return
|
||||||
|
* value is undefined.
|
||||||
|
*/
|
||||||
|
TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BaseType_t xTimerGetStaticBuffer( TimerHandle_t xTimer,
|
||||||
|
* StaticTimer_t ** ppxTimerBuffer );
|
||||||
|
*
|
||||||
|
* Retrieve pointer to a statically created timer's data structure
|
||||||
|
* buffer. This is the same buffer that is supplied at the time of
|
||||||
|
* creation.
|
||||||
|
*
|
||||||
|
* @param xTimer The timer for which to retrieve the buffer.
|
||||||
|
*
|
||||||
|
* @param ppxTaskBuffer Used to return a pointer to the timers's data
|
||||||
|
* structure buffer.
|
||||||
|
*
|
||||||
|
* @return pdTRUE if the buffer was retrieved, pdFALSE otherwise.
|
||||||
|
*/
|
||||||
|
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
|
BaseType_t xTimerGetStaticBuffer( TimerHandle_t xTimer,
|
||||||
|
StaticTimer_t ** ppxTimerBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Functions beyond this part are not part of the public API and are intended
|
* Functions beyond this part are not part of the public API and are intended
|
||||||
* for use by the kernel only.
|
* for use by the kernel only.
|
||||||
*/
|
*/
|
||||||
BaseType_t xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION;
|
BaseType_t xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION;
|
||||||
BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
/*
|
||||||
}
|
* Splitting the xTimerGenericCommand into two sub functions and making it a macro
|
||||||
|
* removes a recursion path when called from ISRs. This is primarily for the XCore
|
||||||
|
* XCC port which detects the recursion path and throws an error during compilation
|
||||||
|
* when this is not split.
|
||||||
|
*/
|
||||||
|
BaseType_t xTimerGenericCommandFromTask( TimerHandle_t xTimer,
|
||||||
|
const BaseType_t xCommandID,
|
||||||
|
const TickType_t xOptionalValue,
|
||||||
|
BaseType_t * const pxHigherPriorityTaskWoken,
|
||||||
|
const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
BaseType_t xTimerGenericCommandFromISR( TimerHandle_t xTimer,
|
||||||
|
const BaseType_t xCommandID,
|
||||||
|
const TickType_t xOptionalValue,
|
||||||
|
BaseType_t * const pxHigherPriorityTaskWoken,
|
||||||
|
const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
#define xTimerGenericCommand( xTimer, xCommandID, xOptionalValue, pxHigherPriorityTaskWoken, xTicksToWait ) \
|
||||||
|
( ( xCommandID ) < tmrFIRST_FROM_ISR_COMMAND ? \
|
||||||
|
xTimerGenericCommandFromTask( xTimer, xCommandID, xOptionalValue, pxHigherPriorityTaskWoken, xTicksToWait ) : \
|
||||||
|
xTimerGenericCommandFromISR( xTimer, xCommandID, xOptionalValue, pxHigherPriorityTaskWoken, xTicksToWait ) )
|
||||||
|
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||||
|
void vTimerSetTimerNumber( TimerHandle_t xTimer,
|
||||||
|
UBaseType_t uxTimerNumber ) PRIVILEGED_FUNCTION;
|
||||||
|
UBaseType_t uxTimerGetTimerNumber( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* task.h
|
||||||
|
* @code{c}
|
||||||
|
* void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer, StackType_t ** ppxTimerTaskStackBuffer, configSTACK_DEPTH_TYPE * puxTimerTaskStackSize )
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* This function is used to provide a statically allocated block of memory to FreeRTOS to hold the Timer Task TCB. This function is required when
|
||||||
|
* configSUPPORT_STATIC_ALLOCATION is set. For more information see this URI: https://www.FreeRTOS.org/a00110.html#configSUPPORT_STATIC_ALLOCATION
|
||||||
|
*
|
||||||
|
* @param ppxTimerTaskTCBBuffer A handle to a statically allocated TCB buffer
|
||||||
|
* @param ppxTimerTaskStackBuffer A handle to a statically allocated Stack buffer for the idle task
|
||||||
|
* @param puxTimerTaskStackSize A pointer to the number of elements that will fit in the allocated stack buffer
|
||||||
|
*/
|
||||||
|
void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer,
|
||||||
|
StackType_t ** ppxTimerTaskStackBuffer,
|
||||||
|
configSTACK_DEPTH_TYPE * puxTimerTaskStackSize );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ( configUSE_DAEMON_TASK_STARTUP_HOOK != 0 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* timers.h
|
||||||
|
* @code{c}
|
||||||
|
* void vApplicationDaemonTaskStartupHook( void );
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* This hook function is called form the timer task once when the task starts running.
|
||||||
|
*/
|
||||||
|
/* MISRA Ref 8.6.1 [External linkage] */
|
||||||
|
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-86 */
|
||||||
|
/* coverity[misra_c_2012_rule_8_6_violation] */
|
||||||
|
void vApplicationDaemonTaskStartupHook( void );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function resets the internal state of the timer module. It must be called
|
||||||
|
* by the application before restarting the scheduler.
|
||||||
|
*/
|
||||||
|
void vTimerResetState( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
#endif /* TIMERS_H */
|
#endif /* TIMERS_H */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
267
Source/list.c
267
Source/list.c
|
@ -1,132 +1,123 @@
|
||||||
/*
|
/*
|
||||||
FreeRTOS V8.2.3 - Copyright (C) 2015 Real Time Engineers Ltd.
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
All rights reserved
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
This file is part of the FreeRTOS distribution.
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
* the Software without restriction, including without limitation the rights to
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
***************************************************************************
|
*
|
||||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
* copies or substantial portions of the Software.
|
||||||
>>! obliged to provide the source code for proprietary components !<<
|
*
|
||||||
>>! outside of the FreeRTOS kernel. !<<
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
***************************************************************************
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
link: http://www.freertos.org/a00114.html
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
***************************************************************************
|
* https://github.com/FreeRTOS
|
||||||
* *
|
*
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
*/
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
|
||||||
* platform software that is more than just the market leader, it *
|
|
||||||
* is the industry's de facto standard. *
|
|
||||||
* *
|
|
||||||
* Help yourself get started quickly while simultaneously helping *
|
|
||||||
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
|
||||||
* tutorial book, reference manual, or both: *
|
|
||||||
* http://www.FreeRTOS.org/Documentation *
|
|
||||||
* *
|
|
||||||
***************************************************************************
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
|
||||||
the FAQ page "My application does not run, what could be wrong?". Have you
|
|
||||||
defined configASSERT()?
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
|
||||||
embedded software for free we request you assist our global community by
|
|
||||||
participating in the support forum.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
|
||||||
be as productive as possible as early as possible. Now you can receive
|
|
||||||
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
|
||||||
Ltd, and the world's leading authority on the world's leading RTOS.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
|
||||||
|
|
||||||
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
|
||||||
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
|
||||||
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
|
||||||
licenses offer ticketed support, indemnification and commercial middleware.
|
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
|
||||||
mission critical applications that require provable dependability.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
|
||||||
|
* all the API functions to use the MPU wrappers. That should only be done when
|
||||||
|
* task.h is included from an application file. */
|
||||||
|
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||||
|
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/* The MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be
|
||||||
* PUBLIC LIST API documented in list.h
|
* defined for the header files above, but not in this file, in order to
|
||||||
*----------------------------------------------------------*/
|
* generate the correct privileged Vs unprivileged linkage and placement. */
|
||||||
|
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* PUBLIC LIST API documented in list.h
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
void vListInitialise( List_t * const pxList )
|
void vListInitialise( List_t * const pxList )
|
||||||
{
|
{
|
||||||
|
traceENTER_vListInitialise( pxList );
|
||||||
|
|
||||||
/* The list structure contains a list item which is used to mark the
|
/* The list structure contains a list item which is used to mark the
|
||||||
end of the list. To initialise the list the list end is inserted
|
* end of the list. To initialise the list the list end is inserted
|
||||||
as the only list entry. */
|
* as the only list entry. */
|
||||||
pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd );
|
||||||
|
|
||||||
|
listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( &( pxList->xListEnd ) );
|
||||||
|
|
||||||
/* The list end value is the highest possible value in the list to
|
/* The list end value is the highest possible value in the list to
|
||||||
ensure it remains at the end of the list. */
|
* ensure it remains at the end of the list. */
|
||||||
pxList->xListEnd.xItemValue = portMAX_DELAY;
|
pxList->xListEnd.xItemValue = portMAX_DELAY;
|
||||||
|
|
||||||
/* The list end next and previous pointers point to itself so we know
|
/* The list end next and previous pointers point to itself so we know
|
||||||
when the list is empty. */
|
* when the list is empty. */
|
||||||
pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd );
|
||||||
pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );/*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );
|
||||||
|
|
||||||
|
/* Initialize the remaining fields of xListEnd when it is a proper ListItem_t */
|
||||||
|
#if ( configUSE_MINI_LIST_ITEM == 0 )
|
||||||
|
{
|
||||||
|
pxList->xListEnd.pvOwner = NULL;
|
||||||
|
pxList->xListEnd.pxContainer = NULL;
|
||||||
|
listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( &( pxList->xListEnd ) );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
pxList->uxNumberOfItems = ( UBaseType_t ) 0U;
|
pxList->uxNumberOfItems = ( UBaseType_t ) 0U;
|
||||||
|
|
||||||
/* Write known values into the list if
|
/* Write known values into the list if
|
||||||
configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||||
listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );
|
listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );
|
||||||
listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );
|
listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );
|
||||||
|
|
||||||
|
traceRETURN_vListInitialise();
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vListInitialiseItem( ListItem_t * const pxItem )
|
void vListInitialiseItem( ListItem_t * const pxItem )
|
||||||
{
|
{
|
||||||
|
traceENTER_vListInitialiseItem( pxItem );
|
||||||
|
|
||||||
/* Make sure the list item is not recorded as being on a list. */
|
/* Make sure the list item is not recorded as being on a list. */
|
||||||
pxItem->pvContainer = NULL;
|
pxItem->pxContainer = NULL;
|
||||||
|
|
||||||
/* Write known values into the list item if
|
/* Write known values into the list item if
|
||||||
configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||||
listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
|
listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
|
||||||
listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
|
listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
|
||||||
|
|
||||||
|
traceRETURN_vListInitialiseItem();
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem )
|
void vListInsertEnd( List_t * const pxList,
|
||||||
|
ListItem_t * const pxNewListItem )
|
||||||
{
|
{
|
||||||
ListItem_t * const pxIndex = pxList->pxIndex;
|
ListItem_t * const pxIndex = pxList->pxIndex;
|
||||||
|
|
||||||
|
traceENTER_vListInsertEnd( pxList, pxNewListItem );
|
||||||
|
|
||||||
/* Only effective when configASSERT() is also defined, these tests may catch
|
/* Only effective when configASSERT() is also defined, these tests may catch
|
||||||
the list data structures being overwritten in memory. They will not catch
|
* the list data structures being overwritten in memory. They will not catch
|
||||||
data errors caused by incorrect configuration or use of FreeRTOS. */
|
* data errors caused by incorrect configuration or use of FreeRTOS. */
|
||||||
listTEST_LIST_INTEGRITY( pxList );
|
listTEST_LIST_INTEGRITY( pxList );
|
||||||
listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
|
listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
|
||||||
|
|
||||||
/* Insert a new list item into pxList, but rather than sort the list,
|
/* Insert a new list item into pxList, but rather than sort the list,
|
||||||
makes the new list item the last item to be removed by a call to
|
* makes the new list item the last item to be removed by a call to
|
||||||
listGET_OWNER_OF_NEXT_ENTRY(). */
|
* listGET_OWNER_OF_NEXT_ENTRY(). */
|
||||||
pxNewListItem->pxNext = pxIndex;
|
pxNewListItem->pxNext = pxIndex;
|
||||||
pxNewListItem->pxPrevious = pxIndex->pxPrevious;
|
pxNewListItem->pxPrevious = pxIndex->pxPrevious;
|
||||||
|
|
||||||
|
@ -137,31 +128,36 @@ ListItem_t * const pxIndex = pxList->pxIndex;
|
||||||
pxIndex->pxPrevious = pxNewListItem;
|
pxIndex->pxPrevious = pxNewListItem;
|
||||||
|
|
||||||
/* Remember which list the item is in. */
|
/* Remember which list the item is in. */
|
||||||
pxNewListItem->pvContainer = ( void * ) pxList;
|
pxNewListItem->pxContainer = pxList;
|
||||||
|
|
||||||
( pxList->uxNumberOfItems )++;
|
( pxList->uxNumberOfItems ) = ( UBaseType_t ) ( pxList->uxNumberOfItems + 1U );
|
||||||
|
|
||||||
|
traceRETURN_vListInsertEnd();
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem )
|
void vListInsert( List_t * const pxList,
|
||||||
|
ListItem_t * const pxNewListItem )
|
||||||
{
|
{
|
||||||
ListItem_t *pxIterator;
|
ListItem_t * pxIterator;
|
||||||
const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
|
const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
|
||||||
|
|
||||||
|
traceENTER_vListInsert( pxList, pxNewListItem );
|
||||||
|
|
||||||
/* Only effective when configASSERT() is also defined, these tests may catch
|
/* Only effective when configASSERT() is also defined, these tests may catch
|
||||||
the list data structures being overwritten in memory. They will not catch
|
* the list data structures being overwritten in memory. They will not catch
|
||||||
data errors caused by incorrect configuration or use of FreeRTOS. */
|
* data errors caused by incorrect configuration or use of FreeRTOS. */
|
||||||
listTEST_LIST_INTEGRITY( pxList );
|
listTEST_LIST_INTEGRITY( pxList );
|
||||||
listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
|
listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
|
||||||
|
|
||||||
/* Insert the new list item into the list, sorted in xItemValue order.
|
/* Insert the new list item into the list, sorted in xItemValue order.
|
||||||
|
*
|
||||||
If the list already contains a list item with the same item value then the
|
* If the list already contains a list item with the same item value then the
|
||||||
new list item should be placed after it. This ensures that TCB's which are
|
* new list item should be placed after it. This ensures that TCBs which are
|
||||||
stored in ready lists (all of which have the same xItemValue value) get a
|
* stored in ready lists (all of which have the same xItemValue value) get a
|
||||||
share of the CPU. However, if the xItemValue is the same as the back marker
|
* share of the CPU. However, if the xItemValue is the same as the back marker
|
||||||
the iteration loop below will not end. Therefore the value is checked
|
* the iteration loop below will not end. Therefore the value is checked
|
||||||
first, and the algorithm slightly modified if necessary. */
|
* first, and the algorithm slightly modified if necessary. */
|
||||||
if( xValueOfInsertion == portMAX_DELAY )
|
if( xValueOfInsertion == portMAX_DELAY )
|
||||||
{
|
{
|
||||||
pxIterator = pxList->xListEnd.pxPrevious;
|
pxIterator = pxList->xListEnd.pxPrevious;
|
||||||
|
@ -169,31 +165,36 @@ const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* *** NOTE ***********************************************************
|
/* *** NOTE ***********************************************************
|
||||||
If you find your application is crashing here then likely causes are
|
* If you find your application is crashing here then likely causes are
|
||||||
listed below. In addition see http://www.freertos.org/FAQHelp.html for
|
* listed below. In addition see https://www.FreeRTOS.org/FAQHelp.html for
|
||||||
more tips, and ensure configASSERT() is defined!
|
* more tips, and ensure configASSERT() is defined!
|
||||||
http://www.freertos.org/a00110.html#configASSERT
|
* https://www.FreeRTOS.org/a00110.html#configASSERT
|
||||||
|
*
|
||||||
1) Stack overflow -
|
* 1) Stack overflow -
|
||||||
see http://www.freertos.org/Stacks-and-stack-overflow-checking.html
|
* see https://www.FreeRTOS.org/Stacks-and-stack-overflow-checking.html
|
||||||
2) Incorrect interrupt priority assignment, especially on Cortex-M
|
* 2) Incorrect interrupt priority assignment, especially on Cortex-M
|
||||||
parts where numerically high priority values denote low actual
|
* parts where numerically high priority values denote low actual
|
||||||
interrupt priorities, which can seem counter intuitive. See
|
* interrupt priorities, which can seem counter intuitive. See
|
||||||
http://www.freertos.org/RTOS-Cortex-M3-M4.html and the definition
|
* https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html and the definition
|
||||||
of configMAX_SYSCALL_INTERRUPT_PRIORITY on
|
* of configMAX_SYSCALL_INTERRUPT_PRIORITY on
|
||||||
http://www.freertos.org/a00110.html
|
* https://www.FreeRTOS.org/a00110.html
|
||||||
3) Calling an API function from within a critical section or when
|
* 3) Calling an API function from within a critical section or when
|
||||||
the scheduler is suspended, or calling an API function that does
|
* the scheduler is suspended, or calling an API function that does
|
||||||
not end in "FromISR" from an interrupt.
|
* not end in "FromISR" from an interrupt.
|
||||||
4) Using a queue or semaphore before it has been initialised or
|
* 4) Using a queue or semaphore before it has been initialised or
|
||||||
before the scheduler has been started (are interrupts firing
|
* before the scheduler has been started (are interrupts firing
|
||||||
before vTaskStartScheduler() has been called?).
|
* before vTaskStartScheduler() has been called?).
|
||||||
|
* 5) If the FreeRTOS port supports interrupt nesting then ensure that
|
||||||
|
* the priority of the tick interrupt is at or below
|
||||||
|
* configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
|
|
||||||
for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext )
|
||||||
{
|
{
|
||||||
/* There is nothing to do here, just iterating to the wanted
|
/* There is nothing to do here, just iterating to the wanted
|
||||||
insertion position. */
|
* insertion position.
|
||||||
|
* IF YOU FIND YOUR CODE STUCK HERE, SEE THE NOTE JUST ABOVE.
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,18 +204,23 @@ const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
|
||||||
pxIterator->pxNext = pxNewListItem;
|
pxIterator->pxNext = pxNewListItem;
|
||||||
|
|
||||||
/* Remember which list the item is in. This allows fast removal of the
|
/* Remember which list the item is in. This allows fast removal of the
|
||||||
item later. */
|
* item later. */
|
||||||
pxNewListItem->pvContainer = ( void * ) pxList;
|
pxNewListItem->pxContainer = pxList;
|
||||||
|
|
||||||
( pxList->uxNumberOfItems )++;
|
( pxList->uxNumberOfItems ) = ( UBaseType_t ) ( pxList->uxNumberOfItems + 1U );
|
||||||
|
|
||||||
|
traceRETURN_vListInsert();
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
|
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
|
||||||
{
|
{
|
||||||
/* The list item knows which list it is in. Obtain the list from the list
|
/* The list item knows which list it is in. Obtain the list from the list
|
||||||
item. */
|
* item. */
|
||||||
List_t * const pxList = ( List_t * ) pxItemToRemove->pvContainer;
|
List_t * const pxList = pxItemToRemove->pxContainer;
|
||||||
|
|
||||||
|
traceENTER_uxListRemove( pxItemToRemove );
|
||||||
|
|
||||||
pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
|
pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
|
||||||
pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
|
pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
|
||||||
|
@ -232,10 +238,11 @@ List_t * const pxList = ( List_t * ) pxItemToRemove->pvContainer;
|
||||||
mtCOVERAGE_TEST_MARKER();
|
mtCOVERAGE_TEST_MARKER();
|
||||||
}
|
}
|
||||||
|
|
||||||
pxItemToRemove->pvContainer = NULL;
|
pxItemToRemove->pxContainer = NULL;
|
||||||
( pxList->uxNumberOfItems )--;
|
( pxList->uxNumberOfItems ) = ( UBaseType_t ) ( pxList->uxNumberOfItems - 1U );
|
||||||
|
|
||||||
|
traceRETURN_uxListRemove( pxList->uxNumberOfItems );
|
||||||
|
|
||||||
return pxList->uxNumberOfItems;
|
return pxList->uxNumberOfItems;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
2611
Source/queue.c
2611
Source/queue.c
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
7971
Source/tasks.c
7971
Source/tasks.c
File diff suppressed because it is too large
Load Diff
1231
Source/timers.c
1231
Source/timers.c
File diff suppressed because it is too large
Load Diff
210
__f
210
__f
|
@ -41,10 +41,21 @@
|
||||||
./Source/include/prescaler.h
|
./Source/include/prescaler.h
|
||||||
./Source/include/timer.h
|
./Source/include/timer.h
|
||||||
./Source/include/uart.h
|
./Source/include/uart.h
|
||||||
|
./Source/include/CMakeLists.txt
|
||||||
|
./Source/include/atomic.h
|
||||||
|
./Source/include/message_buffer.h
|
||||||
|
./Source/include/mpu_prototypes.h
|
||||||
|
./Source/include/mpu_syscall_numbers.h
|
||||||
|
./Source/include/newlib-freertos.h
|
||||||
|
./Source/include/picolibc-freertos.h
|
||||||
|
./Source/include/stack_macros.h
|
||||||
|
./Source/include/stream_buffer.h
|
||||||
./Source/readme.txt
|
./Source/readme.txt
|
||||||
./Source/list.c
|
./Source/list.c
|
||||||
./Source/croutine.c
|
./Source/croutine.c
|
||||||
|
./Source/stream_buffer.c
|
||||||
./Source/tasks.c
|
./Source/tasks.c
|
||||||
|
./Source/.tasks.c.swp
|
||||||
./Demo
|
./Demo
|
||||||
./Demo/arch
|
./Demo/arch
|
||||||
./Demo/arch/clib.c
|
./Demo/arch/clib.c
|
||||||
|
@ -62,13 +73,208 @@
|
||||||
./Demo/Common
|
./Demo/Common
|
||||||
./Demo/Common/.gdb_history
|
./Demo/Common/.gdb_history
|
||||||
./Demo/Common/FreeRTOS-openocd.c
|
./Demo/Common/FreeRTOS-openocd.c
|
||||||
|
./Demo/Common/bin
|
||||||
|
./Demo/Common/X.hpp
|
||||||
|
./Demo/Common/X.cpp
|
||||||
|
./Demo/Common/FreeRTOSStreamBuf.hpp
|
||||||
|
./Demo/Common/SimpleOStream.hpp
|
||||||
|
./Demo/Common/include
|
||||||
|
./Demo/Common/include/Timer.hpp
|
||||||
|
./Demo/Common/include/FreeRTOS
|
||||||
|
./Demo/Common/include/FreeRTOS/EventGroups.hpp
|
||||||
|
./Demo/Common/include/FreeRTOS/MessageBuffer.hpp
|
||||||
|
./Demo/Common/include/FreeRTOS/Mutex.hpp
|
||||||
|
./Demo/Common/include/FreeRTOS/Queue.hpp
|
||||||
|
./Demo/Common/include/FreeRTOS/Semaphore.hpp
|
||||||
|
./Demo/Common/include/FreeRTOS/StreamBuffer.hpp
|
||||||
|
./Demo/Common/include/FreeRTOS/Timer.hpp
|
||||||
|
./Demo/Common/include/FreeRTOS/Task.hpp
|
||||||
|
./Demo/Common/include/FreeRTOS/Kernel.hpp
|
||||||
|
./Demo/Common/lib
|
||||||
|
./Demo/Common/lib/cJSON_Utils.c
|
||||||
|
./Demo/Common/lib/cJSON.c
|
||||||
|
./Demo/Common/lib/cJSON.h
|
||||||
|
./Demo/Common/lib/cJSON_Utils.h
|
||||||
./Demo/Common/Makefile
|
./Demo/Common/Makefile
|
||||||
./Demo/Common/main.cpp
|
./Demo/Common/main.cpp
|
||||||
./Demo/Common/bin
|
|
||||||
./Demo/conf
|
./Demo/conf
|
||||||
./Demo/conf/FreeRTOSConfig.h
|
./Demo/conf/FreeRTOSConfig.h
|
||||||
./gdb.txt
|
./gdb.txt
|
||||||
./.gdb_history
|
|
||||||
./tags
|
./tags
|
||||||
./__t
|
./__t
|
||||||
./__f
|
./__f
|
||||||
|
./.git
|
||||||
|
./.git/branches
|
||||||
|
./.git/description
|
||||||
|
./.git/hooks
|
||||||
|
./.git/hooks/applypatch-msg.sample
|
||||||
|
./.git/hooks/commit-msg.sample
|
||||||
|
./.git/hooks/fsmonitor-watchman.sample
|
||||||
|
./.git/hooks/post-update.sample
|
||||||
|
./.git/hooks/pre-applypatch.sample
|
||||||
|
./.git/hooks/pre-commit.sample
|
||||||
|
./.git/hooks/pre-merge-commit.sample
|
||||||
|
./.git/hooks/pre-push.sample
|
||||||
|
./.git/hooks/pre-rebase.sample
|
||||||
|
./.git/hooks/pre-receive.sample
|
||||||
|
./.git/hooks/prepare-commit-msg.sample
|
||||||
|
./.git/hooks/push-to-checkout.sample
|
||||||
|
./.git/hooks/update.sample
|
||||||
|
./.git/info
|
||||||
|
./.git/info/exclude
|
||||||
|
./.git/refs
|
||||||
|
./.git/refs/heads
|
||||||
|
./.git/refs/heads/master
|
||||||
|
./.git/refs/heads/starter
|
||||||
|
./.git/refs/tags
|
||||||
|
./.git/refs/remotes
|
||||||
|
./.git/refs/remotes/v
|
||||||
|
./.git/refs/remotes/v/starter
|
||||||
|
./.git/objects
|
||||||
|
./.git/objects/pack
|
||||||
|
./.git/objects/info
|
||||||
|
./.git/objects/45
|
||||||
|
./.git/objects/45/b37b0d298b4e8e3d6cfba6efd43cc8a80d0487
|
||||||
|
./.git/objects/a0
|
||||||
|
./.git/objects/a0/e3d5165b78e9718c77332a680dbdecb0f75009
|
||||||
|
./.git/objects/e5
|
||||||
|
./.git/objects/e5/954a793ab23574d479dfd8a5476b441045e49b
|
||||||
|
./.git/objects/81
|
||||||
|
./.git/objects/81/a3ab77abb8b95eea85b07e854c77d74771cad0
|
||||||
|
./.git/objects/81/518ecb4339e35363d844853fde09116e314cea
|
||||||
|
./.git/objects/3a
|
||||||
|
./.git/objects/3a/b4146ec1632a8561c32b00a02aa5ef10f3753b
|
||||||
|
./.git/objects/ba
|
||||||
|
./.git/objects/ba/a5f136424add9d1b77d934183834fe23ef290c
|
||||||
|
./.git/objects/fa
|
||||||
|
./.git/objects/fa/e73fe5c5b97fc397b2e246efc67b6326bb3c86
|
||||||
|
./.git/objects/fa/7ab0256f76a61285dea9ebb840a60ad9b5368b
|
||||||
|
./.git/objects/5c
|
||||||
|
./.git/objects/5c/21ce7485473baef33bc70b06ab35c068d8d400
|
||||||
|
./.git/objects/48
|
||||||
|
./.git/objects/48/fc14bbf73c235e7ff83c24f03442bb1f4954f1
|
||||||
|
./.git/objects/8c
|
||||||
|
./.git/objects/8c/9261a196bc5f790ecba87be0728df775f16994
|
||||||
|
./.git/objects/13
|
||||||
|
./.git/objects/13/5b620e1f9a9e0a3c08e4dce18ad3b8379f876b
|
||||||
|
./.git/objects/13/59090c321f3f7497d5edc97542bc0dd516356f
|
||||||
|
./.git/objects/34
|
||||||
|
./.git/objects/34/348fec0aa202b4b0d716239da3504b2effdb71
|
||||||
|
./.git/objects/23
|
||||||
|
./.git/objects/23/b7d277ae8e8981f8860f0a012fa475ca6607a5
|
||||||
|
./.git/objects/fb
|
||||||
|
./.git/objects/fb/fdf3e7a32e66ca2c714b136827267fbe3e6740
|
||||||
|
./.git/objects/6b
|
||||||
|
./.git/objects/6b/d9694a7fea3f9a53fd2da420b0fceba4480d7d
|
||||||
|
./.git/objects/15
|
||||||
|
./.git/objects/15/77535c524b8f7f8328509632390360e5e268e8
|
||||||
|
./.git/objects/c3
|
||||||
|
./.git/objects/c3/a30a56f42678fbf403a431874af64c4f925391
|
||||||
|
./.git/objects/7a
|
||||||
|
./.git/objects/7a/7a2ea49058caaea65402f0e804ea6d4847539c
|
||||||
|
./.git/objects/e2
|
||||||
|
./.git/objects/e2/f75e4445e79b67c5cfe46f5f67f611fbaf646a
|
||||||
|
./.git/objects/4d
|
||||||
|
./.git/objects/4d/6d4d7e25a81d87fb9ace7573b1eb9b0fdba38f
|
||||||
|
./.git/objects/62
|
||||||
|
./.git/objects/62/5548c56c78b594a09f5c2899b9a328edbca57c
|
||||||
|
./.git/objects/7d
|
||||||
|
./.git/objects/7d/34ec63bb51796ff02f130e26c23ccd0f291e3d
|
||||||
|
./.git/objects/78
|
||||||
|
./.git/objects/78/c78ff5fc463de1a9a6c87f682fd81d0a68f818
|
||||||
|
./.git/objects/56
|
||||||
|
./.git/objects/56/07e07b123a7476c484168e29103a4d232f022f
|
||||||
|
./.git/objects/dc
|
||||||
|
./.git/objects/dc/655ae20c83666f2b45c475850acce797c31712
|
||||||
|
./.git/objects/dc/85497503cf1dec9e79aa32e19830d18627b7a1
|
||||||
|
./.git/objects/0f
|
||||||
|
./.git/objects/0f/ad862693692a2a00d134252d24245429a38933
|
||||||
|
./.git/objects/0f/da74c35c06a8af6b913da649275801ea364b9b
|
||||||
|
./.git/objects/a3
|
||||||
|
./.git/objects/a3/81ed0726010521968e55fc974332b2c4156490
|
||||||
|
./.git/objects/75
|
||||||
|
./.git/objects/75/d391d4ce4e4d281ea1a9eeacee36fb57fd31ed
|
||||||
|
./.git/objects/5b
|
||||||
|
./.git/objects/5b/2ad474d848a7d690dc14dacb2edbe61b9d66c6
|
||||||
|
./.git/objects/cd
|
||||||
|
./.git/objects/cd/6a9344c4d2b7ea59069ca8eef52bc3c14d5db6
|
||||||
|
./.git/objects/95
|
||||||
|
./.git/objects/95/6264b953a110f90c92e44c09e979aa33e5f58f
|
||||||
|
./.git/objects/2d
|
||||||
|
./.git/objects/2d/7b5e90a70c06b879216f0381a0b1ed5f708cee
|
||||||
|
./.git/objects/ab
|
||||||
|
./.git/objects/ab/00d09d76ce0debee162e1770de2c11b5031572
|
||||||
|
./.git/objects/ab/b56f10c3eb0a28a7193a0d482edcc553b3b954
|
||||||
|
./.git/objects/6d
|
||||||
|
./.git/objects/6d/86149ca6bcc6719648f0ca98d3263f706d273c
|
||||||
|
./.git/objects/b8
|
||||||
|
./.git/objects/b8/d6dd89094179130a8ddcfac6ccda5bd341be98
|
||||||
|
./.git/objects/3c
|
||||||
|
./.git/objects/3c/6c6bf308576cf9936700040b4385041042dce8
|
||||||
|
./.git/objects/67
|
||||||
|
./.git/objects/67/d3b7342c2bdce013c4b04c2b54daedf1f7715c
|
||||||
|
./.git/objects/37
|
||||||
|
./.git/objects/37/06184d9dbea321cae9592a7c6599dbde2a6b7a
|
||||||
|
./.git/objects/d2
|
||||||
|
./.git/objects/d2/feaddba00c34854b3a106e3d5d2946da292277
|
||||||
|
./.git/objects/ae
|
||||||
|
./.git/objects/ae/ca28735c9913d0418a62cf69f9ae731a2294c9
|
||||||
|
./.git/objects/d9
|
||||||
|
./.git/objects/d9/f52c1f2e05816b8dd193f22f5d1acb2764a0c0
|
||||||
|
./.git/objects/df
|
||||||
|
./.git/objects/df/3a9460cddec035804bb122af8ddcffd713e4a6
|
||||||
|
./.git/objects/f1
|
||||||
|
./.git/objects/f1/39ef0512d9b11f7a9a6d7b015ca6c7a9edaeef
|
||||||
|
./.git/objects/2f
|
||||||
|
./.git/objects/2f/7b50abf0fbafcbd186bad9441665ba6f7569bd
|
||||||
|
./.git/objects/41
|
||||||
|
./.git/objects/41/855c26ad9bebd897c9412bc4e7f5be69b4ad21
|
||||||
|
./.git/objects/e0
|
||||||
|
./.git/objects/e0/18d1ff244e1696cd85273cb36a1f71601c9ee1
|
||||||
|
./.git/objects/c7
|
||||||
|
./.git/objects/c7/ab9023f007fb4f2a3083d398243985b806f724
|
||||||
|
./.git/objects/f3
|
||||||
|
./.git/objects/f3/1fd927646698c28970e2a9de2fb126854ced84
|
||||||
|
./.git/objects/f2
|
||||||
|
./.git/objects/f2/814eb6ec114655e87ffdea55fee06c753032ae
|
||||||
|
./.git/objects/89
|
||||||
|
./.git/objects/89/c2735a8f73706f2a01f15f1359dd08bb56676b
|
||||||
|
./.git/objects/9e
|
||||||
|
./.git/objects/9e/035cca58ac05b855842b1052979661e57005ec
|
||||||
|
./.git/objects/ec
|
||||||
|
./.git/objects/ec/531c45cdea82edc87747207b5d15b5e0aef062
|
||||||
|
./.git/objects/bd
|
||||||
|
./.git/objects/bd/3dfdb012139317c927d6ca42330fef67b19902
|
||||||
|
./.git/objects/28
|
||||||
|
./.git/objects/28/849eb45410f46b5cc41ba6a67f5071dfec5e7a
|
||||||
|
./.git/objects/12
|
||||||
|
./.git/objects/12/fd856f80e1862f09fc8f56765a40029997726c
|
||||||
|
./.git/objects/99
|
||||||
|
./.git/objects/99/20965ed94cb7c6ddd8f6241dc0e4e92bb2013c
|
||||||
|
./.git/objects/e8
|
||||||
|
./.git/objects/e8/77421c109080020054ccd81b92f73f27849ed0
|
||||||
|
./.git/objects/5f
|
||||||
|
./.git/objects/5f/3e7e9a0a47f25fc50b1d39542d654cfed861dc
|
||||||
|
./.git/objects/bf
|
||||||
|
./.git/objects/bf/d3073292a71eadb70fae0323087586bfb78996
|
||||||
|
./.git/objects/42
|
||||||
|
./.git/objects/42/369fa558663fda06848be22706c80eab8ff09f
|
||||||
|
./.git/objects/61
|
||||||
|
./.git/objects/61/d00c335518254b1154756ee1487eb0b64bb521
|
||||||
|
./.git/objects/17
|
||||||
|
./.git/objects/17/448b4161ecd3ad249ff4de2e34ebce71c1122a
|
||||||
|
./.git/COMMIT_EDITMSG
|
||||||
|
./.git/logs
|
||||||
|
./.git/logs/HEAD
|
||||||
|
./.git/logs/refs
|
||||||
|
./.git/logs/refs/heads
|
||||||
|
./.git/logs/refs/heads/master
|
||||||
|
./.git/logs/refs/heads/starter
|
||||||
|
./.git/logs/refs/remotes
|
||||||
|
./.git/logs/refs/remotes/v
|
||||||
|
./.git/logs/refs/remotes/v/starter
|
||||||
|
./.git/config
|
||||||
|
./.git/HEAD
|
||||||
|
./.git/index
|
||||||
|
./.gdb_history
|
||||||
|
./1
|
||||||
|
|
Loading…
Reference in New Issue