1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

cpu/esp_common/freertos: missing functions/definitions for ESP-IDF v4.4

This commit is contained in:
Gunar Schorcht 2022-02-01 21:42:57 +01:00
parent 3e4dc10740
commit d4e061f635
9 changed files with 255 additions and 63 deletions

View File

@ -0,0 +1,36 @@
/*
* Copyright (C) 2022 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.
*/
/**
* @ingroup cpu_esp32
* @{
*
* @file
* @brief FreeRTOS configuration for ESP32 as required by ESP-IDF
*
* @author Gunar Schorcht <gunar@schorcht.net>
* @}
*/
#include "sdkconfig.h"
#ifndef FREERTOS_FREERTOSCONFIG_H
#define FREERTOS_FREERTOSCONFIG_H
#ifndef DOXYGEN
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif /* DOXYGEN */
#endif /* FREERTOS_FREERTOSCONFIG_H */

View File

@ -1,35 +0,0 @@
/*
* Copyright (C) 2018 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.
*/
/* This file is just a mapper for source code compatibility with ESP-IDF */
#ifndef DRIVER_GPIO_H
#define DRIVER_GPIO_H
#ifndef DOXYGEN
#ifdef __cplusplus
extern "C" {
#endif
/* the order of these includes is important */
#include "periph_conf.h"
#include "gpio_arch.h"
#define GPIO_NUM_MAX (40)
#define gpio_num_t gpio_t
#define gpio_pull_mode_t uint32_t
#define gpio_drive_cap_t gpio_drive_strength_t
#ifdef __cplusplus
}
#endif
#endif /* DOXYGEN */
#endif /* DRIVER_GPIO_H */

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2018 Gunar Schorcht
* Copyright (C) 2021 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
@ -31,4 +31,20 @@ BaseType_t xPortInIsrContext(void)
return irq_is_in();
}
UBaseType_t xPortSetInterruptMaskFromISR(void)
{
UBaseType_t state = irq_disable();
return state;
}
void vPortClearInterruptMaskFromISR(UBaseType_t state)
{
irq_restore(state);
}
bool xPortCanYield(void)
{
return irq_is_enabled();
}
#endif /* DOXYGEN */

View File

@ -47,23 +47,27 @@
typedef struct {
uint32_t saved_int_state;
uint32_t critical_nesting;
uint32_t notification_value;
bool notification_wait_for;
} 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)
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)
{
assert(xCoreID == 0 || xCoreID == tskNO_AFFINITY);
/* 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);
DEBUG("%s name=%s size=%d prio=%d pvCreatedTask=%p xCoreId=%d",
__func__, pcName, usStackDepth, uxPriority, pvCreatedTask, xCoreID);
char* stack = malloc(usStackDepth + sizeof(thread_t));
@ -89,23 +93,23 @@ BaseType_t xTaskCreatePinnedToCore (TaskFunction_t pvTaskCode,
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)
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);
return xTaskCreatePinnedToCore(pvTaskCode,
pcName,
usStackDepth,
pvParameters,
uxPriority,
pvCreatedTask,
PRO_CPU_NUM);
}
void vTaskDelete (TaskHandle_t xTaskToDelete)
void vTaskDelete(TaskHandle_t xTaskToDelete)
{
extern volatile thread_t *sched_active_thread;
DEBUG("%s pid=%d task=%p\n", __func__, thread_getpid(), xTaskToDelete);
@ -125,6 +129,36 @@ void vTaskDelete (TaskHandle_t xTaskToDelete)
sched_run();
}
void vTaskSuspend(TaskHandle_t xTaskToSuspend)
{
extern volatile thread_t *sched_active_thread;
DEBUG("%s pid=%d task=%p\n", __func__, thread_getpid(), xTaskToSuspend);
uint32_t pid = (xTaskToSuspend == NULL) ? (uint32_t)thread_getpid()
: (uint32_t)xTaskToSuspend;
assert(pid <= KERNEL_PID_LAST);
/* set status to sleeping to suspend it */
thread_t* thread = (thread_t*)sched_threads[pid];
sched_set_status(thread, STATUS_SLEEPING);
/* trigger rescheduling */
sched_active_thread = NULL;
/* determine the new running task */
sched_run();
}
void vTaskResume(TaskHandle_t xTaskToResume)
{
extern volatile thread_t *sched_active_thread;
DEBUG("%s pid=%d task=%p\n", __func__, thread_getpid(), xTaskToResume);
uint32_t pid = (uint32_t)xTaskToResume;
assert(pid <= KERNEL_PID_LAST);
thread_wakeup (pid);
}
TaskHandle_t xTaskGetCurrentTaskHandle(void)
{
DEBUG("%s pid=%d\n", __func__, thread_getpid());
@ -136,9 +170,9 @@ TaskHandle_t xTaskGetCurrentTaskHandle(void)
void vTaskDelay( const TickType_t xTicksToDelay )
{
DEBUG("%s xTicksToDelay=%d\n", __func__, xTicksToDelay);
#if defined(MODULE_ESP_WIFI_ANY)
uint64_t ms = xTicksToDelay * MS_PER_SEC / xPortGetTickRateHz();
ztimer_sleep(ZTIMER_MSEC, ms);
#if defined(MODULE_ESP_WIFI_ANY) || defined(MODULE_ESP_ETH)
uint64_t ms = xTicksToDelay * MS_PER_SEC / xPortGetTickRateHz();
ztimer_sleep(ZTIMER_MSEC, ms);
#endif
}
@ -235,4 +269,88 @@ TickType_t prvGetExpectedIdleTime(void)
return 0;
}
BaseType_t xTaskNotifyGive(TaskHandle_t xTaskToNotify)
{
DEBUG("%s pid=%d task=%p\n", __func__, thread_getpid(), xTaskToNotify);
vTaskNotifyGiveFromISR(xTaskToNotify, NULL);
return pdPASS;
}
void vTaskNotifyGiveFromISR(TaskHandle_t xTaskToNotify,
BaseType_t *pxHigherPriorityTaskWoken)
{
DEBUG("%s pid=%d task=%p\n", __func__, thread_getpid(), xTaskToNotify);
uint32_t pid = (uint32_t)xTaskToNotify;
assert(pid <= KERNEL_PID_LAST);
vTaskEnterCritical(0);
threads_arch_exts[pid].notification_value++;
if (threads_arch_exts[pid].notification_wait_for) {
/* if the task is waiting for notification, set its status to pending */
thread_t* thread = (thread_t*)sched_threads[pid];
sched_set_status(thread, STATUS_PENDING);
if (thread->priority < sched_threads[thread_getpid()]->priority) {
/* a context switch is needed */
if (pxHigherPriorityTaskWoken) {
*pxHigherPriorityTaskWoken = pdTRUE;
}
vTaskExitCritical(0);
/* sets only the sched_context_switch_request in ISRs */
thread_yield_higher();
return;
}
}
vTaskExitCritical(0);
}
uint32_t ulTaskNotifyTake(BaseType_t xClearCountOnExit,
TickType_t xTicksToWait)
{
DEBUG("%s pid=%d\n", __func__, thread_getpid());
kernel_pid_t pid = thread_getpid();
assert((pid >= 0) && (pid <= KERNEL_PID_LAST));
vTaskEnterCritical(0);
uint32_t prev_value = threads_arch_exts[pid].notification_value;
if (prev_value) {
/* notification was pending */
threads_arch_exts[pid].notification_value--;
vTaskExitCritical(0);
}
else if (xTicksToWait == 0 || irq_is_in()) {
/* if delaying is not allowed */
DEBUG("%s pid=%d delaying not allowed\n", __func__, thread_getpid());
assert(0);
}
else {
/* suspend the calling thread to wait for notification */
threads_arch_exts[pid].notification_wait_for = true;
thread_t *me = thread_get_active();
sched_set_status(me, STATUS_SLEEPING);
DEBUG("%s pid=%d suspend calling thread\n", __func__, thread_getpid());
vTaskExitCritical(0);
thread_yield_higher();
/* TODO timeout handling with xTicksToWait */
DEBUG("%s pid=%d continue calling thread\n", __func__, thread_getpid());
}
threads_arch_exts[pid].notification_wait_for = false;
if (xClearCountOnExit) {
threads_arch_exts[pid].notification_value = 0;
}
return prev_value;
}
#endif /* DOXYGEN */

View File

@ -19,6 +19,7 @@
extern "C" {
#endif
#define configTASK_NOTIFICATION_ARRAY_ENTRIES 1
#define configMAX_PRIORITIES SCHED_PRIO_LEVELS
#ifndef configASSERT
@ -33,11 +34,16 @@ extern "C" {
#define BaseType_t portBASE_TYPE
#define UBaseType_t unsigned portBASE_TYPE
#define pdMS_TO_TICKS(ms) ((TickType_t)(ms / portTICK_PERIOD_MS))
typedef uint32_t TickType_t;
uint32_t xPortGetTickRateHz(void);
BaseType_t xPortInIsrContext(void);
UBaseType_t xPortSetInterruptMaskFromISR(void);
void vPortClearInterruptMaskFromISR(UBaseType_t state);
/*
* PLEASE NOTE: Following definitions were copied directly from the FreeRTOS
* distribution and are under the following copyright:

View File

@ -13,8 +13,13 @@
#ifndef DOXYGEN
#include "stdbool.h"
#include "stdint.h"
#ifndef MCU_ESP8266
#include "esp_timer.h"
#endif
#include "mutex.h"
#include "irq.h"
@ -28,17 +33,23 @@ extern "C" {
#define portMAX_DELAY 0xFFFFFFFF
#define portMUX_TYPE mutex_t
#define portMUX_INITIALIZE mutex_init
#define portMUX_INITIALIZER_UNLOCKED MUTEX_INIT
#define portYIELD_FROM_ISR thread_yield_higher
#define portENTER_CRITICAL vTaskEnterCritical
#define portEXIT_CRITICAL vTaskExitCritical
#define portENTER_CRITICAL_SAFE vTaskEnterCritical
#define portEXIT_CRITICAL_SAFE vTaskExitCritical
#define portENTER_CRITICAL_ISR vTaskEnterCritical
#define portEXIT_CRITICAL_ISR vTaskExitCritical
#define portENTER_CRITICAL_NESTED irq_disable
#define portEXIT_CRITICAL_NESTED irq_restore
#define portSET_INTERRUPT_MASK_FROM_ISR xPortSetInterruptMaskFromISR
#define portCLEAR_INTERRUPT_MASK_FROM_ISR vPortClearInterruptMaskFromISR
#ifdef MCU_ESP32
#define portNUM_PROCESSORS 2
@ -54,6 +65,8 @@ extern "C" {
extern void vTaskEnterCritical(portMUX_TYPE *mux);
extern void vTaskExitCritical(portMUX_TYPE *mux);
bool xPortCanYield(void);
#ifdef __cplusplus
}
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2019 Gunar Schorcht
* Copyright (C) 2022 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

View File

@ -0,0 +1,29 @@
/*
* Copyright (C) 2022 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
*
* At the moment this header file is empty and exists only to avoid
* compilation errors for files of the ESP-IDF that include `ringbuf.h`,
* such as `uart.h` even if they do not need definitions from `ringbuf.h`.
*/
#ifndef FREERTOS_RINGBUF_H
#define FREERTOS_RINGBUF_H
#ifndef DOXYGEN
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif /* DOXYGEN */
#endif /* FREERTOS_RINGBUF_H */

View File

@ -51,7 +51,10 @@ BaseType_t xTaskCreatePinnedToCore(TaskFunction_t pvTaskCode,
const BaseType_t xCoreID);
void vTaskDelete(TaskHandle_t xTaskToDelete);
void vTaskSuspend(TaskHandle_t xTaskToSuspend);
void vTaskResume(TaskHandle_t xTaskToResume);
void vTaskDelay(const TickType_t xTicksToDelay);
void vTaskSuspendAll(void);
TaskHandle_t xTaskGetCurrentTaskHandle(void);
@ -60,6 +63,12 @@ void vTaskExitCritical(portMUX_TYPE *mux);
TickType_t xTaskGetTickCount(void);
BaseType_t xTaskNotifyGive(TaskHandle_t xTaskToNotify);
void vTaskNotifyGiveFromISR(TaskHandle_t xTaskToNotify,
BaseType_t *pxHigherPriorityTaskWoken);
uint32_t ulTaskNotifyTake(BaseType_t xClearCountOnExit,
TickType_t xTicksToWait);
#ifdef __cplusplus
}
#endif