use crate::config::*;
use crate::kernel::list::*;
use crate::kernel::tasks::*;
use crate::memory::*;
use crate::port::*;
use crate::trace::*;
use crate::types::*;
use core::ffi::c_void;
use core::ptr;
const queueUNLOCKED: i8 = -1;
const queueLOCKED_UNMODIFIED: i8 = 0;
const queueINT8_MAX: i8 = 127;
pub const queueSEND_TO_BACK: BaseType_t = 0;
pub const queueSEND_TO_FRONT: BaseType_t = 1;
pub const queueOVERWRITE: BaseType_t = 2;
pub const queueQUEUE_TYPE_BASE: u8 = 0;
pub const queueQUEUE_TYPE_MUTEX: u8 = 1;
pub const queueQUEUE_TYPE_COUNTING_SEMAPHORE: u8 = 2;
pub const queueQUEUE_TYPE_BINARY_SEMAPHORE: u8 = 3;
pub const queueQUEUE_TYPE_RECURSIVE_MUTEX: u8 = 4;
pub const queueQUEUE_TYPE_SET: u8 = 5;
const queueSEMAPHORE_QUEUE_ITEM_LENGTH: UBaseType_t = 0;
const queueMUTEX_GIVE_BLOCK_TIME: TickType_t = 0;
#[repr(C)]
#[derive(Clone, Copy)]
pub struct QueuePointers_t {
pub pcTail: *mut i8,
pub pcReadFrom: *mut i8,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct SemaphoreData_t {
pub xMutexHolder: TaskHandle_t,
pub uxRecursiveCallCount: UBaseType_t,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub union QueueUnion_t {
pub xQueue: QueuePointers_t,
pub xSemaphore: SemaphoreData_t,
}
#[repr(C)]
pub struct xQUEUE {
pub pcHead: *mut i8,
pub pcWriteTo: *mut i8,
pub u: QueueUnion_t,
pub xTasksWaitingToSend: List_t,
pub xTasksWaitingToReceive: List_t,
pub uxMessagesWaiting: UBaseType_t,
pub uxLength: UBaseType_t,
pub uxItemSize: UBaseType_t,
pub cRxLock: i8,
pub cTxLock: i8,
#[cfg(any(feature = "alloc", feature = "heap-4", feature = "heap-5"))]
pub ucStaticallyAllocated: u8,
#[cfg(feature = "queue-sets")]
pub pxQueueSetContainer: *mut xQUEUE,
#[cfg(feature = "trace-facility")]
pub uxQueueNumber: UBaseType_t,
#[cfg(feature = "trace-facility")]
pub ucQueueType: u8,
}
pub type Queue_t = xQUEUE;
pub type QueueHandle_t = *mut Queue_t;
#[cfg(feature = "queue-sets")]
pub type QueueSetHandle_t = *mut Queue_t;
#[cfg(feature = "queue-sets")]
pub type QueueSetMemberHandle_t = *mut Queue_t;
#[repr(C)]
pub struct StaticQueue_t {
_data: xQUEUE,
}
#[inline(always)]
fn mtCOVERAGE_TEST_DELAY() {}
#[inline(always)]
fn mtCOVERAGE_TEST_MARKER() {}
#[inline(always)]
fn queueYIELD_IF_USING_PREEMPTION() {
if configUSE_PREEMPTION != 0 {
portYIELD_WITHIN_API();
}
}
#[inline(always)]
unsafe fn prvLockQueue(pxQueue: *mut Queue_t) {
taskENTER_CRITICAL();
{
if (*pxQueue).cRxLock == queueUNLOCKED {
(*pxQueue).cRxLock = queueLOCKED_UNMODIFIED;
}
if (*pxQueue).cTxLock == queueUNLOCKED {
(*pxQueue).cTxLock = queueLOCKED_UNMODIFIED;
}
}
taskEXIT_CRITICAL();
}
pub unsafe fn xQueueGenericReset(xQueue: QueueHandle_t, xNewQueue: BaseType_t) -> BaseType_t {
let mut xReturn: BaseType_t = pdPASS;
let pxQueue: *mut Queue_t = xQueue;
traceENTER_xQueueGenericReset(pxQueue as *mut c_void, xNewQueue);
configASSERT(!pxQueue.is_null());
if !pxQueue.is_null()
&& (*pxQueue).uxLength >= 1
&& (usize::MAX / (*pxQueue).uxLength as usize) >= (*pxQueue).uxItemSize as usize
{
taskENTER_CRITICAL();
{
(*pxQueue).u.xQueue.pcTail = (*pxQueue)
.pcHead
.add(((*pxQueue).uxLength * (*pxQueue).uxItemSize) as usize);
(*pxQueue).uxMessagesWaiting = 0;
(*pxQueue).pcWriteTo = (*pxQueue).pcHead;
(*pxQueue).u.xQueue.pcReadFrom = (*pxQueue)
.pcHead
.add((((*pxQueue).uxLength - 1) * (*pxQueue).uxItemSize) as usize);
(*pxQueue).cRxLock = queueUNLOCKED;
(*pxQueue).cTxLock = queueUNLOCKED;
if xNewQueue == pdFALSE {
if listLIST_IS_EMPTY(&(*pxQueue).xTasksWaitingToSend) == pdFALSE {
if xTaskRemoveFromEventList(&(*pxQueue).xTasksWaitingToSend) != pdFALSE {
queueYIELD_IF_USING_PREEMPTION();
} else {
mtCOVERAGE_TEST_MARKER();
}
} else {
mtCOVERAGE_TEST_MARKER();
}
} else {
vListInitialise(&mut (*pxQueue).xTasksWaitingToSend);
vListInitialise(&mut (*pxQueue).xTasksWaitingToReceive);
}
}
taskEXIT_CRITICAL();
} else {
xReturn = pdFAIL;
}
configASSERT(xReturn != pdFAIL);
traceRETURN_xQueueGenericReset(xReturn);
xReturn
}
unsafe fn prvInitialiseNewQueue(
uxQueueLength: UBaseType_t,
uxItemSize: UBaseType_t,
pucQueueStorage: *mut u8,
#[allow(unused_variables)] ucQueueType: u8,
pxNewQueue: *mut Queue_t,
) {
if uxItemSize == 0 {
(*pxNewQueue).pcHead = pxNewQueue as *mut i8;
} else {
(*pxNewQueue).pcHead = pucQueueStorage as *mut i8;
}
(*pxNewQueue).uxLength = uxQueueLength;
(*pxNewQueue).uxItemSize = uxItemSize;
xQueueGenericReset(pxNewQueue, pdTRUE);
#[cfg(feature = "trace-facility")]
{
(*pxNewQueue).ucQueueType = ucQueueType;
}
#[cfg(feature = "queue-sets")]
{
(*pxNewQueue).pxQueueSetContainer = ptr::null_mut();
}
traceQUEUE_CREATE(pxNewQueue as *mut c_void);
}
pub unsafe fn xQueueGenericCreateStatic(
uxQueueLength: UBaseType_t,
uxItemSize: UBaseType_t,
pucQueueStorage: *mut u8,
pxStaticQueue: *mut StaticQueue_t,
ucQueueType: u8,
) -> QueueHandle_t {
let mut pxNewQueue: *mut Queue_t = ptr::null_mut();
traceENTER_xQueueGenericCreateStatic(
uxQueueLength,
uxItemSize,
pucQueueStorage as *mut c_void,
pxStaticQueue as *mut c_void,
ucQueueType,
);
configASSERT(!pxStaticQueue.is_null());
if uxQueueLength > 0
&& !pxStaticQueue.is_null()
&& !((!pucQueueStorage.is_null()) && (uxItemSize == 0))
&& !((pucQueueStorage.is_null()) && (uxItemSize != 0))
{
pxNewQueue = pxStaticQueue as *mut Queue_t;
#[cfg(any(feature = "alloc", feature = "heap-4", feature = "heap-5"))]
{
(*pxNewQueue).ucStaticallyAllocated = pdTRUE as u8;
}
prvInitialiseNewQueue(
uxQueueLength,
uxItemSize,
pucQueueStorage,
ucQueueType,
pxNewQueue,
);
} else {
configASSERT(!pxNewQueue.is_null());
mtCOVERAGE_TEST_MARKER();
}
traceRETURN_xQueueGenericCreateStatic(pxNewQueue as *mut c_void);
pxNewQueue
}
pub unsafe fn xQueueGenericGetStaticBuffers(
xQueue: QueueHandle_t,
ppucQueueStorage: *mut *mut u8,
ppxStaticQueue: *mut *mut StaticQueue_t,
) -> BaseType_t {
let xReturn: BaseType_t;
let pxQueue = xQueue as *const Queue_t;
traceENTER_xQueueGenericGetStaticBuffers(
xQueue,
ppucQueueStorage as *mut c_void,
ppxStaticQueue as *mut c_void,
);
configASSERT(!pxQueue.is_null());
configASSERT(!ppxStaticQueue.is_null());
#[cfg(any(feature = "alloc", feature = "heap-4", feature = "heap-5"))]
{
if (*pxQueue).ucStaticallyAllocated == pdTRUE as u8 {
if !ppucQueueStorage.is_null() {
*ppucQueueStorage = (*pxQueue).pcHead as *mut u8;
}
*ppxStaticQueue = pxQueue as *mut StaticQueue_t;
xReturn = pdTRUE;
} else {
xReturn = pdFALSE;
}
}
#[cfg(not(any(feature = "alloc", feature = "heap-4", feature = "heap-5")))]
{
if !ppucQueueStorage.is_null() {
*ppucQueueStorage = (*pxQueue).pcHead as *mut u8;
}
*ppxStaticQueue = pxQueue as *mut StaticQueue_t;
xReturn = pdTRUE;
}
traceRETURN_xQueueGenericGetStaticBuffers(xReturn);
xReturn
}
#[cfg(any(feature = "alloc", feature = "heap-4", feature = "heap-5"))]
pub unsafe fn xQueueGenericCreate(
uxQueueLength: UBaseType_t,
uxItemSize: UBaseType_t,
ucQueueType: u8,
) -> QueueHandle_t {
let mut pxNewQueue: *mut Queue_t = ptr::null_mut();
traceENTER_xQueueGenericCreate(uxQueueLength, uxItemSize, ucQueueType);
if uxQueueLength > 0
&& (usize::MAX / uxQueueLength as usize) >= uxItemSize as usize
&& (usize::MAX - core::mem::size_of::<Queue_t>())
>= (uxQueueLength as usize * uxItemSize as usize)
{
let xQueueSizeInBytes: usize = uxQueueLength as usize * uxItemSize as usize;
pxNewQueue =
pvPortMalloc(core::mem::size_of::<Queue_t>() + xQueueSizeInBytes) as *mut Queue_t;
if !pxNewQueue.is_null() {
let pucQueueStorage: *mut u8 =
(pxNewQueue as *mut u8).add(core::mem::size_of::<Queue_t>());
(*pxNewQueue).ucStaticallyAllocated = pdFALSE as u8;
prvInitialiseNewQueue(
uxQueueLength,
uxItemSize,
pucQueueStorage,
ucQueueType,
pxNewQueue,
);
} else {
traceQUEUE_CREATE_FAILED(ucQueueType);
mtCOVERAGE_TEST_MARKER();
}
} else {
configASSERT(!pxNewQueue.is_null());
mtCOVERAGE_TEST_MARKER();
}
traceRETURN_xQueueGenericCreate(pxNewQueue as *mut c_void);
pxNewQueue
}
#[cfg(any(feature = "alloc", feature = "heap-4", feature = "heap-5"))]
#[inline(always)]
pub unsafe fn xQueueCreate(uxQueueLength: UBaseType_t, uxItemSize: UBaseType_t) -> QueueHandle_t {
xQueueGenericCreate(uxQueueLength, uxItemSize, queueQUEUE_TYPE_BASE)
}
#[inline(always)]
pub unsafe fn xQueueCreateStatic(
uxQueueLength: UBaseType_t,
uxItemSize: UBaseType_t,
pucQueueStorage: *mut u8,
pxQueueBuffer: *mut StaticQueue_t,
) -> QueueHandle_t {
xQueueGenericCreateStatic(
uxQueueLength,
uxItemSize,
pucQueueStorage,
pxQueueBuffer,
queueQUEUE_TYPE_BASE,
)
}
unsafe fn prvCopyDataToQueue(
pxQueue: *mut Queue_t,
pvItemToQueue: *const c_void,
xPosition: BaseType_t,
) -> BaseType_t {
let mut xReturn: BaseType_t = pdFALSE;
let uxMessagesWaiting: UBaseType_t = (*pxQueue).uxMessagesWaiting;
if (*pxQueue).uxItemSize == 0 {
#[cfg(any(feature = "alloc", feature = "heap-4", feature = "heap-5"))] {
if (*pxQueue).pcHead.is_null() {
xReturn = xTaskPriorityDisinherit((*pxQueue).u.xSemaphore.xMutexHolder);
(*pxQueue).u.xSemaphore.xMutexHolder = ptr::null_mut();
} else {
mtCOVERAGE_TEST_MARKER();
}
}
} else if xPosition == queueSEND_TO_BACK {
ptr::copy_nonoverlapping(
pvItemToQueue as *const u8,
(*pxQueue).pcWriteTo as *mut u8,
(*pxQueue).uxItemSize as usize,
);
(*pxQueue).pcWriteTo = (*pxQueue).pcWriteTo.add((*pxQueue).uxItemSize as usize);
if (*pxQueue).pcWriteTo >= (*pxQueue).u.xQueue.pcTail {
(*pxQueue).pcWriteTo = (*pxQueue).pcHead;
} else {
mtCOVERAGE_TEST_MARKER();
}
} else {
ptr::copy_nonoverlapping(
pvItemToQueue as *const u8,
(*pxQueue).u.xQueue.pcReadFrom as *mut u8,
(*pxQueue).uxItemSize as usize,
);
(*pxQueue).u.xQueue.pcReadFrom = (*pxQueue)
.u
.xQueue
.pcReadFrom
.sub((*pxQueue).uxItemSize as usize);
if (*pxQueue).u.xQueue.pcReadFrom < (*pxQueue).pcHead {
(*pxQueue).u.xQueue.pcReadFrom = (*pxQueue)
.u
.xQueue
.pcTail
.sub((*pxQueue).uxItemSize as usize);
} else {
mtCOVERAGE_TEST_MARKER();
}
if xPosition == queueOVERWRITE {
if uxMessagesWaiting > 0 {
(*pxQueue).uxMessagesWaiting = uxMessagesWaiting - 1;
} else {
mtCOVERAGE_TEST_MARKER();
}
} else {
mtCOVERAGE_TEST_MARKER();
}
}
(*pxQueue).uxMessagesWaiting = (*pxQueue).uxMessagesWaiting + 1;
xReturn
}
unsafe fn prvCopyDataFromQueue(pxQueue: *mut Queue_t, pvBuffer: *mut c_void) {
if (*pxQueue).uxItemSize != 0 {
(*pxQueue).u.xQueue.pcReadFrom = (*pxQueue)
.u
.xQueue
.pcReadFrom
.add((*pxQueue).uxItemSize as usize);
if (*pxQueue).u.xQueue.pcReadFrom >= (*pxQueue).u.xQueue.pcTail {
(*pxQueue).u.xQueue.pcReadFrom = (*pxQueue).pcHead;
} else {
mtCOVERAGE_TEST_MARKER();
}
ptr::copy_nonoverlapping(
(*pxQueue).u.xQueue.pcReadFrom as *const u8,
pvBuffer as *mut u8,
(*pxQueue).uxItemSize as usize,
);
}
}
unsafe fn prvIsQueueEmpty(pxQueue: *const Queue_t) -> BaseType_t {
let xReturn: BaseType_t;
taskENTER_CRITICAL();
{
if (*pxQueue).uxMessagesWaiting == 0 {
xReturn = pdTRUE;
} else {
xReturn = pdFALSE;
}
}
taskEXIT_CRITICAL();
xReturn
}
unsafe fn prvIsQueueFull(pxQueue: *const Queue_t) -> BaseType_t {
let xReturn: BaseType_t;
taskENTER_CRITICAL();
{
if (*pxQueue).uxMessagesWaiting == (*pxQueue).uxLength {
xReturn = pdTRUE;
} else {
xReturn = pdFALSE;
}
}
taskEXIT_CRITICAL();
xReturn
}
pub unsafe fn xQueueGenericSend(
xQueue: QueueHandle_t,
pvItemToQueue: *const c_void,
xTicksToWait: TickType_t,
xCopyPosition: BaseType_t,
) -> BaseType_t {
let mut xEntryTimeSet: BaseType_t = pdFALSE;
let xYieldRequired: BaseType_t;
let mut xTimeOut = TimeOut_t::new();
let pxQueue: *mut Queue_t = xQueue;
traceENTER_xQueueGenericSend(
pxQueue as *mut c_void,
pvItemToQueue,
xTicksToWait,
xCopyPosition,
);
configASSERT(!pxQueue.is_null());
configASSERT(!(pvItemToQueue.is_null() && (*pxQueue).uxItemSize != 0));
configASSERT(!(xCopyPosition == queueOVERWRITE && (*pxQueue).uxLength != 1));
loop {
taskENTER_CRITICAL();
{
if (*pxQueue).uxMessagesWaiting < (*pxQueue).uxLength || xCopyPosition == queueOVERWRITE
{
traceQUEUE_SEND(pxQueue as *mut c_void);
#[cfg(feature = "queue-sets")]
let uxPreviousMessagesWaiting = (*pxQueue).uxMessagesWaiting;
xYieldRequired = prvCopyDataToQueue(pxQueue, pvItemToQueue, xCopyPosition);
#[cfg(feature = "queue-sets")]
{
if !(*pxQueue).pxQueueSetContainer.is_null() {
if xCopyPosition == queueOVERWRITE && uxPreviousMessagesWaiting != 0 {
mtCOVERAGE_TEST_MARKER();
} else if prvNotifyQueueSetContainer(pxQueue) != pdFALSE {
queueYIELD_IF_USING_PREEMPTION();
}
} else {
if listLIST_IS_EMPTY(&(*pxQueue).xTasksWaitingToReceive) == pdFALSE {
if xTaskRemoveFromEventList(&(*pxQueue).xTasksWaitingToReceive)
!= pdFALSE
{
queueYIELD_IF_USING_PREEMPTION();
}
} else if xYieldRequired != pdFALSE {
queueYIELD_IF_USING_PREEMPTION();
}
}
}
#[cfg(not(feature = "queue-sets"))]
{
if listLIST_IS_EMPTY(&(*pxQueue).xTasksWaitingToReceive) == pdFALSE {
if xTaskRemoveFromEventList(&(*pxQueue).xTasksWaitingToReceive) != pdFALSE {
queueYIELD_IF_USING_PREEMPTION();
} else {
mtCOVERAGE_TEST_MARKER();
}
} else if xYieldRequired != pdFALSE {
queueYIELD_IF_USING_PREEMPTION();
} else {
mtCOVERAGE_TEST_MARKER();
}
}
taskEXIT_CRITICAL();
traceRETURN_xQueueGenericSend(pdPASS);
return pdPASS;
} else {
if xTicksToWait == 0 {
taskEXIT_CRITICAL();
traceQUEUE_SEND_FAILED(pxQueue as *mut c_void);
traceRETURN_xQueueGenericSend(errQUEUE_FULL);
return errQUEUE_FULL;
} else if xEntryTimeSet == pdFALSE {
vTaskSetTimeOutState(&mut xTimeOut);
xEntryTimeSet = pdTRUE;
} else {
mtCOVERAGE_TEST_MARKER();
}
}
}
taskEXIT_CRITICAL();
vTaskSuspendAll();
prvLockQueue(pxQueue);
if xTaskCheckForTimeOut(&mut xTimeOut, &mut (xTicksToWait as TickType_t)) == pdFALSE {
if prvIsQueueFull(pxQueue) != pdFALSE {
traceBLOCKING_ON_QUEUE_SEND(pxQueue as *mut c_void);
vTaskPlaceOnEventList(&mut (*pxQueue).xTasksWaitingToSend, xTicksToWait);
prvUnlockQueue(pxQueue);
if xTaskResumeAll() == pdFALSE {
portYIELD_WITHIN_API();
}
} else {
prvUnlockQueue(pxQueue);
xTaskResumeAll();
}
} else {
prvUnlockQueue(pxQueue);
xTaskResumeAll();
traceQUEUE_SEND_FAILED(pxQueue as *mut c_void);
traceRETURN_xQueueGenericSend(errQUEUE_FULL);
return errQUEUE_FULL;
}
}
}
pub unsafe fn xQueueReceive(
xQueue: QueueHandle_t,
pvBuffer: *mut c_void,
xTicksToWait: TickType_t,
) -> BaseType_t {
let mut xEntryTimeSet: BaseType_t = pdFALSE;
let mut xTimeOut = TimeOut_t::new();
let pxQueue: *mut Queue_t = xQueue;
traceENTER_xQueueReceive(pxQueue as *mut c_void, pvBuffer, xTicksToWait);
configASSERT(!pxQueue.is_null());
configASSERT(!(pvBuffer.is_null() && (*pxQueue).uxItemSize != 0));
loop {
taskENTER_CRITICAL();
{
let uxMessagesWaiting = (*pxQueue).uxMessagesWaiting;
if uxMessagesWaiting > 0 {
prvCopyDataFromQueue(pxQueue, pvBuffer);
traceQUEUE_RECEIVE(pxQueue as *mut c_void);
(*pxQueue).uxMessagesWaiting = uxMessagesWaiting - 1;
if listLIST_IS_EMPTY(&(*pxQueue).xTasksWaitingToSend) == pdFALSE {
if xTaskRemoveFromEventList(&(*pxQueue).xTasksWaitingToSend) != pdFALSE {
queueYIELD_IF_USING_PREEMPTION();
} else {
mtCOVERAGE_TEST_MARKER();
}
} else {
mtCOVERAGE_TEST_MARKER();
}
taskEXIT_CRITICAL();
traceRETURN_xQueueReceive(pdPASS);
return pdPASS;
} else {
if xTicksToWait == 0 {
taskEXIT_CRITICAL();
traceQUEUE_RECEIVE_FAILED(pxQueue as *mut c_void);
traceRETURN_xQueueReceive(errQUEUE_EMPTY);
return errQUEUE_EMPTY;
} else if xEntryTimeSet == pdFALSE {
vTaskSetTimeOutState(&mut xTimeOut);
xEntryTimeSet = pdTRUE;
} else {
mtCOVERAGE_TEST_MARKER();
}
}
}
taskEXIT_CRITICAL();
vTaskSuspendAll();
prvLockQueue(pxQueue);
if xTaskCheckForTimeOut(&mut xTimeOut, &mut (xTicksToWait as TickType_t)) == pdFALSE {
if prvIsQueueEmpty(pxQueue) != pdFALSE {
traceBLOCKING_ON_QUEUE_RECEIVE(pxQueue as *mut c_void);
vTaskPlaceOnEventList(&mut (*pxQueue).xTasksWaitingToReceive, xTicksToWait);
prvUnlockQueue(pxQueue);
if xTaskResumeAll() == pdFALSE {
portYIELD_WITHIN_API();
}
} else {
prvUnlockQueue(pxQueue);
xTaskResumeAll();
}
} else {
prvUnlockQueue(pxQueue);
xTaskResumeAll();
traceQUEUE_RECEIVE_FAILED(pxQueue as *mut c_void);
traceRETURN_xQueueReceive(errQUEUE_EMPTY);
return errQUEUE_EMPTY;
}
}
}
pub unsafe fn xQueuePeek(
xQueue: QueueHandle_t,
pvBuffer: *mut c_void,
xTicksToWait: TickType_t,
) -> BaseType_t {
let mut xEntryTimeSet: BaseType_t = pdFALSE;
let mut xTimeOut = TimeOut_t::new();
let pxQueue: *mut Queue_t = xQueue;
traceENTER_xQueuePeek(pxQueue as *mut c_void, pvBuffer, xTicksToWait);
configASSERT(!pxQueue.is_null());
configASSERT(!(pvBuffer.is_null() && (*pxQueue).uxItemSize != 0));
loop {
taskENTER_CRITICAL();
{
let uxMessagesWaiting = (*pxQueue).uxMessagesWaiting;
if uxMessagesWaiting > 0 {
let pcOriginalReadPosition = (*pxQueue).u.xQueue.pcReadFrom;
prvCopyDataFromQueue(pxQueue, pvBuffer);
(*pxQueue).u.xQueue.pcReadFrom = pcOriginalReadPosition;
traceQUEUE_PEEK(pxQueue as *mut c_void);
if listLIST_IS_EMPTY(&(*pxQueue).xTasksWaitingToReceive) == pdFALSE {
if xTaskRemoveFromEventList(&(*pxQueue).xTasksWaitingToReceive) != pdFALSE {
queueYIELD_IF_USING_PREEMPTION();
}
}
taskEXIT_CRITICAL();
traceRETURN_xQueuePeek(pdPASS);
return pdPASS;
} else {
if xTicksToWait == 0 {
taskEXIT_CRITICAL();
traceQUEUE_PEEK_FAILED(pxQueue as *mut c_void);
traceRETURN_xQueuePeek(errQUEUE_EMPTY);
return errQUEUE_EMPTY;
} else if xEntryTimeSet == pdFALSE {
vTaskSetTimeOutState(&mut xTimeOut);
xEntryTimeSet = pdTRUE;
}
}
}
taskEXIT_CRITICAL();
vTaskSuspendAll();
prvLockQueue(pxQueue);
if xTaskCheckForTimeOut(&mut xTimeOut, &mut (xTicksToWait as TickType_t)) == pdFALSE {
if prvIsQueueEmpty(pxQueue) != pdFALSE {
traceBLOCKING_ON_QUEUE_PEEK(pxQueue as *mut c_void);
vTaskPlaceOnEventList(&mut (*pxQueue).xTasksWaitingToReceive, xTicksToWait);
prvUnlockQueue(pxQueue);
if xTaskResumeAll() == pdFALSE {
portYIELD_WITHIN_API();
}
} else {
prvUnlockQueue(pxQueue);
xTaskResumeAll();
}
} else {
prvUnlockQueue(pxQueue);
xTaskResumeAll();
traceQUEUE_PEEK_FAILED(pxQueue as *mut c_void);
traceRETURN_xQueuePeek(errQUEUE_EMPTY);
return errQUEUE_EMPTY;
}
}
}
pub unsafe fn xQueueReceiveFromISR(
xQueue: QueueHandle_t,
pvBuffer: *mut c_void,
pxHigherPriorityTaskWoken: *mut BaseType_t,
) -> BaseType_t {
let xReturn: BaseType_t;
let pxQueue = xQueue as *mut Queue_t;
traceENTER_xQueueReceiveFromISR(xQueue, pvBuffer, pxHigherPriorityTaskWoken);
configASSERT(!pxQueue.is_null());
configASSERT(!(pvBuffer.is_null() && (*pxQueue).uxItemSize != 0));
let uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
{
let uxMessagesWaiting = (*pxQueue).uxMessagesWaiting;
if uxMessagesWaiting > 0 {
let cRxLock = (*pxQueue).cRxLock;
traceQUEUE_RECEIVE_FROM_ISR(pxQueue as *mut c_void);
prvCopyDataFromQueue(pxQueue, pvBuffer);
(*pxQueue).uxMessagesWaiting = uxMessagesWaiting - 1;
if cRxLock == queueUNLOCKED {
if listLIST_IS_EMPTY(&(*pxQueue).xTasksWaitingToSend) == pdFALSE {
if xTaskRemoveFromEventList(&(*pxQueue).xTasksWaitingToSend) != pdFALSE {
if !pxHigherPriorityTaskWoken.is_null() {
*pxHigherPriorityTaskWoken = pdTRUE;
}
}
}
} else {
configASSERT(cRxLock != queueINT8_MAX);
(*pxQueue).cRxLock = cRxLock + 1;
}
xReturn = pdPASS;
} else {
traceQUEUE_RECEIVE_FROM_ISR_FAILED(pxQueue as *mut c_void);
xReturn = pdFAIL;
}
}
portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus);
traceRETURN_xQueueReceiveFromISR(xReturn);
xReturn
}
pub unsafe fn xQueuePeekFromISR(xQueue: QueueHandle_t, pvBuffer: *mut c_void) -> BaseType_t {
let xReturn: BaseType_t;
let pxQueue = xQueue as *mut Queue_t;
traceENTER_xQueuePeekFromISR(xQueue, pvBuffer);
configASSERT(!pxQueue.is_null());
configASSERT(!pvBuffer.is_null());
configASSERT((*pxQueue).uxItemSize != 0);
let uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
{
if (*pxQueue).uxMessagesWaiting > 0 {
traceQUEUE_PEEK_FROM_ISR(pxQueue as *mut c_void);
let pcOriginalReadPosition = (*pxQueue).u.xQueue.pcReadFrom;
prvCopyDataFromQueue(pxQueue, pvBuffer);
(*pxQueue).u.xQueue.pcReadFrom = pcOriginalReadPosition;
xReturn = pdPASS;
} else {
traceQUEUE_PEEK_FROM_ISR_FAILED(pxQueue as *mut c_void);
xReturn = pdFAIL;
}
}
portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus);
traceRETURN_xQueuePeekFromISR(xReturn);
xReturn
}
unsafe fn prvUnlockQueue(pxQueue: *mut Queue_t) {
taskENTER_CRITICAL();
{
let mut cTxLock: i8 = (*pxQueue).cTxLock;
while cTxLock > queueLOCKED_UNMODIFIED {
cTxLock -= 1;
}
(*pxQueue).cTxLock = queueUNLOCKED;
}
taskEXIT_CRITICAL();
taskENTER_CRITICAL();
{
let mut cRxLock: i8 = (*pxQueue).cRxLock;
while cRxLock > queueLOCKED_UNMODIFIED {
cRxLock -= 1;
}
(*pxQueue).cRxLock = queueUNLOCKED;
}
taskEXIT_CRITICAL();
}
pub unsafe fn uxQueueMessagesWaiting(xQueue: QueueHandle_t) -> UBaseType_t {
let uxReturn: UBaseType_t;
configASSERT(!xQueue.is_null());
taskENTER_CRITICAL();
{
uxReturn = (*xQueue).uxMessagesWaiting;
}
taskEXIT_CRITICAL();
uxReturn
}
pub unsafe fn uxQueueSpacesAvailable(xQueue: QueueHandle_t) -> UBaseType_t {
let uxReturn: UBaseType_t;
configASSERT(!xQueue.is_null());
taskENTER_CRITICAL();
{
uxReturn = (*xQueue).uxLength - (*xQueue).uxMessagesWaiting;
}
taskEXIT_CRITICAL();
uxReturn
}
pub unsafe fn uxQueueMessagesWaitingFromISR(xQueue: QueueHandle_t) -> UBaseType_t {
let uxReturn: UBaseType_t;
traceENTER_uxQueueMessagesWaitingFromISR(xQueue);
configASSERT(!xQueue.is_null());
uxReturn = (*xQueue).uxMessagesWaiting;
traceRETURN_uxQueueMessagesWaitingFromISR(uxReturn);
uxReturn
}
#[cfg(any(feature = "alloc", feature = "heap-4", feature = "heap-5"))]
pub unsafe fn vQueueDelete(xQueue: QueueHandle_t) {
let pxQueue = xQueue as *mut Queue_t;
traceENTER_vQueueDelete(xQueue);
configASSERT(!pxQueue.is_null());
traceQUEUE_DELETE(pxQueue as *mut c_void);
#[cfg(feature = "queue-registry")]
{
vQueueUnregisterQueue(xQueue);
}
if (*pxQueue).ucStaticallyAllocated == pdFALSE as u8 {
vPortFree(pxQueue as *mut c_void);
} else {
mtCOVERAGE_TEST_MARKER();
}
traceRETURN_vQueueDelete();
}
pub unsafe fn uxQueueGetQueueItemSize(xQueue: QueueHandle_t) -> UBaseType_t {
configASSERT(!xQueue.is_null());
(*xQueue).uxItemSize
}
pub unsafe fn uxQueueGetQueueLength(xQueue: QueueHandle_t) -> UBaseType_t {
configASSERT(!xQueue.is_null());
(*xQueue).uxLength
}
pub unsafe fn xQueueIsQueueEmptyFromISR(xQueue: QueueHandle_t) -> BaseType_t {
let xReturn: BaseType_t;
traceENTER_xQueueIsQueueEmptyFromISR(xQueue);
configASSERT(!xQueue.is_null());
if (*xQueue).uxMessagesWaiting == 0 {
xReturn = pdTRUE;
} else {
xReturn = pdFALSE;
}
traceRETURN_xQueueIsQueueEmptyFromISR(xReturn);
xReturn
}
pub unsafe fn xQueueIsQueueFullFromISR(xQueue: QueueHandle_t) -> BaseType_t {
let xReturn: BaseType_t;
traceENTER_xQueueIsQueueFullFromISR(xQueue);
configASSERT(!xQueue.is_null());
if (*xQueue).uxMessagesWaiting == (*xQueue).uxLength {
xReturn = pdTRUE;
} else {
xReturn = pdFALSE;
}
traceRETURN_xQueueIsQueueFullFromISR(xReturn);
xReturn
}
#[cfg(feature = "trace-facility")]
pub unsafe fn uxQueueGetQueueNumber(xQueue: QueueHandle_t) -> UBaseType_t {
traceENTER_uxQueueGetQueueNumber(xQueue);
let uxReturn = (*xQueue).uxQueueNumber;
traceRETURN_uxQueueGetQueueNumber(uxReturn);
uxReturn
}
#[cfg(feature = "trace-facility")]
pub unsafe fn vQueueSetQueueNumber(xQueue: QueueHandle_t, uxQueueNumber: UBaseType_t) {
traceENTER_vQueueSetQueueNumber(xQueue, uxQueueNumber);
(*xQueue).uxQueueNumber = uxQueueNumber;
traceRETURN_vQueueSetQueueNumber();
}
#[cfg(feature = "trace-facility")]
pub unsafe fn ucQueueGetQueueType(xQueue: QueueHandle_t) -> u8 {
traceENTER_ucQueueGetQueueType(xQueue);
let ucReturn = (*xQueue).ucQueueType;
traceRETURN_ucQueueGetQueueType(ucReturn);
ucReturn
}
#[inline(always)]
fn traceENTER_xQueueGenericReset(_pxQueue: *mut c_void, _xNewQueue: BaseType_t) {}
#[inline(always)]
fn traceRETURN_xQueueGenericReset(_xReturn: BaseType_t) {}
#[inline(always)]
fn traceENTER_xQueueGenericCreateStatic(
_uxQueueLength: UBaseType_t,
_uxItemSize: UBaseType_t,
_pucQueueStorage: *mut c_void,
_pxStaticQueue: *mut c_void,
_ucQueueType: u8,
) {
}
#[inline(always)]
fn traceRETURN_xQueueGenericCreateStatic(_pxNewQueue: *mut c_void) {}
#[inline(always)]
fn traceENTER_xQueueGenericGetStaticBuffers(
_xQueue: QueueHandle_t,
_ppucQueueStorage: *mut c_void,
_ppxStaticQueue: *mut c_void,
) {
}
#[inline(always)]
fn traceRETURN_xQueueGenericGetStaticBuffers(_xReturn: BaseType_t) {}
#[inline(always)]
fn traceENTER_xQueueGenericCreate(
_uxQueueLength: UBaseType_t,
_uxItemSize: UBaseType_t,
_ucQueueType: u8,
) {
}
#[inline(always)]
fn traceRETURN_xQueueGenericCreate(_pxNewQueue: *mut c_void) {}
#[inline(always)]
fn traceENTER_xQueueGenericSend(
_pxQueue: *mut c_void,
_pvItemToQueue: *const c_void,
_xTicksToWait: TickType_t,
_xCopyPosition: BaseType_t,
) {
}
#[inline(always)]
fn traceRETURN_xQueueGenericSend(_xReturn: BaseType_t) {}
#[inline(always)]
fn traceENTER_xQueueReceive(
_pxQueue: *mut c_void,
_pvBuffer: *mut c_void,
_xTicksToWait: TickType_t,
) {
}
#[inline(always)]
fn traceRETURN_xQueueReceive(_xReturn: BaseType_t) {}
#[cfg(feature = "use-mutexes")]
#[inline(always)]
fn traceENTER_xQueueCreateMutexStatic(_ucQueueType: u8, _pxStaticQueue: *mut StaticQueue_t) {}
#[cfg(feature = "use-mutexes")]
#[inline(always)]
fn traceRETURN_xQueueCreateMutexStatic(_xNewQueue: QueueHandle_t) {}
#[cfg(feature = "use-mutexes")]
#[inline(always)]
fn traceCREATE_MUTEX(_pxNewQueue: *mut c_void) {}
#[cfg(feature = "use-mutexes")]
#[inline(always)]
fn traceCREATE_MUTEX_FAILED() {}
#[cfg(feature = "use-mutexes")]
#[inline(always)]
fn traceENTER_xQueueGetMutexHolder(_xSemaphore: QueueHandle_t) {}
#[cfg(feature = "use-mutexes")]
#[inline(always)]
fn traceRETURN_xQueueGetMutexHolder(_pxReturn: TaskHandle_t) {}
#[cfg(feature = "use-mutexes")]
#[inline(always)]
fn traceENTER_xQueueGetMutexHolderFromISR(_xSemaphore: QueueHandle_t) {}
#[cfg(feature = "use-mutexes")]
#[inline(always)]
fn traceRETURN_xQueueGetMutexHolderFromISR(_pxReturn: TaskHandle_t) {}
#[cfg(feature = "use-mutexes")]
#[inline(always)]
fn traceENTER_xQueueGiveMutexRecursive(_xMutex: QueueHandle_t) {}
#[cfg(feature = "use-mutexes")]
#[inline(always)]
fn traceRETURN_xQueueGiveMutexRecursive(_xReturn: BaseType_t) {}
#[cfg(feature = "use-mutexes")]
#[inline(always)]
fn traceGIVE_MUTEX_RECURSIVE(_pxMutex: *mut c_void) {}
#[cfg(feature = "use-mutexes")]
#[inline(always)]
fn traceGIVE_MUTEX_RECURSIVE_FAILED(_pxMutex: *mut c_void) {}
#[cfg(feature = "use-mutexes")]
#[inline(always)]
fn traceENTER_xQueueTakeMutexRecursive(_xMutex: QueueHandle_t, _xTicksToWait: TickType_t) {}
#[cfg(feature = "use-mutexes")]
#[inline(always)]
fn traceRETURN_xQueueTakeMutexRecursive(_xReturn: BaseType_t) {}
#[cfg(feature = "use-mutexes")]
#[inline(always)]
fn traceTAKE_MUTEX_RECURSIVE(_pxMutex: *mut c_void) {}
#[cfg(feature = "use-mutexes")]
#[inline(always)]
fn traceTAKE_MUTEX_RECURSIVE_FAILED(_pxMutex: *mut c_void) {}
#[cfg(any(feature = "alloc", feature = "heap-4", feature = "heap-5"))]
#[inline(always)]
fn traceENTER_xQueueCreateCountingSemaphore(
_uxMaxCount: UBaseType_t,
_uxInitialCount: UBaseType_t,
) {
}
#[cfg(any(feature = "alloc", feature = "heap-4", feature = "heap-5"))]
#[inline(always)]
fn traceRETURN_xQueueCreateCountingSemaphore(_xHandle: QueueHandle_t) {}
#[inline(always)]
fn traceENTER_xQueueCreateCountingSemaphoreStatic(
_uxMaxCount: UBaseType_t,
_uxInitialCount: UBaseType_t,
_pxStaticQueue: *mut StaticQueue_t,
) {
}
#[inline(always)]
fn traceRETURN_xQueueCreateCountingSemaphoreStatic(_xHandle: QueueHandle_t) {}
#[inline(always)]
fn traceCREATE_COUNTING_SEMAPHORE() {}
#[inline(always)]
fn traceCREATE_COUNTING_SEMAPHORE_FAILED() {}
#[inline(always)]
fn traceENTER_xQueueGiveFromISR(
_xQueue: QueueHandle_t,
_pxHigherPriorityTaskWoken: *mut BaseType_t,
) {
}
#[inline(always)]
fn traceRETURN_xQueueGiveFromISR(_xReturn: BaseType_t) {}
#[inline(always)]
fn traceQUEUE_SEND_FROM_ISR(_pxQueue: *mut c_void) {}
#[inline(always)]
fn traceQUEUE_SEND_FROM_ISR_FAILED(_pxQueue: *mut c_void) {}
#[inline(always)]
fn traceENTER_xQueuePeek(_pxQueue: *mut c_void, _pvBuffer: *mut c_void, _xTicksToWait: TickType_t) {
}
#[inline(always)]
fn traceRETURN_xQueuePeek(_xReturn: BaseType_t) {}
#[inline(always)]
fn traceQUEUE_PEEK(_pxQueue: *mut c_void) {}
#[inline(always)]
fn traceQUEUE_PEEK_FAILED(_pxQueue: *mut c_void) {}
#[inline(always)]
fn traceBLOCKING_ON_QUEUE_PEEK(_pxQueue: *mut c_void) {}
#[inline(always)]
fn traceENTER_xQueueReceiveFromISR(
_xQueue: QueueHandle_t,
_pvBuffer: *mut c_void,
_pxHigherPriorityTaskWoken: *mut BaseType_t,
) {
}
#[inline(always)]
fn traceRETURN_xQueueReceiveFromISR(_xReturn: BaseType_t) {}
#[inline(always)]
fn traceQUEUE_RECEIVE_FROM_ISR(_pxQueue: *mut c_void) {}
#[inline(always)]
fn traceQUEUE_RECEIVE_FROM_ISR_FAILED(_pxQueue: *mut c_void) {}
#[inline(always)]
fn traceENTER_xQueuePeekFromISR(_xQueue: QueueHandle_t, _pvBuffer: *mut c_void) {}
#[inline(always)]
fn traceRETURN_xQueuePeekFromISR(_xReturn: BaseType_t) {}
#[inline(always)]
fn traceQUEUE_PEEK_FROM_ISR(_pxQueue: *mut c_void) {}
#[inline(always)]
fn traceQUEUE_PEEK_FROM_ISR_FAILED(_pxQueue: *mut c_void) {}
#[inline(always)]
fn traceENTER_uxQueueMessagesWaitingFromISR(_xQueue: QueueHandle_t) {}
#[inline(always)]
fn traceRETURN_uxQueueMessagesWaitingFromISR(_uxReturn: UBaseType_t) {}
#[cfg(any(feature = "alloc", feature = "heap-4", feature = "heap-5"))]
#[inline(always)]
fn traceENTER_vQueueDelete(_xQueue: QueueHandle_t) {}
#[cfg(any(feature = "alloc", feature = "heap-4", feature = "heap-5"))]
#[inline(always)]
fn traceRETURN_vQueueDelete() {}
#[cfg(any(feature = "alloc", feature = "heap-4", feature = "heap-5"))]
#[inline(always)]
fn traceQUEUE_DELETE(_pxQueue: *mut c_void) {}
#[inline(always)]
fn traceENTER_xQueueIsQueueEmptyFromISR(_xQueue: QueueHandle_t) {}
#[inline(always)]
fn traceRETURN_xQueueIsQueueEmptyFromISR(_xReturn: BaseType_t) {}
#[inline(always)]
fn traceENTER_xQueueIsQueueFullFromISR(_xQueue: QueueHandle_t) {}
#[inline(always)]
fn traceRETURN_xQueueIsQueueFullFromISR(_xReturn: BaseType_t) {}
#[cfg(feature = "trace-facility")]
#[inline(always)]
fn traceENTER_uxQueueGetQueueNumber(_xQueue: QueueHandle_t) {}
#[cfg(feature = "trace-facility")]
#[inline(always)]
fn traceRETURN_uxQueueGetQueueNumber(_uxReturn: UBaseType_t) {}
#[cfg(feature = "trace-facility")]
#[inline(always)]
fn traceENTER_vQueueSetQueueNumber(_xQueue: QueueHandle_t, _uxQueueNumber: UBaseType_t) {}
#[cfg(feature = "trace-facility")]
#[inline(always)]
fn traceRETURN_vQueueSetQueueNumber() {}
#[cfg(feature = "trace-facility")]
#[inline(always)]
fn traceENTER_ucQueueGetQueueType(_xQueue: QueueHandle_t) {}
#[cfg(feature = "trace-facility")]
#[inline(always)]
fn traceRETURN_ucQueueGetQueueType(_ucReturn: u8) {}
#[inline(always)]
pub unsafe fn xQueueSendToBack(
xQueue: QueueHandle_t,
pvItemToQueue: *const c_void,
xTicksToWait: TickType_t,
) -> BaseType_t {
xQueueGenericSend(xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_BACK)
}
#[inline(always)]
pub unsafe fn xQueueSendToFront(
xQueue: QueueHandle_t,
pvItemToQueue: *const c_void,
xTicksToWait: TickType_t,
) -> BaseType_t {
xQueueGenericSend(xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_FRONT)
}
#[inline(always)]
pub unsafe fn xQueueSend(
xQueue: QueueHandle_t,
pvItemToQueue: *const c_void,
xTicksToWait: TickType_t,
) -> BaseType_t {
xQueueSendToBack(xQueue, pvItemToQueue, xTicksToWait)
}
#[inline(always)]
pub unsafe fn xQueueSendToBackFromISR(
xQueue: QueueHandle_t,
pvItemToQueue: *const c_void,
pxHigherPriorityTaskWoken: *mut BaseType_t,
) -> BaseType_t {
xQueueGenericSendFromISR(
xQueue,
pvItemToQueue,
pxHigherPriorityTaskWoken,
queueSEND_TO_BACK,
)
}
#[inline(always)]
pub unsafe fn xQueueSendFromISR(
xQueue: QueueHandle_t,
pvItemToQueue: *const c_void,
pxHigherPriorityTaskWoken: *mut BaseType_t,
) -> BaseType_t {
xQueueSendToBackFromISR(xQueue, pvItemToQueue, pxHigherPriorityTaskWoken)
}
#[allow(unused_assignments)] pub unsafe fn xQueueGenericSendFromISR(
xQueue: QueueHandle_t,
pvItemToQueue: *const c_void,
pxHigherPriorityTaskWoken: *mut BaseType_t,
xCopyPosition: BaseType_t,
) -> BaseType_t {
let mut xReturn: BaseType_t = pdFAIL;
let pxQueue = xQueue as *mut Queue_t;
configASSERT(!pxQueue.is_null());
configASSERT(!(!pvItemToQueue.is_null() && (*pxQueue).uxItemSize == 0));
let uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
{
if (*pxQueue).uxMessagesWaiting < (*pxQueue).uxLength {
let cTxLock = (*pxQueue).cTxLock;
traceQUEUE_SEND_FROM_ISR(pxQueue as *mut c_void);
prvCopyDataToQueue(pxQueue, pvItemToQueue, xCopyPosition);
#[cfg(feature = "queue-sets")]
{
if !(*pxQueue).pxQueueSetContainer.is_null() {
if prvNotifyQueueSetContainer(pxQueue) != pdFALSE {
if !pxHigherPriorityTaskWoken.is_null() {
*pxHigherPriorityTaskWoken = pdTRUE;
}
}
} else {
if cTxLock == queueUNLOCKED {
if listLIST_IS_EMPTY(&(*pxQueue).xTasksWaitingToReceive) == pdFALSE {
if xTaskRemoveFromEventList(&(*pxQueue).xTasksWaitingToReceive)
!= pdFALSE
{
if !pxHigherPriorityTaskWoken.is_null() {
*pxHigherPriorityTaskWoken = pdTRUE;
}
}
}
} else {
configASSERT(cTxLock != queueINT8_MAX);
(*pxQueue).cTxLock = cTxLock + 1;
}
}
}
#[cfg(not(feature = "queue-sets"))]
{
if cTxLock == queueUNLOCKED {
if listLIST_IS_EMPTY(&(*pxQueue).xTasksWaitingToReceive) == pdFALSE {
if xTaskRemoveFromEventList(&(*pxQueue).xTasksWaitingToReceive) != pdFALSE {
if !pxHigherPriorityTaskWoken.is_null() {
*pxHigherPriorityTaskWoken = pdTRUE;
}
}
}
} else {
configASSERT(cTxLock != queueINT8_MAX);
(*pxQueue).cTxLock = cTxLock + 1;
}
}
xReturn = pdPASS;
} else {
traceQUEUE_SEND_FROM_ISR_FAILED(pxQueue as *mut c_void);
xReturn = errQUEUE_FULL;
}
}
portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus);
xReturn
}
pub unsafe fn xQueueGiveFromISR(
xQueue: QueueHandle_t,
pxHigherPriorityTaskWoken: *mut BaseType_t,
) -> BaseType_t {
let xReturn: BaseType_t;
let pxQueue = xQueue as *mut Queue_t;
traceENTER_xQueueGiveFromISR(xQueue, pxHigherPriorityTaskWoken);
configASSERT(!pxQueue.is_null());
configASSERT((*pxQueue).uxItemSize == 0);
configASSERT(!(*pxQueue).pcHead.is_null() || (*pxQueue).u.xSemaphore.xMutexHolder.is_null());
let uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
{
let uxMessagesWaiting = (*pxQueue).uxMessagesWaiting;
if uxMessagesWaiting < (*pxQueue).uxLength {
let cTxLock = (*pxQueue).cTxLock;
traceQUEUE_SEND_FROM_ISR(pxQueue as *mut c_void);
(*pxQueue).uxMessagesWaiting = uxMessagesWaiting + 1;
#[cfg(feature = "queue-sets")]
{
if !(*pxQueue).pxQueueSetContainer.is_null() {
if prvNotifyQueueSetContainer(pxQueue) != pdFALSE {
if !pxHigherPriorityTaskWoken.is_null() {
*pxHigherPriorityTaskWoken = pdTRUE;
}
}
} else {
if cTxLock == queueUNLOCKED {
if listLIST_IS_EMPTY(&(*pxQueue).xTasksWaitingToReceive) == pdFALSE {
if xTaskRemoveFromEventList(&(*pxQueue).xTasksWaitingToReceive)
!= pdFALSE
{
if !pxHigherPriorityTaskWoken.is_null() {
*pxHigherPriorityTaskWoken = pdTRUE;
}
}
}
} else {
configASSERT(cTxLock != queueINT8_MAX);
(*pxQueue).cTxLock = cTxLock + 1;
}
}
}
#[cfg(not(feature = "queue-sets"))]
{
if cTxLock == queueUNLOCKED {
if listLIST_IS_EMPTY(&(*pxQueue).xTasksWaitingToReceive) == pdFALSE {
if xTaskRemoveFromEventList(&(*pxQueue).xTasksWaitingToReceive) != pdFALSE {
if !pxHigherPriorityTaskWoken.is_null() {
*pxHigherPriorityTaskWoken = pdTRUE;
}
}
}
} else {
configASSERT(cTxLock != queueINT8_MAX);
(*pxQueue).cTxLock = cTxLock + 1;
}
}
xReturn = pdPASS;
} else {
traceQUEUE_SEND_FROM_ISR_FAILED(pxQueue as *mut c_void);
xReturn = errQUEUE_FULL;
}
}
portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus);
traceRETURN_xQueueGiveFromISR(xReturn);
xReturn
}
pub unsafe fn vQueueWaitForMessageRestricted(
xQueue: QueueHandle_t,
xTicksToWait: TickType_t,
xWaitIndefinitely: BaseType_t,
) {
let pxQueue = xQueue as *mut Queue_t;
prvLockQueue(pxQueue);
if (*pxQueue).uxMessagesWaiting == 0 {
vTaskPlaceOnEventListRestricted(
&mut (*pxQueue).xTasksWaitingToReceive,
xTicksToWait,
xWaitIndefinitely,
);
}
prvUnlockQueue(pxQueue);
}
#[cfg(all(
any(feature = "alloc", feature = "heap-4", feature = "heap-5"),
feature = "use-mutexes"
))]
pub unsafe fn xQueueCreateMutex(ucQueueType: u8) -> QueueHandle_t {
let xNewQueue = xQueueGenericCreate(1, 0, ucQueueType);
if !xNewQueue.is_null() {
let pxQueue = xNewQueue as *mut Queue_t;
(*pxQueue).u.xSemaphore.xMutexHolder = ptr::null_mut();
(*pxQueue).u.xSemaphore.uxRecursiveCallCount = 0;
(*pxQueue).pcHead = ptr::null_mut();
xQueueGenericSend(xNewQueue, ptr::null(), 0, queueSEND_TO_BACK);
}
xNewQueue
}
#[cfg(feature = "use-mutexes")]
pub unsafe fn xQueueCreateMutexStatic(
ucQueueType: u8,
pxStaticQueue: *mut StaticQueue_t,
) -> QueueHandle_t {
traceENTER_xQueueCreateMutexStatic(ucQueueType, pxStaticQueue);
let xNewQueue = xQueueGenericCreateStatic(1, 0, ptr::null_mut(), pxStaticQueue, ucQueueType);
if !xNewQueue.is_null() {
prvInitialiseMutex(xNewQueue as *mut Queue_t);
}
traceRETURN_xQueueCreateMutexStatic(xNewQueue);
xNewQueue
}
#[cfg(feature = "use-mutexes")]
unsafe fn prvInitialiseMutex(pxNewQueue: *mut Queue_t) {
if !pxNewQueue.is_null() {
(*pxNewQueue).u.xSemaphore.xMutexHolder = ptr::null_mut();
(*pxNewQueue).u.xSemaphore.uxRecursiveCallCount = 0;
(*pxNewQueue).pcHead = ptr::null_mut();
xQueueGenericSend(
pxNewQueue as QueueHandle_t,
ptr::null(),
0,
queueSEND_TO_BACK,
);
traceCREATE_MUTEX(pxNewQueue as *mut c_void);
} else {
traceCREATE_MUTEX_FAILED();
}
}
#[cfg(feature = "use-mutexes")]
pub unsafe fn xQueueGetMutexHolder(xSemaphore: QueueHandle_t) -> TaskHandle_t {
let mut pxReturn: TaskHandle_t = ptr::null_mut();
let pxSemaphore = xSemaphore as *mut Queue_t;
traceENTER_xQueueGetMutexHolder(xSemaphore);
configASSERT(!xSemaphore.is_null());
taskENTER_CRITICAL();
{
if (*pxSemaphore).pcHead.is_null() {
pxReturn = (*pxSemaphore).u.xSemaphore.xMutexHolder;
}
}
taskEXIT_CRITICAL();
traceRETURN_xQueueGetMutexHolder(pxReturn);
pxReturn
}
#[cfg(feature = "use-mutexes")]
pub unsafe fn xQueueGetMutexHolderFromISR(xSemaphore: QueueHandle_t) -> TaskHandle_t {
let pxReturn: TaskHandle_t;
traceENTER_xQueueGetMutexHolderFromISR(xSemaphore);
configASSERT(!xSemaphore.is_null());
if (*(xSemaphore as *mut Queue_t)).pcHead.is_null() {
pxReturn = (*(xSemaphore as *mut Queue_t)).u.xSemaphore.xMutexHolder;
} else {
pxReturn = ptr::null_mut();
}
traceRETURN_xQueueGetMutexHolderFromISR(pxReturn);
pxReturn
}
#[cfg(feature = "use-mutexes")]
pub unsafe fn xQueueGiveMutexRecursive(xMutex: QueueHandle_t) -> BaseType_t {
let xReturn: BaseType_t;
let pxMutex = xMutex as *mut Queue_t;
traceENTER_xQueueGiveMutexRecursive(xMutex);
configASSERT(!pxMutex.is_null());
if (*pxMutex).u.xSemaphore.xMutexHolder == xTaskGetCurrentTaskHandle() {
traceGIVE_MUTEX_RECURSIVE(pxMutex as *mut c_void);
(*pxMutex).u.xSemaphore.uxRecursiveCallCount -= 1;
if (*pxMutex).u.xSemaphore.uxRecursiveCallCount == 0 {
xQueueGenericSend(pxMutex as QueueHandle_t, ptr::null(), 0, queueSEND_TO_BACK);
}
xReturn = pdPASS;
} else {
xReturn = pdFAIL;
traceGIVE_MUTEX_RECURSIVE_FAILED(pxMutex as *mut c_void);
}
traceRETURN_xQueueGiveMutexRecursive(xReturn);
xReturn
}
#[inline(always)]
pub unsafe fn xQueueSemaphoreTake(xQueue: QueueHandle_t, xTicksToWait: TickType_t) -> BaseType_t {
let pxQueue = xQueue as *mut Queue_t;
#[cfg(feature = "use-mutexes")]
{
if (*pxQueue).pcHead.is_null() {
return xQueueTakeMutexRecursive(xQueue, xTicksToWait);
}
}
xQueueReceive(xQueue, ptr::null_mut(), xTicksToWait)
}
#[cfg(feature = "use-mutexes")]
pub unsafe fn xQueueTakeMutexRecursive(
xMutex: QueueHandle_t,
xTicksToWait: TickType_t,
) -> BaseType_t {
use crate::kernel::tasks::{pvTaskIncrementMutexHeldCount, xTaskGetCurrentTaskHandle};
let xReturn: BaseType_t;
let pxMutex = xMutex as *mut Queue_t;
traceENTER_xQueueTakeMutexRecursive(xMutex, xTicksToWait);
configASSERT(!pxMutex.is_null());
let xCurrentTaskHandle = xTaskGetCurrentTaskHandle();
if (*pxMutex).u.xSemaphore.xMutexHolder == xCurrentTaskHandle {
(*pxMutex).u.xSemaphore.uxRecursiveCallCount += 1;
xReturn = pdPASS;
traceTAKE_MUTEX_RECURSIVE(pxMutex as *mut c_void);
} else {
xReturn = xQueueReceive(xMutex, ptr::null_mut(), xTicksToWait);
if xReturn == pdPASS {
(*pxMutex).u.xSemaphore.uxRecursiveCallCount = 1;
pvTaskIncrementMutexHeldCount();
traceTAKE_MUTEX_RECURSIVE(pxMutex as *mut c_void);
} else {
traceTAKE_MUTEX_RECURSIVE_FAILED(pxMutex as *mut c_void);
}
}
traceRETURN_xQueueTakeMutexRecursive(xReturn);
xReturn
}
#[cfg(any(feature = "alloc", feature = "heap-4", feature = "heap-5"))]
pub unsafe fn xQueueCreateCountingSemaphore(
uxMaxCount: UBaseType_t,
uxInitialCount: UBaseType_t,
) -> QueueHandle_t {
let xHandle: QueueHandle_t;
traceENTER_xQueueCreateCountingSemaphore(uxMaxCount, uxInitialCount);
configASSERT(uxMaxCount != 0);
configASSERT(uxInitialCount <= uxMaxCount);
xHandle = xQueueGenericCreate(
uxMaxCount,
queueSEMAPHORE_QUEUE_ITEM_LENGTH,
queueQUEUE_TYPE_COUNTING_SEMAPHORE,
);
if !xHandle.is_null() {
let pxQueue = xHandle as *mut Queue_t;
(*pxQueue).uxMessagesWaiting = uxInitialCount;
traceCREATE_COUNTING_SEMAPHORE();
} else {
traceCREATE_COUNTING_SEMAPHORE_FAILED();
}
traceRETURN_xQueueCreateCountingSemaphore(xHandle);
xHandle
}
pub unsafe fn xQueueCreateCountingSemaphoreStatic(
uxMaxCount: UBaseType_t,
uxInitialCount: UBaseType_t,
pxStaticQueue: *mut StaticQueue_t,
) -> QueueHandle_t {
let xHandle: QueueHandle_t;
traceENTER_xQueueCreateCountingSemaphoreStatic(uxMaxCount, uxInitialCount, pxStaticQueue);
configASSERT(uxMaxCount != 0);
configASSERT(uxInitialCount <= uxMaxCount);
xHandle = xQueueGenericCreateStatic(
uxMaxCount,
queueSEMAPHORE_QUEUE_ITEM_LENGTH,
ptr::null_mut(),
pxStaticQueue,
queueQUEUE_TYPE_COUNTING_SEMAPHORE,
);
if !xHandle.is_null() {
let pxQueue = xHandle as *mut Queue_t;
(*pxQueue).uxMessagesWaiting = uxInitialCount;
traceCREATE_COUNTING_SEMAPHORE();
} else {
traceCREATE_COUNTING_SEMAPHORE_FAILED();
}
traceRETURN_xQueueCreateCountingSemaphoreStatic(xHandle);
xHandle
}
#[cfg(feature = "queue-sets")]
unsafe fn prvNotifyQueueSetContainer(pxQueue: *const Queue_t) -> BaseType_t {
let pxQueueSetContainer = (*pxQueue).pxQueueSetContainer;
let mut xReturn: BaseType_t = pdFALSE;
configASSERT(!pxQueueSetContainer.is_null());
configASSERT((*pxQueueSetContainer).uxMessagesWaiting < (*pxQueueSetContainer).uxLength);
if (*pxQueueSetContainer).uxMessagesWaiting < (*pxQueueSetContainer).uxLength {
let cTxLock = (*pxQueueSetContainer).cTxLock;
traceQUEUE_SET_SEND(pxQueueSetContainer as *mut c_void);
xReturn = prvCopyDataToQueue(
pxQueueSetContainer,
&pxQueue as *const *const Queue_t as *const c_void,
queueSEND_TO_BACK,
);
if cTxLock == queueUNLOCKED {
if listLIST_IS_EMPTY(&(*pxQueueSetContainer).xTasksWaitingToReceive) == pdFALSE {
if xTaskRemoveFromEventList(&(*pxQueueSetContainer).xTasksWaitingToReceive)
!= pdFALSE
{
xReturn = pdTRUE;
}
}
} else {
if cTxLock < queueINT8_MAX {
(*pxQueueSetContainer).cTxLock = cTxLock + 1;
}
}
}
xReturn
}
#[cfg(all(feature = "queue-sets", feature = "alloc"))]
pub unsafe fn xQueueCreateSet(uxEventQueueLength: UBaseType_t) -> QueueSetHandle_t {
let pxQueue = xQueueGenericCreate(
uxEventQueueLength,
core::mem::size_of::<*mut Queue_t>() as UBaseType_t,
queueQUEUE_TYPE_SET,
);
pxQueue
}
#[cfg(feature = "queue-sets")]
pub unsafe fn xQueueCreateSetStatic(
uxEventQueueLength: UBaseType_t,
pucQueueStorage: *mut u8,
pxStaticQueue: *mut StaticQueue_t,
) -> QueueSetHandle_t {
let pxQueue = xQueueGenericCreateStatic(
uxEventQueueLength,
core::mem::size_of::<*mut Queue_t>() as UBaseType_t,
pucQueueStorage,
pxStaticQueue,
queueQUEUE_TYPE_SET,
);
pxQueue
}
#[cfg(feature = "queue-sets")]
pub unsafe fn xQueueAddToSet(
xQueueOrSemaphore: QueueSetMemberHandle_t,
xQueueSet: QueueSetHandle_t,
) -> BaseType_t {
let xReturn: BaseType_t;
taskENTER_CRITICAL();
{
if !(*xQueueOrSemaphore).pxQueueSetContainer.is_null() {
xReturn = pdFAIL;
} else if (*xQueueOrSemaphore).uxMessagesWaiting != 0 {
xReturn = pdFAIL;
} else {
(*xQueueOrSemaphore).pxQueueSetContainer = xQueueSet;
xReturn = pdPASS;
}
}
taskEXIT_CRITICAL();
xReturn
}
#[cfg(feature = "queue-sets")]
pub unsafe fn xQueueRemoveFromSet(
xQueueOrSemaphore: QueueSetMemberHandle_t,
xQueueSet: QueueSetHandle_t,
) -> BaseType_t {
let xReturn: BaseType_t;
if (*xQueueOrSemaphore).pxQueueSetContainer != xQueueSet {
xReturn = pdFAIL;
} else if (*xQueueOrSemaphore).uxMessagesWaiting != 0 {
xReturn = pdFAIL;
} else {
taskENTER_CRITICAL();
{
(*xQueueOrSemaphore).pxQueueSetContainer = ptr::null_mut();
}
taskEXIT_CRITICAL();
xReturn = pdPASS;
}
xReturn
}
#[cfg(feature = "queue-sets")]
pub unsafe fn xQueueSelectFromSet(
xQueueSet: QueueSetHandle_t,
xTicksToWait: TickType_t,
) -> QueueSetMemberHandle_t {
let mut xReturn: QueueSetMemberHandle_t = ptr::null_mut();
xQueueReceive(
xQueueSet,
&mut xReturn as *mut QueueSetMemberHandle_t as *mut c_void,
xTicksToWait,
);
xReturn
}
#[cfg(feature = "queue-sets")]
pub unsafe fn xQueueSelectFromSetFromISR(xQueueSet: QueueSetHandle_t) -> QueueSetMemberHandle_t {
let mut xReturn: QueueSetMemberHandle_t = ptr::null_mut();
let pxQueue = xQueueSet as *mut Queue_t;
let uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
{
if (*pxQueue).uxMessagesWaiting > 0 {
let pcReadFrom = (*pxQueue).u.xQueue.pcReadFrom;
let pcNextReadFrom = pcReadFrom.add((*pxQueue).uxItemSize as usize);
let pcActualRead = if pcNextReadFrom >= (*pxQueue).u.xQueue.pcTail {
(*pxQueue).pcHead
} else {
pcNextReadFrom
};
(*pxQueue).u.xQueue.pcReadFrom = pcActualRead;
ptr::copy_nonoverlapping(
pcActualRead as *const QueueSetMemberHandle_t,
&mut xReturn,
1,
);
(*pxQueue).uxMessagesWaiting -= 1;
}
}
portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus);
xReturn
}
#[cfg(feature = "queue-sets")]
#[inline(always)]
fn traceQUEUE_SET_SEND(_pxQueue: *mut c_void) {}
#[cfg(feature = "queue-registry")]
mod queue_registry {
use super::*;
use crate::config::configQUEUE_REGISTRY_SIZE;
#[repr(C)]
struct QueueRegistryItem {
pcQueueName: *const u8,
xHandle: QueueHandle_t,
}
impl QueueRegistryItem {
const fn new() -> Self {
QueueRegistryItem {
pcQueueName: ptr::null(),
xHandle: ptr::null_mut(),
}
}
}
static mut QUEUE_REGISTRY: [QueueRegistryItem; configQUEUE_REGISTRY_SIZE] =
[const { QueueRegistryItem::new() }; configQUEUE_REGISTRY_SIZE];
pub unsafe fn vQueueAddToRegistry(xQueue: QueueHandle_t, pcQueueName: *const u8) {
traceENTER_vQueueAddToRegistry(xQueue, pcQueueName);
configASSERT(!xQueue.is_null());
if !pcQueueName.is_null() {
let mut pxEntryToWrite: Option<usize> = None;
for ux in 0..configQUEUE_REGISTRY_SIZE {
if xQueue == QUEUE_REGISTRY[ux].xHandle {
pxEntryToWrite = Some(ux);
break;
}
else if pxEntryToWrite.is_none() && QUEUE_REGISTRY[ux].pcQueueName.is_null() {
pxEntryToWrite = Some(ux);
}
}
if let Some(ux) = pxEntryToWrite {
QUEUE_REGISTRY[ux].pcQueueName = pcQueueName;
QUEUE_REGISTRY[ux].xHandle = xQueue;
traceQUEUE_REGISTRY_ADD(xQueue, pcQueueName);
}
}
traceRETURN_vQueueAddToRegistry();
}
pub unsafe fn pcQueueGetName(xQueue: QueueHandle_t) -> *const u8 {
traceENTER_pcQueueGetName(xQueue);
configASSERT(!xQueue.is_null());
let mut pcReturn: *const u8 = ptr::null();
for ux in 0..configQUEUE_REGISTRY_SIZE {
if QUEUE_REGISTRY[ux].xHandle == xQueue {
pcReturn = QUEUE_REGISTRY[ux].pcQueueName;
break;
}
}
traceRETURN_pcQueueGetName(pcReturn);
pcReturn
}
pub unsafe fn vQueueUnregisterQueue(xQueue: QueueHandle_t) {
traceENTER_vQueueUnregisterQueue(xQueue);
configASSERT(!xQueue.is_null());
for ux in 0..configQUEUE_REGISTRY_SIZE {
if QUEUE_REGISTRY[ux].xHandle == xQueue {
QUEUE_REGISTRY[ux].pcQueueName = ptr::null();
QUEUE_REGISTRY[ux].xHandle = ptr::null_mut();
break;
}
}
traceRETURN_vQueueUnregisterQueue();
}
#[inline(always)]
fn traceENTER_vQueueAddToRegistry(_xQueue: QueueHandle_t, _pcQueueName: *const u8) {}
#[inline(always)]
fn traceRETURN_vQueueAddToRegistry() {}
#[inline(always)]
fn traceQUEUE_REGISTRY_ADD(_xQueue: QueueHandle_t, _pcQueueName: *const u8) {}
#[inline(always)]
fn traceENTER_pcQueueGetName(_xQueue: QueueHandle_t) {}
#[inline(always)]
fn traceRETURN_pcQueueGetName(_pcReturn: *const u8) {}
#[inline(always)]
fn traceENTER_vQueueUnregisterQueue(_xQueue: QueueHandle_t) {}
#[inline(always)]
fn traceRETURN_vQueueUnregisterQueue() {}
}
#[cfg(feature = "queue-registry")]
pub use queue_registry::*;