mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
cpu/esp8266: FreeRTOS adaption layer added for RTOS SDK
This commit is contained in:
parent
dca6d59b60
commit
f397a74948
@ -3,6 +3,7 @@ MODULE = cpu
|
||||
|
||||
# Add a list of subdirectories, that should also be built:
|
||||
DIRS += $(RIOTCPU)/esp_common
|
||||
DIRS += freertos
|
||||
DIRS += periph
|
||||
DIRS += sdk
|
||||
DIRS += vendor
|
||||
|
@ -59,7 +59,7 @@ PSEUDOMODULES += esp_sdk
|
||||
PSEUDOMODULES += esp_sw_timer
|
||||
PSEUDOMODULES += esp_spiffs
|
||||
|
||||
USEMODULE += esp
|
||||
USEMODULE += esp_freertos
|
||||
USEMODULE += mtd
|
||||
USEMODULE += newlib
|
||||
USEMODULE += newlib_nano
|
||||
|
3
cpu/esp8266/freertos/Makefile
Normal file
3
cpu/esp8266/freertos/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
MODULE=esp_freertos
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
58
cpu/esp8266/freertos/event_groups.c
Normal file
58
cpu/esp8266/freertos/event_groups.c
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*
|
||||
* FreeRTOS to RIOT-OS adaption module for source code compatibility
|
||||
*/
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "rom/ets_sys.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/event_groups.h"
|
||||
|
||||
EventGroupHandle_t xEventGroupCreate (void)
|
||||
{
|
||||
printf("%s is not supported\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void vEventGroupDelete (EventGroupHandle_t xEventGroup)
|
||||
{
|
||||
printf("%s is not supported\n", __func__);
|
||||
}
|
||||
|
||||
EventBits_t xEventGroupSetBits (EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToSet)
|
||||
{
|
||||
printf("%s is not supported\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
EventBits_t xEventGroupClearBits (EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToClear )
|
||||
{
|
||||
printf("%s is not supported\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
EventBits_t xEventGroupWaitBits (const EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToWaitFor,
|
||||
const BaseType_t xClearOnExit,
|
||||
const BaseType_t xWaitForAllBits,
|
||||
TickType_t xTicksToWait)
|
||||
{
|
||||
printf("%s is not supported\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* DOXYGEN */
|
75
cpu/esp8266/freertos/portable.c
Normal file
75
cpu/esp8266/freertos/portable.c
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*
|
||||
* FreeRTOS to RIOT-OS adaption module for source code compatibility
|
||||
*/
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_common.h"
|
||||
#include "log.h"
|
||||
#ifdef MCU_ESP8266
|
||||
#include "esp_attr.h"
|
||||
#include "irq.h"
|
||||
#include "rom/ets_sys.h"
|
||||
#endif
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
||||
uint32_t xPortGetTickRateHz(void) {
|
||||
return MSEC_PER_SEC / portTICK_PERIOD_MS;
|
||||
}
|
||||
|
||||
BaseType_t xPortInIsrContext(void)
|
||||
{
|
||||
/* is working on single core in that way */
|
||||
return irq_is_in();
|
||||
}
|
||||
|
||||
#ifdef MCU_ESP8266
|
||||
|
||||
unsigned _xt_tick_divisor = 0; /* cached number of cycles per tick */
|
||||
|
||||
extern void vTaskEnterCritical( portMUX_TYPE *mux );
|
||||
extern void vTaskExitCritical( portMUX_TYPE *mux );
|
||||
|
||||
void vPortEnterCritical(void)
|
||||
{
|
||||
vTaskEnterCritical(0);
|
||||
}
|
||||
|
||||
extern void vPortExitCritical(void)
|
||||
{
|
||||
vTaskExitCritical(0);
|
||||
}
|
||||
|
||||
/* source: /path/to/esp8266-rtos-sdk/components/freertos/port/esp8266/port.c */
|
||||
void IRAM_ATTR vPortETSIntrLock(void)
|
||||
{
|
||||
ETS_INTR_LOCK();
|
||||
}
|
||||
|
||||
/* source: /path/to/esp8266-rtos-sdk/components/freertos/port/esp8266/port.c */
|
||||
void IRAM_ATTR vPortETSIntrUnlock(void)
|
||||
{
|
||||
ETS_INTR_UNLOCK();
|
||||
}
|
||||
|
||||
/* source: /path/to/esp8266-rtos-sdk/components/freertos/port/esp8266/port.c */
|
||||
void ResetCcountVal(unsigned int cnt_val)
|
||||
{
|
||||
asm volatile("wsr a2, ccount");
|
||||
}
|
||||
|
||||
#endif /* MCU_ESP8266 */
|
||||
|
||||
#endif /* DOXYGEN */
|
390
cpu/esp8266/freertos/queue.c
Normal file
390
cpu/esp8266/freertos/queue.c
Normal file
@ -0,0 +1,390 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*
|
||||
* FreeRTOS to RIOT-OS adaption module for source code compatibility
|
||||
*/
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_common.h"
|
||||
#include "esp_attr.h"
|
||||
#include "irq_arch.h"
|
||||
#include "log.h"
|
||||
#include "mutex.h"
|
||||
#include "rmutex.h"
|
||||
#include "syscalls.h"
|
||||
#include "thread.h"
|
||||
|
||||
#include "rom/ets_sys.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
/*
|
||||
* In FreeRTOS different types of semaphores, mutexes and queues are all
|
||||
* mapped to a single generic queue type. With all these different types,
|
||||
* single functions for send, receive, give and take are then used. To be
|
||||
* able to dsitinguish between these different types in RIOT, we need typed
|
||||
* objects.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t type; /* type of the queue, MUST be the first element */
|
||||
list_node_t sending; /* threads that are waiting to send */
|
||||
list_node_t receiving; /* threads that are waiting to receive */
|
||||
uint8_t* queue; /* the queue of waiting items */
|
||||
uint32_t item_size; /* size of each item in the queue */
|
||||
uint32_t item_num; /* num of items that can be stored in queue */
|
||||
uint32_t item_front; /* first item in queue */
|
||||
uint32_t item_tail; /* last item in queue */
|
||||
uint32_t item_level; /* num of items stored in queue */
|
||||
} _queue_t;
|
||||
|
||||
QueueHandle_t xQueueGenericCreate( const UBaseType_t uxQueueLength,
|
||||
const UBaseType_t uxItemSize,
|
||||
const uint8_t ucQueueType )
|
||||
{
|
||||
DEBUG("%s pid=%d len=%u size=%u type=%u ", __func__,
|
||||
thread_getpid(), uxQueueLength, uxItemSize, ucQueueType);
|
||||
|
||||
uint32_t queue_size = uxQueueLength * uxItemSize;
|
||||
_queue_t* queue = malloc(sizeof(_queue_t) + queue_size);
|
||||
|
||||
queue->type = ucQueueType;
|
||||
queue->receiving.next = NULL;
|
||||
queue->sending.next = NULL;
|
||||
queue->queue = (queue_size) ? (uint8_t*)queue + sizeof(_queue_t) : NULL;
|
||||
queue->item_num = uxQueueLength;
|
||||
queue->item_size = uxItemSize;
|
||||
queue->item_front = 0;
|
||||
queue->item_tail = 0;
|
||||
queue->item_level = 0;
|
||||
|
||||
DEBUG("queue=%p\n", queue);
|
||||
|
||||
return queue;
|
||||
}
|
||||
|
||||
#define queueSEMAPHORE_QUEUE_ITEM_LENGTH ( ( UBaseType_t ) 0 )
|
||||
|
||||
QueueHandle_t xQueueCreateCountingSemaphore (const UBaseType_t uxMaxCount,
|
||||
const UBaseType_t uxInitialCount)
|
||||
{
|
||||
_queue_t* queue;
|
||||
|
||||
assert(uxMaxCount != 0);
|
||||
assert(uxInitialCount <= uxMaxCount);
|
||||
|
||||
queue = xQueueGenericCreate(uxMaxCount, queueSEMAPHORE_QUEUE_ITEM_LENGTH,
|
||||
queueQUEUE_TYPE_COUNTING_SEMAPHORE);
|
||||
|
||||
DEBUG("%s pid=%d queue=%p\n", __func__, thread_getpid(), queue);
|
||||
|
||||
if (queue != NULL) {
|
||||
queue->item_level = uxInitialCount;
|
||||
queue->item_tail = (queue->item_front + queue->item_level) % queue->item_num;
|
||||
}
|
||||
|
||||
return queue;
|
||||
}
|
||||
|
||||
void vQueueDelete( QueueHandle_t xQueue )
|
||||
{
|
||||
DEBUG("%s pid=%d queue=%p\n", __func__, thread_getpid(), xQueue);
|
||||
|
||||
assert(xQueue != NULL);
|
||||
free(xQueue);
|
||||
}
|
||||
|
||||
BaseType_t IRAM_ATTR _queue_generic_send(QueueHandle_t xQueue,
|
||||
const void * const pvItemToQueue,
|
||||
const BaseType_t xCopyPosition,
|
||||
TickType_t xTicksToWait,
|
||||
BaseType_t * const pxHigherPriorityTaskWoken)
|
||||
{
|
||||
DEBUG("%s pid=%d prio=%d queue=%p pos=%d wait=%u woken=%p isr=%d\n", __func__,
|
||||
thread_getpid(), sched_threads[thread_getpid()]->priority,
|
||||
xQueue, xCopyPosition, xTicksToWait, pxHigherPriorityTaskWoken,
|
||||
irq_is_in());
|
||||
|
||||
assert(xQueue != NULL);
|
||||
|
||||
_queue_t* queue = (_queue_t*)xQueue;
|
||||
|
||||
while (1) {
|
||||
vTaskEnterCritical(0);
|
||||
|
||||
/* is there still space in the queue */
|
||||
if (queue->item_level < queue->item_num || xCopyPosition == queueOVERWRITE) {
|
||||
uint32_t write_pos;
|
||||
/* determine the write position in the queue and update positions */
|
||||
if (xCopyPosition == queueSEND_TO_BACK) {
|
||||
write_pos = queue->item_tail;
|
||||
queue->item_tail = (queue->item_tail + 1) % queue->item_num;
|
||||
queue->item_level++;
|
||||
}
|
||||
else if (xCopyPosition == queueSEND_TO_FRONT) {
|
||||
queue->item_front = (queue->item_front - 1) % queue->item_num;
|
||||
queue->item_level++;
|
||||
write_pos = queue->item_front;
|
||||
}
|
||||
else { /* queueOVERWRITE */
|
||||
write_pos = queue->item_front;
|
||||
if (queue->item_level == 0) {
|
||||
queue->item_level++;
|
||||
}
|
||||
}
|
||||
|
||||
/* if the item has no 0 size, copy it to the according place in queue */
|
||||
if (queue->item_size && queue->queue && pvItemToQueue) {
|
||||
memcpy(queue->queue + write_pos * queue->item_size,
|
||||
pvItemToQueue, queue->item_size);
|
||||
}
|
||||
|
||||
/* indicates a required context switch */
|
||||
bool ctx_switch = false;
|
||||
|
||||
/* unlock waiting receiving thread */
|
||||
if (queue->receiving.next != NULL) {
|
||||
list_node_t *next = list_remove_head(&queue->receiving);
|
||||
thread_t *proc = container_of((clist_node_t*)next, thread_t, rq_entry);
|
||||
sched_set_status(proc, STATUS_PENDING);
|
||||
ctx_switch = proc->priority < sched_threads[thread_getpid()]->priority;
|
||||
|
||||
DEBUG("%s pid=%d queue=%p unlock waiting pid=%d switch=%d\n",
|
||||
__func__, thread_getpid(), xQueue, proc->pid, ctx_switch);
|
||||
}
|
||||
|
||||
if (ctx_switch && pxHigherPriorityTaskWoken) {
|
||||
*pxHigherPriorityTaskWoken = pdTRUE;
|
||||
vTaskExitCritical(0);
|
||||
}
|
||||
else if (ctx_switch) {
|
||||
vTaskExitCritical(0);
|
||||
/* sets only the sched_context_switch_request in ISRs */
|
||||
thread_yield_higher();
|
||||
}
|
||||
else {
|
||||
vTaskExitCritical(0);
|
||||
}
|
||||
|
||||
DEBUG("%s pid=%d queue=%p return pdPASS\n", __func__,
|
||||
thread_getpid(), xQueue);
|
||||
|
||||
/* in all cases vTaskExitCritical has been called already */
|
||||
return pdPASS;
|
||||
}
|
||||
else if (xTicksToWait == 0 || irq_is_in()) {
|
||||
/* if there was no space and timeout = 0, return with error */
|
||||
DEBUG("%s pid=%d queue=%p return errQUEUE_FULL\n", __func__,
|
||||
thread_getpid(), xQueue);
|
||||
vTaskExitCritical(0);
|
||||
return errQUEUE_FULL;
|
||||
}
|
||||
else {
|
||||
/* suspend the calling thread to wait for space in the queue */
|
||||
thread_t *me = (thread_t*)sched_active_thread;
|
||||
sched_set_status(me, STATUS_SEND_BLOCKED);
|
||||
/* waiting list is sorted by priority */
|
||||
thread_add_to_list(&queue->sending, me);
|
||||
|
||||
DEBUG("%s pid=%d queue=%p suspended calling thread\n", __func__,
|
||||
thread_getpid(), xQueue);
|
||||
vTaskExitCritical(0);
|
||||
thread_yield_higher();
|
||||
|
||||
/* TODO timeout handling with xTicksToWait */
|
||||
DEBUG("%s pid=%d queue=%p continue calling thread\n", __func__,
|
||||
thread_getpid(), xQueue);
|
||||
}
|
||||
/* in all cases vTaskExitCritical has been called already */
|
||||
}
|
||||
return errQUEUE_FULL;
|
||||
}
|
||||
|
||||
BaseType_t IRAM_ATTR _queue_generic_recv (QueueHandle_t xQueue,
|
||||
void * const pvBuffer,
|
||||
TickType_t xTicksToWait,
|
||||
const BaseType_t xJustPeeking,
|
||||
BaseType_t * const pxHigherPriorityTaskWoken)
|
||||
{
|
||||
DEBUG("%s pid=%d prio=%d queue=%p wait=%u peek=%u woken=%p isr=%d\n", __func__,
|
||||
thread_getpid(), sched_threads[thread_getpid()]->priority,
|
||||
xQueue, xTicksToWait, xJustPeeking, pxHigherPriorityTaskWoken,
|
||||
irq_is_in());
|
||||
|
||||
assert(xQueue != NULL);
|
||||
|
||||
_queue_t* queue = (_queue_t*)xQueue;
|
||||
|
||||
while (1) {
|
||||
vTaskEnterCritical(0);
|
||||
|
||||
/* if there is at least one item in the queue */
|
||||
if (queue->item_level > 0) {
|
||||
/* if the item has no 0 size, copy it from queue to buffer */
|
||||
if (queue->item_size && queue->item_num && queue->queue && pvBuffer) {
|
||||
memcpy(pvBuffer,
|
||||
queue->queue + queue->item_front * queue->item_size,
|
||||
queue->item_size);
|
||||
}
|
||||
|
||||
|
||||
/* when only peeking leave the element in queue */
|
||||
if (xJustPeeking == pdTRUE) {
|
||||
DEBUG("%s pid=%d queue=%p return pdPASS\n", __func__,
|
||||
thread_getpid(), xQueue);
|
||||
vTaskExitCritical(0);
|
||||
return pdPASS;
|
||||
}
|
||||
|
||||
/* remove element from queue */
|
||||
queue->item_front = (queue->item_front + 1) % queue->item_num;
|
||||
queue->item_level--;
|
||||
|
||||
/* return if there is no waiting sending thread */
|
||||
if (queue->sending.next == NULL) {
|
||||
DEBUG("%s pid=%d queue=%p return pdPASS\n", __func__,
|
||||
thread_getpid(), xQueue);
|
||||
vTaskExitCritical(0);
|
||||
return pdPASS;
|
||||
}
|
||||
|
||||
/* otherwise unlock the waiting sending thread */
|
||||
list_node_t *next = list_remove_head(&queue->sending);
|
||||
thread_t *proc = container_of((clist_node_t*)next, thread_t, rq_entry);
|
||||
sched_set_status(proc, STATUS_PENDING);
|
||||
|
||||
/* test whether context switch is required */
|
||||
bool ctx_switch = proc->priority < sched_threads[thread_getpid()]->priority;
|
||||
|
||||
DEBUG("%s pid=%d queue=%p unlock waiting pid=%d switch=%d\n",
|
||||
__func__, thread_getpid(), xQueue, proc->pid, ctx_switch);
|
||||
|
||||
if (ctx_switch && pxHigherPriorityTaskWoken) {
|
||||
*pxHigherPriorityTaskWoken = pdTRUE;
|
||||
vTaskExitCritical(0);
|
||||
}
|
||||
else if (ctx_switch) {
|
||||
vTaskExitCritical(0);
|
||||
/* sets only the sched_context_switch_request in ISRs */
|
||||
sched_switch(proc->priority);
|
||||
}
|
||||
else {
|
||||
vTaskExitCritical(0);
|
||||
}
|
||||
|
||||
DEBUG("%s pid=%d queue=%p return pdPASS\n", __func__,
|
||||
thread_getpid(), xQueue);
|
||||
|
||||
/* in all cases vTaskExitCritical has been called already */
|
||||
return pdPASS;
|
||||
}
|
||||
else if (xTicksToWait == 0 || irq_is_in()) {
|
||||
/* if there was no item in the queue and timeout is 0, return with error */
|
||||
DEBUG("%s pid=%d queue=%p return errQUEUE_EMPTY\n", __func__,
|
||||
thread_getpid(), xQueue);
|
||||
vTaskExitCritical(0);
|
||||
return errQUEUE_EMPTY;
|
||||
}
|
||||
else {
|
||||
/* suspend the calling thread to wait for an item in the queue */
|
||||
thread_t *me = (thread_t*)sched_active_thread;
|
||||
sched_set_status(me, STATUS_RECEIVE_BLOCKED);
|
||||
/* waiting list is sorted by priority */
|
||||
thread_add_to_list(&queue->receiving, me);
|
||||
|
||||
DEBUG("%s pid=%d queue=%p suspended calling thread\n", __func__,
|
||||
thread_getpid(), xQueue);
|
||||
|
||||
vTaskExitCritical(0);
|
||||
thread_yield_higher();
|
||||
|
||||
/* TODO timeout handling with xTicksToWait */
|
||||
DEBUG("%s pid=%d queue=%p continue calling thread\n", __func__,
|
||||
thread_getpid(), xQueue);
|
||||
}
|
||||
/* in all cases vTaskExitCritical has been called already */
|
||||
}
|
||||
}
|
||||
|
||||
BaseType_t IRAM_ATTR xQueueGenericSend( QueueHandle_t xQueue,
|
||||
const void * const pvItemToQueue,
|
||||
TickType_t xTicksToWait,
|
||||
const BaseType_t xCopyPosition )
|
||||
{
|
||||
DEBUG("%s pid=%d prio=%d queue=%p wait=%u pos=%d\n", __func__,
|
||||
thread_getpid(), sched_threads[thread_getpid()]->priority,
|
||||
xQueue, xTicksToWait, xCopyPosition);
|
||||
|
||||
return _queue_generic_send(xQueue, pvItemToQueue, xCopyPosition,
|
||||
xTicksToWait, NULL);
|
||||
}
|
||||
|
||||
BaseType_t IRAM_ATTR xQueueGenericSendFromISR( QueueHandle_t xQueue,
|
||||
const void * const pvItemToQueue,
|
||||
BaseType_t * const pxHigherPriorityTaskWoken,
|
||||
const BaseType_t xCopyPosition )
|
||||
{
|
||||
DEBUG("%s pid=%d prio=%d queue=%p pos=%d woken=%p\n", __func__,
|
||||
thread_getpid(), sched_threads[thread_getpid()]->priority,
|
||||
xQueue, xCopyPosition, pxHigherPriorityTaskWoken);
|
||||
|
||||
return _queue_generic_send(xQueue, pvItemToQueue, xCopyPosition,
|
||||
0, pxHigherPriorityTaskWoken);
|
||||
}
|
||||
|
||||
BaseType_t IRAM_ATTR xQueueGenericReceive (QueueHandle_t xQueue,
|
||||
void * const pvBuffer,
|
||||
TickType_t xTicksToWait,
|
||||
const BaseType_t xJustPeeking)
|
||||
{
|
||||
DEBUG("%s pid=%d prio=%d queue=%p wait=%u peek=%d\n", __func__,
|
||||
thread_getpid(), sched_threads[thread_getpid()]->priority,
|
||||
xQueue, xTicksToWait, xJustPeeking);
|
||||
|
||||
return _queue_generic_recv(xQueue, pvBuffer, xTicksToWait,
|
||||
xJustPeeking, NULL);
|
||||
}
|
||||
|
||||
BaseType_t IRAM_ATTR xQueueReceiveFromISR (QueueHandle_t xQueue,
|
||||
void * const pvBuffer,
|
||||
BaseType_t * const pxHigherPriorityTaskWoken)
|
||||
{
|
||||
DEBUG("%s pid=%d prio=%d queue=%p woken=%p\n", __func__,
|
||||
thread_getpid(), sched_threads[thread_getpid()]->priority,
|
||||
xQueue, pxHigherPriorityTaskWoken);
|
||||
|
||||
return _queue_generic_recv(xQueue, pvBuffer, 0,
|
||||
0, pxHigherPriorityTaskWoken);
|
||||
}
|
||||
|
||||
UBaseType_t uxQueueMessagesWaiting( QueueHandle_t xQueue )
|
||||
{
|
||||
assert(xQueue != NULL);
|
||||
|
||||
_queue_t* queue = (_queue_t*)xQueue;
|
||||
return queue->item_level;
|
||||
}
|
||||
|
||||
BaseType_t xQueueGiveFromISR (QueueHandle_t xQueue,
|
||||
BaseType_t * const pxHigherPriorityTaskWoken)
|
||||
{
|
||||
/* this function only satisfies the linker and should not be called */
|
||||
assert(0);
|
||||
|
||||
DEBUG("%s\n", __func__);
|
||||
return pdFALSE;
|
||||
}
|
||||
|
||||
#endif /* DOXYGEN */
|
176
cpu/esp8266/freertos/semphr.c
Normal file
176
cpu/esp8266/freertos/semphr.c
Normal file
@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*
|
||||
* FreeRTOS to RIOT-OS adaption module for source code compatibility
|
||||
*/
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_common.h"
|
||||
#include "irq_arch.h"
|
||||
#include "log.h"
|
||||
#include "mutex.h"
|
||||
#include "rmutex.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
||||
/*
|
||||
* In FreeRTOS different types of semaphores, mutexes and queues are all
|
||||
* mapped to a single generic queue type. With all these different types,
|
||||
* single functions for send, receive, give and take are then used. To be
|
||||
* able to dsitinguish between these different types in RIOT, we need typed
|
||||
* objects.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t type; /* type of the mutex, MUST be the first element */
|
||||
mutex_t mutex; /* the mutex */
|
||||
} _mutex_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t type; /* type of the mutex, MUST be the first element */
|
||||
rmutex_t rmutex; /* the mutex */
|
||||
} _rmutex_t;
|
||||
|
||||
SemaphoreHandle_t xSemaphoreCreateMutex(void)
|
||||
{
|
||||
_mutex_t* _tmp = (_mutex_t*)malloc (sizeof(_mutex_t));
|
||||
_tmp->type = queueQUEUE_TYPE_MUTEX;
|
||||
mutex_init(&_tmp->mutex);
|
||||
|
||||
DEBUG("%s mutex=%p\n", __func__, _tmp);
|
||||
return _tmp;
|
||||
}
|
||||
|
||||
void vSemaphoreDelete( SemaphoreHandle_t xSemaphore )
|
||||
{
|
||||
DEBUG("%s mutex=%p\n", __func__, xSemaphore);
|
||||
|
||||
assert(xSemaphore != NULL);
|
||||
free(xSemaphore);
|
||||
}
|
||||
|
||||
BaseType_t xSemaphoreGive (SemaphoreHandle_t xSemaphore)
|
||||
{
|
||||
DEBUG("%s mutex=%p\n", __func__, xSemaphore);
|
||||
|
||||
assert(xSemaphore != NULL);
|
||||
|
||||
uint8_t type = ((_mutex_t*)xSemaphore)->type;
|
||||
mutex_t* mutex= &((_mutex_t*)xSemaphore)->mutex;
|
||||
|
||||
switch (type) {
|
||||
case queueQUEUE_TYPE_MUTEX:
|
||||
mutex_unlock(mutex);
|
||||
break;
|
||||
case queueQUEUE_TYPE_RECURSIVE_MUTEX:
|
||||
return xSemaphoreGiveRecursive (xSemaphore);
|
||||
default:
|
||||
return xQueueGenericSend(xSemaphore, NULL, 0, queueSEND_TO_BACK);
|
||||
}
|
||||
|
||||
return pdTRUE;
|
||||
}
|
||||
|
||||
BaseType_t xSemaphoreTake (SemaphoreHandle_t xSemaphore,
|
||||
TickType_t xTicksToWait)
|
||||
{
|
||||
DEBUG("%s mutex=%p wait=%u\n", __func__, xSemaphore, xTicksToWait);
|
||||
|
||||
assert(xSemaphore != NULL);
|
||||
|
||||
uint8_t type = ((_mutex_t*)xSemaphore)->type;
|
||||
mutex_t* mutex= &((_mutex_t*)xSemaphore)->mutex;
|
||||
|
||||
switch (type) {
|
||||
case queueQUEUE_TYPE_MUTEX:
|
||||
{
|
||||
if (xTicksToWait == 0) {
|
||||
return (mutex_trylock(mutex) == 1) ? pdPASS : pdFAIL;
|
||||
}
|
||||
else {
|
||||
mutex_lock(mutex);
|
||||
/* TODO timeout handling */
|
||||
return pdTRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case queueQUEUE_TYPE_RECURSIVE_MUTEX:
|
||||
return xSemaphoreTakeRecursive (xSemaphore, xTicksToWait);
|
||||
|
||||
default:
|
||||
return xQueueGenericReceive(xSemaphore, NULL, xTicksToWait, pdFALSE);
|
||||
}
|
||||
}
|
||||
|
||||
SemaphoreHandle_t xSemaphoreCreateRecursiveMutex(void)
|
||||
{
|
||||
_rmutex_t* _tmp = (_rmutex_t*)malloc (sizeof(_rmutex_t));
|
||||
_tmp->type = queueQUEUE_TYPE_RECURSIVE_MUTEX;
|
||||
rmutex_init(&_tmp->rmutex);
|
||||
|
||||
DEBUG("%s rmutex=%p\n", __func__, _tmp);
|
||||
|
||||
return _tmp;
|
||||
}
|
||||
|
||||
BaseType_t xSemaphoreGiveRecursive (SemaphoreHandle_t xSemaphore)
|
||||
{
|
||||
DEBUG("%s rmutex=%p\n", __func__, xSemaphore);
|
||||
|
||||
assert(xSemaphore != NULL);
|
||||
assert(((_rmutex_t*)xSemaphore)->type == queueQUEUE_TYPE_RECURSIVE_MUTEX);
|
||||
|
||||
rmutex_unlock(&((_rmutex_t*)xSemaphore)->rmutex);
|
||||
return pdTRUE;
|
||||
}
|
||||
|
||||
BaseType_t xSemaphoreTakeRecursive (SemaphoreHandle_t xSemaphore,
|
||||
TickType_t xTicksToWait)
|
||||
{
|
||||
DEBUG("%s rmutex=%p wait=%u\n", __func__, xSemaphore, xTicksToWait);
|
||||
|
||||
assert(xSemaphore != NULL);
|
||||
assert(((_rmutex_t*)xSemaphore)->type == queueQUEUE_TYPE_RECURSIVE_MUTEX);
|
||||
|
||||
BaseType_t ret = pdTRUE;
|
||||
rmutex_t* rmutex = &((_rmutex_t*)xSemaphore)->rmutex;
|
||||
|
||||
if (xTicksToWait == 0) {
|
||||
ret = (rmutex_trylock(rmutex) == 1) ? pdPASS : pdFAIL;
|
||||
}
|
||||
else {
|
||||
rmutex_lock(&((_rmutex_t*)xSemaphore)->rmutex);
|
||||
/* TODO timeout handling */
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void vPortCPUAcquireMutex(portMUX_TYPE *mux)
|
||||
{
|
||||
DEBUG("%s pid=%d prio=%d mux=%p\n", __func__,
|
||||
thread_getpid(), sched_threads[thread_getpid()]->priority, mux);
|
||||
critical_enter();
|
||||
mutex_lock(mux); /* lock the mutex with interrupts disabled */
|
||||
critical_exit();
|
||||
}
|
||||
|
||||
void vPortCPUReleaseMutex(portMUX_TYPE *mux)
|
||||
{
|
||||
DEBUG("%s pid=%d prio=%d mux=%p\n", __func__,
|
||||
thread_getpid(), sched_threads[thread_getpid()]->priority, mux);
|
||||
critical_enter();
|
||||
mutex_unlock(mux); /* unlock the mutex with interrupts disabled */
|
||||
critical_exit();
|
||||
}
|
||||
|
||||
#endif /* DOXYGEN */
|
226
cpu/esp8266/freertos/task.c
Normal file
226
cpu/esp8266/freertos/task.c
Normal file
@ -0,0 +1,226 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*
|
||||
* FreeRTOS to RIOT-OS adaption module for source code compatibility
|
||||
*/
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_common.h"
|
||||
#include "esp_attr.h"
|
||||
#include "log.h"
|
||||
#include "syscalls.h"
|
||||
#include "thread.h"
|
||||
#include "xtimer.h"
|
||||
|
||||
#ifdef MCU_ESP32
|
||||
#include "soc/soc.h"
|
||||
#endif
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
#define MHZ 1000000
|
||||
|
||||
#ifdef MCU_ESP8266
|
||||
#include "rom/ets_sys.h"
|
||||
|
||||
#define PRO_CPU_NUM (0)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Architecture specific data of thread control blocks
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t saved_int_state;
|
||||
uint32_t critical_nesting;
|
||||
} thread_arch_ext_t;
|
||||
|
||||
volatile thread_arch_ext_t threads_arch_exts[KERNEL_PID_LAST + 1] = {};
|
||||
|
||||
BaseType_t xTaskCreatePinnedToCore (TaskFunction_t pvTaskCode,
|
||||
const char * const pcName,
|
||||
const uint32_t usStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
TaskHandle_t * const pvCreatedTask,
|
||||
const BaseType_t xCoreID)
|
||||
{
|
||||
/* FreeRTOS priority values have to be inverted */
|
||||
uxPriority = SCHED_PRIO_LEVELS - uxPriority - 1;
|
||||
|
||||
DEBUG("%s name=%s size=%d prio=%d pvCreatedTask=%p ",
|
||||
__func__, pcName, usStackDepth, uxPriority, pvCreatedTask);
|
||||
|
||||
char* stack = malloc(usStackDepth + sizeof(thread_t));
|
||||
|
||||
if (!stack) {
|
||||
LOG_TAG_ERROR("freertos", "not enough memory to create task %s with "
|
||||
"stack size of %d bytes\n", pcName, usStackDepth);
|
||||
abort();
|
||||
return pdFALSE;
|
||||
}
|
||||
kernel_pid_t pid = thread_create(stack,
|
||||
usStackDepth + sizeof(thread_t),
|
||||
uxPriority,
|
||||
THREAD_CREATE_WOUT_YIELD |
|
||||
THREAD_CREATE_STACKTEST,
|
||||
(thread_task_func_t)pvTaskCode,
|
||||
pvParameters, pcName);
|
||||
DEBUG("pid=%d\n", pid);
|
||||
|
||||
if (pvCreatedTask) {
|
||||
*pvCreatedTask = (TaskHandle_t)(0L + pid);
|
||||
}
|
||||
|
||||
return (pid < 0) ? pdFALSE : pdTRUE;
|
||||
}
|
||||
|
||||
BaseType_t xTaskCreate (TaskFunction_t pvTaskCode,
|
||||
const char * const pcName,
|
||||
const uint32_t usStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
TaskHandle_t * const pvCreatedTask)
|
||||
{
|
||||
return xTaskCreatePinnedToCore (pvTaskCode,
|
||||
pcName,
|
||||
usStackDepth,
|
||||
pvParameters,
|
||||
uxPriority,
|
||||
pvCreatedTask,
|
||||
PRO_CPU_NUM);
|
||||
}
|
||||
|
||||
void vTaskDelete (TaskHandle_t xTaskToDelete)
|
||||
{
|
||||
DEBUG("%s pid=%d task=%p\n", __func__, thread_getpid(), xTaskToDelete);
|
||||
|
||||
assert(xTaskToDelete != NULL);
|
||||
|
||||
uint32_t pid = (uint32_t)xTaskToDelete;
|
||||
|
||||
/* remove old task from scheduling */
|
||||
thread_t* thread = (thread_t*)sched_threads[pid];
|
||||
sched_set_status(thread, STATUS_STOPPED);
|
||||
sched_threads[pid] = NULL;
|
||||
sched_num_threads--;
|
||||
sched_active_thread = NULL;
|
||||
|
||||
/* determine the new running task */
|
||||
sched_run();
|
||||
}
|
||||
|
||||
TaskHandle_t xTaskGetCurrentTaskHandle(void)
|
||||
{
|
||||
DEBUG("%s pid=%d\n", __func__, thread_getpid());
|
||||
|
||||
uint32_t pid = thread_getpid();
|
||||
return (TaskHandle_t)pid;
|
||||
}
|
||||
|
||||
void vTaskDelay( const TickType_t xTicksToDelay )
|
||||
{
|
||||
DEBUG("%s xTicksToDelay=%d\n", __func__, xTicksToDelay);
|
||||
#if defined(MCU_ESP8266) && defined(MODULE_ESP_WIFI_ANY)
|
||||
uint64_t us = xTicksToDelay * MHZ / xPortGetTickRateHz();
|
||||
xtimer_usleep(us);
|
||||
#endif
|
||||
}
|
||||
|
||||
TickType_t xTaskGetTickCount (void)
|
||||
{
|
||||
return system_get_time() / USEC_PER_MSEC / portTICK_PERIOD_MS;
|
||||
}
|
||||
|
||||
void vTaskEnterCritical( portMUX_TYPE *mux )
|
||||
{
|
||||
#ifdef MCU_ESP8266
|
||||
/* we have to return on NMI */
|
||||
if (NMIIrqIsOn) {
|
||||
return;
|
||||
}
|
||||
#endif /* MCU_ESP8266 */
|
||||
|
||||
/* disable interrupts */
|
||||
uint32_t state = irq_disable();
|
||||
|
||||
/* determine calling thread pid (can't fail) */
|
||||
kernel_pid_t my_pid = thread_getpid();
|
||||
|
||||
DEBUG("%s pid=%d prio=%d mux=%p\n", __func__,
|
||||
my_pid, sched_threads[my_pid]->priority, mux);
|
||||
|
||||
/* acquire the mutex with interrupts disabled */
|
||||
if (mux) {
|
||||
mutex_lock(mux); /* TODO should be only a spin lock */
|
||||
}
|
||||
|
||||
/* increment nesting counter and save old interrupt level */
|
||||
threads_arch_exts[my_pid].critical_nesting++;
|
||||
if (threads_arch_exts[my_pid].critical_nesting == 1) {
|
||||
threads_arch_exts[my_pid].saved_int_state = state;
|
||||
}
|
||||
}
|
||||
|
||||
void vTaskExitCritical( portMUX_TYPE *mux )
|
||||
{
|
||||
#ifdef MCU_ESP8266
|
||||
/* we have to return on NMI */
|
||||
if (NMIIrqIsOn) {
|
||||
return;
|
||||
}
|
||||
#endif /* MCU_ESP8266 */
|
||||
|
||||
/* determine calling thread pid (can't fail) */
|
||||
kernel_pid_t my_pid = thread_getpid();
|
||||
|
||||
DEBUG("%s pid=%d prio=%d mux=%p\n", __func__,
|
||||
my_pid, sched_threads[my_pid]->priority, mux);
|
||||
|
||||
/* release the mutex with interrupts disabled */
|
||||
if (mux) {
|
||||
mutex_unlock(mux); /* TODO should be only a spin lock */
|
||||
}
|
||||
|
||||
/* decrement nesting counter and restore old interrupt level */
|
||||
if (threads_arch_exts[my_pid].critical_nesting) {
|
||||
threads_arch_exts[my_pid].critical_nesting--;
|
||||
if (threads_arch_exts[my_pid].critical_nesting == 0) {
|
||||
irq_restore(threads_arch_exts[my_pid].saved_int_state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vTaskStepTick(const TickType_t xTicksToJump)
|
||||
{
|
||||
DEBUG("%s xTicksToJump=%d\n", __func__, xTicksToJump);
|
||||
/*
|
||||
* TODO:
|
||||
* At the moment, only the calling task is set to sleep state. Usually, the
|
||||
* complete system should sleep but not only the task.
|
||||
*/
|
||||
vTaskDelay(xTicksToJump);
|
||||
}
|
||||
|
||||
TickType_t prvGetExpectedIdleTime(void)
|
||||
{
|
||||
DEBUG("%s\n", __func__);
|
||||
/*
|
||||
* TODO:
|
||||
* Since we are not able to estimate the time the system will be idle,
|
||||
* we simply return 0.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* DOXYGEN */
|
129
cpu/esp8266/freertos/timers.c
Normal file
129
cpu/esp8266/freertos/timers.c
Normal file
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*
|
||||
* FreeRTOS to RIOT-OS adaption module for source code compatibility
|
||||
*/
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_common.h"
|
||||
#include "esp_attr.h"
|
||||
#include "log.h"
|
||||
#include "xtimer.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/timers.h"
|
||||
|
||||
typedef struct {
|
||||
xtimer_t xtimer; /* xtimer object */
|
||||
const char* name; /* FreeRTOS timer name */
|
||||
uint32_t period; /* in us */
|
||||
bool autoreload; /* FreeRTOS timer reload indicator */
|
||||
const void* timerid; /* FreeRTOS timer id */
|
||||
TimerCallbackFunction_t cb; /* FreeRTOS callback function */
|
||||
} freertos_xtimer_t;
|
||||
|
||||
static void IRAM_ATTR _xtimer_callback (void *arg)
|
||||
{
|
||||
assert(arg != NULL);
|
||||
|
||||
freertos_xtimer_t* timer = (freertos_xtimer_t*)arg;
|
||||
|
||||
if (timer->autoreload) {
|
||||
xtimer_set(&timer->xtimer, timer->period);
|
||||
}
|
||||
|
||||
if (timer->cb) {
|
||||
timer->cb(arg);
|
||||
}
|
||||
}
|
||||
|
||||
TimerHandle_t xTimerCreate (const char * const pcTimerName,
|
||||
const TickType_t xTimerPeriod,
|
||||
const UBaseType_t uxAutoReload,
|
||||
void * const pvTimerID,
|
||||
TimerCallbackFunction_t pxCallbackFunction)
|
||||
{
|
||||
freertos_xtimer_t* timer = malloc(sizeof(freertos_xtimer_t));
|
||||
if (timer == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* FreeRTOS timer parameter */
|
||||
timer->name = pcTimerName;
|
||||
timer->period = xTimerPeriod * portTICK_PERIOD_MS * USEC_PER_MSEC;
|
||||
timer->autoreload = uxAutoReload;
|
||||
timer->timerid = pvTimerID;
|
||||
timer->cb = pxCallbackFunction;
|
||||
|
||||
/* xtimer parameter */
|
||||
timer->xtimer.callback = _xtimer_callback;
|
||||
timer->xtimer.arg = timer;
|
||||
|
||||
DEBUG("%s %p %s %d %u\n", __func__, timer, pcTimerName, xTimerPeriod, uxAutoReload);
|
||||
return timer;
|
||||
}
|
||||
|
||||
BaseType_t xTimerDelete(TimerHandle_t xTimer, TickType_t xBlockTime)
|
||||
{
|
||||
DEBUG("%s %p %d\n", __func__, xTimer, xBlockTime);
|
||||
assert(xTimer != NULL);
|
||||
|
||||
freertos_xtimer_t* timer = (freertos_xtimer_t*)xTimer;
|
||||
xtimer_remove(&timer->xtimer);
|
||||
free(timer);
|
||||
|
||||
return pdTRUE;
|
||||
}
|
||||
|
||||
BaseType_t xTimerStart (TimerHandle_t xTimer, TickType_t xBlockTime)
|
||||
{
|
||||
DEBUG("%s %p %d\n", __func__, xTimer, xBlockTime);
|
||||
assert(xTimer != NULL);
|
||||
|
||||
freertos_xtimer_t* timer = (freertos_xtimer_t*)xTimer;
|
||||
xtimer_set(&timer->xtimer, timer->period);
|
||||
|
||||
return pdTRUE;
|
||||
}
|
||||
|
||||
BaseType_t xTimerStop (TimerHandle_t xTimer, TickType_t xBlockTime)
|
||||
{
|
||||
DEBUG("%s %p %d\n", __func__, xTimer, xBlockTime);
|
||||
assert(xTimer != NULL);
|
||||
|
||||
freertos_xtimer_t* timer = (freertos_xtimer_t*)xTimer;
|
||||
xtimer_remove(&timer->xtimer);
|
||||
|
||||
return pdTRUE;
|
||||
}
|
||||
|
||||
BaseType_t xTimerReset (TimerHandle_t xTimer, TickType_t xBlockTime)
|
||||
{
|
||||
DEBUG("%s %p %d\n", __func__, xTimer, xBlockTime);
|
||||
assert(xTimer != NULL);
|
||||
|
||||
freertos_xtimer_t* timer = (freertos_xtimer_t*)xTimer;
|
||||
xtimer_set(&timer->xtimer, xBlockTime * portTICK_PERIOD_MS * USEC_PER_MSEC);
|
||||
|
||||
return pdTRUE;
|
||||
}
|
||||
|
||||
void *pvTimerGetTimerID(const TimerHandle_t xTimer)
|
||||
{
|
||||
assert(xTimer != NULL);
|
||||
|
||||
freertos_xtimer_t* timer = (freertos_xtimer_t*)xTimer;
|
||||
return (void*)timer->timerid;
|
||||
}
|
||||
|
||||
#endif /* DOXYGEN */
|
69
cpu/esp8266/include/freertos/FreeRTOS.h
Normal file
69
cpu/esp8266/include/freertos/FreeRTOS.h
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*
|
||||
* FreeRTOS to RIOT-OS adaption module for source code compatibility
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_FREERTOS_H
|
||||
#define FREERTOS_FREERTOS_H
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#include "freertos/portmacro.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define configMAX_PRIORITIES SCHED_PRIO_LEVELS
|
||||
|
||||
#ifndef configASSERT
|
||||
#define configASSERT assert
|
||||
#endif
|
||||
|
||||
#define portTICK_PERIOD_MS 10
|
||||
#define portTickType TickType_t
|
||||
|
||||
#define portTICK_RATE_MS portTICK_PERIOD_MS
|
||||
|
||||
#define BaseType_t portBASE_TYPE
|
||||
#define UBaseType_t unsigned portBASE_TYPE
|
||||
|
||||
typedef uint32_t TickType_t;
|
||||
|
||||
uint32_t xPortGetTickRateHz(void);
|
||||
BaseType_t xPortInIsrContext(void);
|
||||
|
||||
/*
|
||||
* PLEASE NOTE: Following definitions were copied directly from the FreeRTOS
|
||||
* distribution and are under the following copyright:
|
||||
*
|
||||
* FreeRTOS V8.2.0 - Copyright (C) 2015 Real Time Engineers Ltd.
|
||||
* All rights reserved
|
||||
*
|
||||
* FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License (version 2) as published by the
|
||||
* Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||
*
|
||||
* Full license text is available on the following
|
||||
* link: http://www.freertos.org/a00114.html
|
||||
*/
|
||||
|
||||
#define pdFALSE ( ( BaseType_t ) 0 )
|
||||
#define pdTRUE ( ( BaseType_t ) 1 )
|
||||
#define pdPASS ( pdTRUE )
|
||||
#define pdFAIL ( pdFALSE )
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/queue.h"
|
||||
|
||||
#endif /* DOXYGEN */
|
||||
#endif /* FREERTOS_FREERTOS_H */
|
46
cpu/esp8266/include/freertos/event_groups.h
Normal file
46
cpu/esp8266/include/freertos/event_groups.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*
|
||||
* FreeRTOS to RIOT-OS adaption module for source code compatibility
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_EVENT_GROUPS_H
|
||||
#define FREERTOS_EVENT_GROUPS_H
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void * EventGroupHandle_t;
|
||||
typedef TickType_t EventBits_t;
|
||||
|
||||
EventGroupHandle_t xEventGroupCreate (void);
|
||||
|
||||
void vEventGroupDelete (EventGroupHandle_t xEventGroup);
|
||||
|
||||
EventBits_t xEventGroupSetBits (EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToSet);
|
||||
|
||||
EventBits_t xEventGroupClearBits (EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToClear );
|
||||
|
||||
EventBits_t xEventGroupWaitBits (const EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToWaitFor,
|
||||
const BaseType_t xClearOnExit,
|
||||
const BaseType_t xWaitForAllBits,
|
||||
TickType_t xTicksToWait);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DOXYGEN */
|
||||
#endif /* FREERTOS_EVENT_GROUPS_H */
|
63
cpu/esp8266/include/freertos/portmacro.h
Normal file
63
cpu/esp8266/include/freertos/portmacro.h
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*
|
||||
* FreeRTOS to RIOT-OS adaption module for source code compatibility
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_PORTMACRO_H
|
||||
#define FREERTOS_PORTMACRO_H
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
#include "mutex.h"
|
||||
#include "irq.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define portBASE_TYPE int
|
||||
#define portUBASE_TYPE unsigned portBASE_TYPE
|
||||
|
||||
#define portMAX_DELAY 0xFFFFFFFF
|
||||
|
||||
#define portMUX_TYPE mutex_t
|
||||
#define portMUX_INITIALIZER_UNLOCKED MUTEX_INIT
|
||||
|
||||
#define portYIELD_FROM_ISR thread_yield_higher
|
||||
|
||||
#ifdef MCU_ESP32
|
||||
|
||||
#define portNUM_PROCESSORS 2
|
||||
#define xPortGetCoreID() PRO_CPU_NUM
|
||||
|
||||
#define portENTER_CRITICAL(pm) mutex_lock(pm)
|
||||
#define portEXIT_CRITICAL(pm) mutex_unlock(pm)
|
||||
#define portENTER_CRITICAL_NESTED irq_disable
|
||||
#define portEXIT_CRITICAL_NESTED irq_restore
|
||||
|
||||
#define portENTER_CRITICAL_ISR vTaskEnterCritical
|
||||
#define portEXIT_CRITICAL_ISR vTaskExitCritical
|
||||
|
||||
#else /* MCU_ESP32 */
|
||||
|
||||
#define portNUM_PROCESSORS 1
|
||||
#define xPortGetCoreID() PRO_CPU_NUM
|
||||
|
||||
#define portENTER_CRITICAL vTaskEnterCritical
|
||||
#define portEXIT_CRITICAL vTaskExitCritical
|
||||
|
||||
#endif /* MCU_ESP32 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DOXYGEN */
|
||||
#endif /* FREERTOS_PORTMACRO_H */
|
118
cpu/esp8266/include/freertos/queue.h
Normal file
118
cpu/esp8266/include/freertos/queue.h
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*
|
||||
* FreeRTOS to RIOT-OS adaption module for source code compatibility
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_QUEUE_H
|
||||
#define FREERTOS_QUEUE_H
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define xQueueHandle QueueHandle_t
|
||||
|
||||
typedef void* QueueHandle_t;
|
||||
|
||||
QueueHandle_t xQueueGenericCreate (const UBaseType_t uxQueueLength,
|
||||
const UBaseType_t uxItemSize,
|
||||
const uint8_t ucQueueType);
|
||||
|
||||
QueueHandle_t xQueueCreateCountingSemaphore (const UBaseType_t uxMaxCount,
|
||||
const UBaseType_t uxInitialCount);
|
||||
|
||||
void vQueueDelete (QueueHandle_t xQueue);
|
||||
|
||||
BaseType_t xQueueGenericReset (QueueHandle_t xQueue, BaseType_t xNewQueue);
|
||||
|
||||
BaseType_t xQueueGenericReceive (QueueHandle_t xQueue,
|
||||
void * const pvBuffer,
|
||||
TickType_t xTicksToWait,
|
||||
const BaseType_t xJustPeeking);
|
||||
|
||||
BaseType_t xQueueGenericSend (QueueHandle_t xQueue,
|
||||
const void * const pvItemToQueue,
|
||||
TickType_t xTicksToWait,
|
||||
const BaseType_t xCopyPosition);
|
||||
|
||||
BaseType_t xQueueReceiveFromISR (QueueHandle_t xQueue, void * const pvBuffer,
|
||||
BaseType_t * const pxHigherPriorityTaskWoken);
|
||||
|
||||
BaseType_t xQueueGenericSendFromISR (QueueHandle_t xQueue,
|
||||
const void * const pvItemToQueue,
|
||||
BaseType_t * const pxHigherPriorityTaskWoken,
|
||||
const BaseType_t xCopyPosition );
|
||||
|
||||
BaseType_t xQueueGiveFromISR (QueueHandle_t xQueue,
|
||||
BaseType_t * const pxHigherPriorityTaskWoken);
|
||||
|
||||
UBaseType_t uxQueueMessagesWaiting( QueueHandle_t xQueue );
|
||||
|
||||
/*
|
||||
* PLEASE NOTE: Following definitions were copied directly from the FreeRTOS
|
||||
* distribution and are under the following copyright:
|
||||
*
|
||||
* FreeRTOS V8.2.0 - Copyright (C) 2015 Real Time Engineers Ltd.
|
||||
* All rights reserved
|
||||
*
|
||||
* FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License (version 2) as published by the
|
||||
* Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||
*
|
||||
* Full license text is available on the following
|
||||
* link: http://www.freertos.org/a00114.html
|
||||
*/
|
||||
|
||||
#define queueSEND_TO_BACK ( ( BaseType_t ) 0 )
|
||||
#define queueSEND_TO_FRONT ( ( BaseType_t ) 1 )
|
||||
#define queueOVERWRITE ( ( BaseType_t ) 2 )
|
||||
|
||||
#define queueQUEUE_TYPE_BASE ( ( uint8_t ) 0U )
|
||||
#define queueQUEUE_TYPE_SET ( ( uint8_t ) 0U )
|
||||
#define queueQUEUE_TYPE_MUTEX ( ( uint8_t ) 1U )
|
||||
#define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( ( uint8_t ) 2U )
|
||||
#define queueQUEUE_TYPE_BINARY_SEMAPHORE ( ( uint8_t ) 3U )
|
||||
#define queueQUEUE_TYPE_RECURSIVE_MUTEX ( ( uint8_t ) 4U )
|
||||
|
||||
#define errQUEUE_EMPTY ( ( BaseType_t ) 0 )
|
||||
#define errQUEUE_FULL ( ( BaseType_t ) 0 )
|
||||
#define errQUEUE_BLOCKED ( -4 )
|
||||
#define errQUEUE_YIELD ( -5 )
|
||||
|
||||
#define xQueueCreate( uxQueueLength, uxItemSize ) \
|
||||
xQueueGenericCreate( ( uxQueueLength ), ( uxItemSize ), ( queueQUEUE_TYPE_BASE ) )
|
||||
|
||||
#define xQueueReceive( xQueue, pvBuffer, xTicksToWait ) \
|
||||
xQueueGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), \
|
||||
pdFALSE )
|
||||
|
||||
#define xQueueSend( xQueue, pvItemToQueue, xTicksToWait ) \
|
||||
xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), \
|
||||
queueSEND_TO_BACK )
|
||||
|
||||
#define xQueueSendToBack( xQueue, pvItemToQueue, xTicksToWait ) \
|
||||
xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), \
|
||||
queueSEND_TO_BACK )
|
||||
|
||||
#define xQueueSendFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) \
|
||||
xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), \
|
||||
( pxHigherPriorityTaskWoken ), \
|
||||
queueSEND_TO_BACK )
|
||||
|
||||
#define xQueueReset( xQueue ) xQueueGenericReset( xQueue, pdFALSE )
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DOXYGEN */
|
||||
#endif /* FREERTOS_QUEUE_H */
|
81
cpu/esp8266/include/freertos/semphr.h
Normal file
81
cpu/esp8266/include/freertos/semphr.h
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*
|
||||
* FreeRTOS to RIOT-OS adaption module for source code compatibility
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_SEMPHR_H
|
||||
#define FREERTOS_SEMPHR_H
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "mutex.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void* SemaphoreHandle_t;
|
||||
|
||||
SemaphoreHandle_t xSemaphoreCreateMutex(void);
|
||||
SemaphoreHandle_t xSemaphoreCreateRecursiveMutex(void);
|
||||
|
||||
void vSemaphoreDelete (SemaphoreHandle_t xSemaphore);
|
||||
|
||||
BaseType_t xSemaphoreGive (SemaphoreHandle_t xSemaphore);
|
||||
BaseType_t xSemaphoreTake (SemaphoreHandle_t xSemaphore,
|
||||
TickType_t xTicksToWait);
|
||||
BaseType_t xSemaphoreGiveRecursive (SemaphoreHandle_t xSemaphore);
|
||||
BaseType_t xSemaphoreTakeRecursive (SemaphoreHandle_t xSemaphore,
|
||||
TickType_t xTicksToWait);
|
||||
|
||||
#define vPortCPUInitializeMutex(m) mutex_init(m)
|
||||
|
||||
void vPortCPUAcquireMutex (portMUX_TYPE *mux);
|
||||
void vPortCPUReleaseMutex (portMUX_TYPE *mux);
|
||||
|
||||
/*
|
||||
* PLEASE NOTE: Following definitions were copied directly from the FreeRTOS
|
||||
* distribution and are under the following copyright:
|
||||
*
|
||||
* FreeRTOS V8.2.0 - Copyright (C) 2015 Real Time Engineers Ltd.
|
||||
* All rights reserved
|
||||
*
|
||||
* FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License (version 2) as published by the
|
||||
* Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||
*
|
||||
* Full license text is available on the following
|
||||
* link: http://www.freertos.org/a00114.html
|
||||
*/
|
||||
|
||||
#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( uint8_t ) 0U )
|
||||
|
||||
#define xSemaphoreCreateBinary() \
|
||||
xQueueGenericCreate( ( UBaseType_t ) 1, \
|
||||
semSEMAPHORE_QUEUE_ITEM_LENGTH, \
|
||||
queueQUEUE_TYPE_BINARY_SEMAPHORE )
|
||||
#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) \
|
||||
xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) )
|
||||
|
||||
#define xSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken ) \
|
||||
xQueueReceiveFromISR( ( QueueHandle_t ) ( xSemaphore ), \
|
||||
NULL, ( pxHigherPriorityTaskWoken ) )
|
||||
|
||||
#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) \
|
||||
xQueueGiveFromISR( ( QueueHandle_t ) ( xSemaphore ), \
|
||||
( pxHigherPriorityTaskWoken ) )
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DOXYGEN */
|
||||
#endif /* FREERTOS_SEMPHR_H */
|
65
cpu/esp8266/include/freertos/task.h
Normal file
65
cpu/esp8266/include/freertos/task.h
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*
|
||||
* FreeRTOS to RIOT-OS adaption module for source code compatibility
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_TASK_H
|
||||
#define FREERTOS_TASK_H
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#include "thread.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define xTaskHandle TaskHandle_t
|
||||
#define tskNO_AFFINITY INT_MAX
|
||||
|
||||
#define taskDISABLE_INTERRUPTS portDISABLE_INTERRUPTS
|
||||
#define taskENABLE_INTERRUPTS portENABLE_INTERRUPTS
|
||||
|
||||
#define taskENTER_CRITICAL portENTER_CRITICAL
|
||||
#define taskEXIT_CRITICAL portEXIT_CRITICAL
|
||||
|
||||
typedef void (*TaskFunction_t)(void *);
|
||||
|
||||
typedef void* TaskHandle_t;
|
||||
|
||||
BaseType_t xTaskCreate(TaskFunction_t pvTaskCode,
|
||||
const char * const pcName,
|
||||
const uint32_t usStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
TaskHandle_t * const pvCreatedTask);
|
||||
|
||||
BaseType_t xTaskCreatePinnedToCore(TaskFunction_t pvTaskCode,
|
||||
const char * const pcName,
|
||||
const uint32_t usStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
TaskHandle_t * const pvCreatedTask,
|
||||
const BaseType_t xCoreID);
|
||||
|
||||
void vTaskDelete(TaskHandle_t xTaskToDelete);
|
||||
void vTaskDelay(const TickType_t xTicksToDelay);
|
||||
|
||||
TaskHandle_t xTaskGetCurrentTaskHandle(void);
|
||||
|
||||
void vTaskEnterCritical(portMUX_TYPE *mux);
|
||||
void vTaskExitCritical(portMUX_TYPE *mux);
|
||||
|
||||
TickType_t xTaskGetTickCount (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DOXYGEN */
|
||||
#endif /* FREERTOS_TASK_H */
|
45
cpu/esp8266/include/freertos/timers.h
Normal file
45
cpu/esp8266/include/freertos/timers.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*
|
||||
* FreeRTOS to RIOT-OS adaption module for source code compatibility
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_TIMERS_H
|
||||
#define FREERTOS_TIMERS_H
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "xtimer.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void* TimerHandle_t;
|
||||
|
||||
#define TimerCallbackFunction_t xtimer_callback_t
|
||||
#define tmrTIMER_CALLBACK TimerCallbackFunction_t
|
||||
|
||||
TimerHandle_t xTimerCreate (const char * const pcTimerName,
|
||||
const TickType_t xTimerPeriod,
|
||||
const UBaseType_t uxAutoReload,
|
||||
void * const pvTimerID,
|
||||
TimerCallbackFunction_t pxCallbackFunction);
|
||||
BaseType_t xTimerDelete(TimerHandle_t xTimer, TickType_t xBlockTime);
|
||||
BaseType_t xTimerStart (TimerHandle_t xTimer, TickType_t xBlockTime);
|
||||
BaseType_t xTimerStop (TimerHandle_t xTimer, TickType_t xBlockTime);
|
||||
BaseType_t xTimerReset (TimerHandle_t xTimer, TickType_t xTicksToWait);
|
||||
|
||||
void *pvTimerGetTimerID(const TimerHandle_t xTimer);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DOXYGEN */
|
||||
#endif /* FREERTOS_TIMERS_H */
|
24
cpu/esp8266/include/freertos/xtensa_api.h
Normal file
24
cpu/esp8266/include/freertos/xtensa_api.h
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*
|
||||
* FreeRTOS to RIOT-OS adaption module for source code compatibility
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_XTENSA_API_H
|
||||
#define FREERTOS_XTENSA_API_H
|
||||
|
||||
#include "xtensa/xtensa_api.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FREERTOS_XTENSA_API_H */
|
Loading…
Reference in New Issue
Block a user