blob: 9b8f072e1baf155d8f4fa7c49c34c0a246c3e68d [file] [log] [blame]
#pragma once
#include "FreeRTOS.h"
#include <queue.h>
#define errQUEUE_EMPTY pdFALSE
#define errQUEUE_FULL pdFALSE
/**
* Queue handle. This is used to reference queues in the API functions.
*/
typedef struct MessageQueue *QueueHandle_t;
/**
* Receive a message on a queue. The message is received into `buffer`, which
* must be large enough to accommodate a message of the size passed to
* `xQueueCreate`. This blocks for up to `waitTicks` ticks if the queue is
* empty.
*
* Returns `pdPASS` if a message was received, or `errQUEUE_EMPTY` if the queue
* is empty and no message arrived (or was not collected by another
* higher-priority thread) for the duration of the call.
*/
static inline BaseType_t
xQueueReceive(QueueHandle_t queueHandle, void *buffer, TickType_t waitTicks)
{
struct Timeout timeout = {0, waitTicks};
int rv = queue_receive(&timeout, queueHandle, buffer);
if (rv == 0)
return pdPASS;
return errQUEUE_EMPTY;
}
/**
* Send a message to the queue. Blocks for up to `waitTicks` ticks if the
* queue is full. The message is copied from `buffer` which must be large
* enough to accommodate a message of the size passed to `xQueueCreate`.
*
* returns `pdPASS` if the message was sent, or `errQUEUE_FULL` if the queue
* remained full for the duration of the call.
*/
static inline BaseType_t xQueueSendToBack(QueueHandle_t queueHandle,
const void *buffer,
TickType_t waitTicks)
{
struct Timeout timeout = {0, waitTicks};
int rv = queue_send(&timeout, queueHandle, buffer);
if (rv == 0)
return pdPASS;
return errQUEUE_FULL;
}
/**
* Send a message to the queue from an ISR. We do not allow running code from
* ISRs and so this behaves like a non-blocking `xQueueSendToBack`.
*
* The `pxHigherPriorityTaskWoken` parameter is used to return whether a yield
* is necessary. A yield is never necessary in this implementation and so this
* is unconditionally given a value of `pdFALSE`.
*/
static inline BaseType_t
xQueueSendToBackFromISR(QueueHandle_t queueHandle,
const void *buffer,
BaseType_t *pxHigherPriorityTaskWoken)
{
*pxHigherPriorityTaskWoken = pdFALSE;
return xQueueSendToBack(queueHandle, buffer, 0);
}
#ifndef CHERIOT_NO_AMBIENT_MALLOC
/**
* Create a queue that can store `uxQueueLength` messages of size `uxItemSize`.
* Returns NULL if queue creation failed, false otherwise.
*/
static inline QueueHandle_t xQueueCreate(UBaseType_t uxQueueLength,
UBaseType_t uxItemSize)
{
QueueHandle_t ret = NULL;
struct Timeout timeout = {0, UnlimitedTimeout};
int rc = queue_create(&timeout,
MALLOC_CAPABILITY,
&ret,
uxItemSize,
uxQueueLength);
return ret;
}
#endif
/**
* Delete a queue. This frees the memory associated with the queue.
*/
static inline void vQueueDelete(QueueHandle_t xQueue)
{
queue_destroy(MALLOC_CAPABILITY, xQueue);
}
/**
* Return the number of messages waiting in a queue.
*
* Note: This is inherently racy and should not be used for anything other than
* debugging.
*/
static inline UBaseType_t uxQueueMessagesWaiting(const QueueHandle_t xQueue)
{
size_t ret;
int rv = queue_items_remaining(xQueue, &ret);
assert(rv == 0);
return ret;
}