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

cpu/esp*: move common freertos code to cpu/esp_common

This commit is contained in:
Gunar Schorcht 2019-12-13 08:45:40 +01:00
parent 922429bc3b
commit 61339001e7
10 changed files with 4 additions and 736 deletions

View File

@ -1,59 +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.
*
* 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)
{
ets_printf("%s\n", __func__);
return NULL;
}
void vEventGroupDelete (EventGroupHandle_t xEventGroup)
{
ets_printf("%s\n", __func__);
return NULL;
}
EventBits_t xEventGroupSetBits (EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet)
{
ets_printf("%s\n", __func__);
return NULL;
}
EventBits_t xEventGroupClearBits (EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToClear )
{
ets_printf("%s\n", __func__);
return NULL;
}
EventBits_t xEventGroupWaitBits (const EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToWaitFor,
const BaseType_t xClearOnExit,
const BaseType_t xWaitForAllBits,
TickType_t xTicksToWait)
{
ets_printf("%s\n", __func__);
return NULL;
}
#endif /* DOXYGEN */

View File

@ -1,364 +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.
*
* 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 "mutex.h"
#include "rmutex.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"
#undef portENTER_CRITICAL
#undef portEXIT_CRITICAL
#define portENTER_CRITICAL(mux) vTaskEnterCritical(mux)
#define portEXIT_CRITICAL(mux) vTaskExitCritical(mux)
/*
* 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 */
mutex_t mutex; /* mutex to secure operations on the queue */
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);
mutex_init(&queue->mutex);
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;
CHECK_PARAM_RET(uxMaxCount != 0, NULL);
CHECK_PARAM_RET(uxInitialCount <= uxMaxCount, NULL);
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);
CHECK_PARAM(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\n", __func__,
thread_getpid(), sched_threads[thread_getpid()]->priority,
xQueue, xCopyPosition, xTicksToWait, pxHigherPriorityTaskWoken);
_queue_t* queue = (_queue_t*)xQueue;
CHECK_PARAM_RET(queue != NULL, pdFAIL);
while (1) {
taskENTER_CRITICAL(&queue->mutex);
/* 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);
}
/* unlock waiting receiving thread */
if (queue->receiving.next != NULL) {
list_node_t *next = list_remove_head(&queue->receiving);
thread_t *process = container_of((clist_node_t*)next, thread_t, rq_entry);
uint8_t process_priority = process->priority;
uint8_t my_priority = sched_threads[thread_getpid()]->priority;
if (pxHigherPriorityTaskWoken) {
*pxHigherPriorityTaskWoken = process_priority < my_priority;
}
DEBUG("%s pid=%d queue=%p unlock waiting\n", __func__,
thread_getpid(), xQueue);
sched_set_status(process, STATUS_PENDING);
sched_switch(process_priority);
}
DEBUG("%s pid=%d queue=%p return pdPASS\n", __func__,
thread_getpid(), xQueue);
taskEXIT_CRITICAL(&queue->mutex);
return pdPASS;
}
else if (xTicksToWait == 0) {
/* 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);
taskEXIT_CRITICAL(&queue->mutex);
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);
taskEXIT_CRITICAL(&queue->mutex);
thread_yield_higher();
/* TODO timeout handling with xTicksToWait */
DEBUG("%s pid=%d queue=%p continue calling thread\n", __func__,
thread_getpid(), xQueue);
}
}
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\n", __func__,
thread_getpid(), sched_threads[thread_getpid()]->priority,
xQueue, xTicksToWait, xJustPeeking, pxHigherPriorityTaskWoken);
_queue_t* queue = (_queue_t*)xQueue;
CHECK_PARAM_RET(queue != NULL, pdFAIL);
while (1) {
taskENTER_CRITICAL(&queue->mutex);
if (queue->item_level == 0 && xTicksToWait == 0) {
/* if there was no element in queue and timeout = 0, return with error */
DEBUG("%s pid=%d queue=%p return errQUEUE_EMPTY\n", __func__,
thread_getpid(), xQueue);
taskEXIT_CRITICAL(&queue->mutex);
return errQUEUE_EMPTY;
}
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 == pdFALSE) {
queue->item_front = (queue->item_front + 1) % queue->item_num;
queue->item_level--;
/* unlock waiting sending thread */
if (queue->sending.next != NULL) {
list_node_t *next = list_remove_head(&queue->sending);
thread_t *process = container_of((clist_node_t*)next,
thread_t, rq_entry);
uint16_t process_priority = process->priority;
uint8_t my_priority = sched_threads[thread_getpid()]->priority;
if (pxHigherPriorityTaskWoken) {
*pxHigherPriorityTaskWoken = process_priority < my_priority;
}
DEBUG("%s pid=%d queue=%p unlock waiting\n", __func__,
thread_getpid(), xQueue);
sched_set_status(process, STATUS_PENDING);
sched_switch(process_priority);
}
}
DEBUG("%s pid=%d queue=%p return pdPASS\n", __func__,
thread_getpid(), xQueue);
taskEXIT_CRITICAL(&queue->mutex);
return pdPASS;
}
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);
taskEXIT_CRITICAL(&queue->mutex);
thread_yield_higher();
/* TODO timeout handling with xTicksToWait */
DEBUG("%s pid=%d queue=%p continue calling thread\n", __func__,
thread_getpid(), xQueue);
}
}
}
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 )
{
_queue_t* queue = (_queue_t*)xQueue;
CHECK_PARAM_RET(queue != NULL, 0);
return queue->item_level;
}
BaseType_t xQueueGiveFromISR (QueueHandle_t xQueue,
BaseType_t * const pxHigherPriorityTaskWoken)
{
ets_printf("%s\n", __func__);
return pdFALSE;
}
#endif /* DOXYGEN */

View File

@ -1,178 +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.
*
* 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);
CHECK_PARAM(xSemaphore != NULL);
free(xSemaphore);
}
BaseType_t xSemaphoreGive (SemaphoreHandle_t xSemaphore)
{
DEBUG("%s mutex=%p\n", __func__, xSemaphore);
CHECK_PARAM_RET(xSemaphore != NULL, pdFALSE);
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);
CHECK_PARAM_RET(xSemaphore != NULL, pdFALSE);
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);
CHECK_PARAM_RET(xSemaphore != NULL, pdFALSE);
CHECK_PARAM_RET(((_rmutex_t*)xSemaphore)->type ==
queueQUEUE_TYPE_RECURSIVE_MUTEX, pdFALSE);
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);
CHECK_PARAM_RET(xSemaphore != NULL, pdFALSE);
CHECK_PARAM_RET(((_rmutex_t*)xSemaphore)->type ==
queueQUEUE_TYPE_RECURSIVE_MUTEX, pdFALSE);
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 */

View File

@ -1,110 +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.
*
* FreeRTOS to RIOT-OS adaption module for source code compatibility
*/
#ifndef DOXYGEN
#ifdef MODULE_XTIMER
#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)
{
CHECK_PARAM(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;
return timer;
}
BaseType_t xTimerDelete(TimerHandle_t xTimer, TickType_t xBlockTime)
{
CHECK_PARAM_RET(xTimer != NULL, pdFALSE);
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)
{
CHECK_PARAM_RET(xTimer != NULL, pdFALSE);
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)
{
CHECK_PARAM_RET(xTimer != NULL, pdFALSE);
freertos_xtimer_t* timer = (freertos_xtimer_t*)xTimer;
xtimer_remove(&timer->xtimer);
return pdTRUE;
}
#endif /* MODULE_XTIMER */
#endif /* DOXYGEN */

View File

@ -13,30 +13,12 @@
#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 );
@ -67,9 +49,7 @@ void IRAM_ATTR vPortETSIntrUnlock(void)
/* source: /path/to/esp8266-rtos-sdk/components/freertos/port/esp8266/port.c */
void ResetCcountVal(unsigned int cnt_val)
{
asm volatile("wsr a2, ccount");
__asm__ volatile("wsr a2, ccount");
}
#endif /* MCU_ESP8266 */
#endif /* DOXYGEN */

View File

@ -10,7 +10,7 @@
#ifndef DOXYGEN
#define ENABLE_DEBUG 0
#define ENABLE_DEBUG (0)
#include "debug.h"
#include <string.h>

View File

@ -60,10 +60,9 @@ QueueHandle_t xQueueGenericCreate( const UBaseType_t uxQueueLength,
uint32_t queue_size = uxQueueLength * uxItemSize;
_queue_t* queue = malloc(sizeof(_queue_t) + queue_size);
if (!queue) {
return NULL;
}
assert(queue != NULL);
memset(queue, 0, sizeof(_queue_t) + queue_size);
queue->type = ucQueueType;
queue->receiving.next = NULL;
queue->sending.next = NULL;