1052 lines
36 KiB
C
1052 lines
36 KiB
C
/*
|
|
* FreeRTOS Kernel V10.3.0
|
|
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
* this software and associated documentation files (the "Software"), to deal in
|
|
* the Software without restriction, including without limitation the rights to
|
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
|
* subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in all
|
|
* copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
*
|
|
* http://www.FreeRTOS.org
|
|
* http://aws.amazon.com/freertos
|
|
*
|
|
* 1 tab == 4 spaces!
|
|
*/
|
|
|
|
/*
|
|
* Tests the use of queue sets.
|
|
*
|
|
* A receive task creates a number of queues and adds them to a queue set before
|
|
* blocking on the queue set receive. A transmit task and (optionally) an
|
|
* interrupt repeatedly unblocks the receive task by sending messages to the
|
|
* queues in a pseudo random order. The receive task removes the messages from
|
|
* the queues and flags an error if the received message does not match that
|
|
* expected. The task sends values in the range 0 to
|
|
* queuesetINITIAL_ISR_TX_VALUE, and the ISR sends value in the range
|
|
* queuesetINITIAL_ISR_TX_VALUE to ULONG_MAX.
|
|
*/
|
|
|
|
/* Standard includes. */
|
|
#include <stdlib.h>
|
|
#include <limits.h>
|
|
|
|
/* Kernel includes. */
|
|
#include "FreeRTOS.h"
|
|
#include "task.h"
|
|
#include "queue.h"
|
|
|
|
/* Demo includes. */
|
|
#include "QueueSet.h"
|
|
|
|
#if (configUSE_QUEUE_SETS == \
|
|
1) /* Remove the tests if queue sets are not defined. */
|
|
|
|
/* The number of queues that are created and added to the queue set. */
|
|
#define queuesetNUM_QUEUES_IN_SET 3
|
|
|
|
/* The length of each created queue. */
|
|
#define queuesetQUEUE_LENGTH 3
|
|
|
|
/* Block times used in this demo. A block time or 0 means "don't block". */
|
|
#define queuesetSHORT_DELAY 200
|
|
#define queuesetDONT_BLOCK 0
|
|
|
|
/* Messages are sent in incrementing order from both a task and an interrupt.
|
|
The task sends values in the range 0 to 0xfffe, and the interrupt sends values
|
|
in the range of 0xffff to ULONG_MAX. */
|
|
#define queuesetINITIAL_ISR_TX_VALUE 0xffffUL
|
|
|
|
/* The priorities used in this demo. */
|
|
#define queuesetLOW_PRIORITY (tskIDLE_PRIORITY)
|
|
#define queuesetMEDIUM_PRIORITY (queuesetLOW_PRIORITY + 1)
|
|
|
|
/* For test purposes the priority of the sending task is changed after every
|
|
queuesetPRIORITY_CHANGE_LOOPS number of values are sent to a queue. */
|
|
#define queuesetPRIORITY_CHANGE_LOOPS \
|
|
((queuesetNUM_QUEUES_IN_SET * queuesetQUEUE_LENGTH) * 2)
|
|
|
|
/* The ISR sends to the queue every queuesetISR_TX_PERIOD ticks. */
|
|
#define queuesetISR_TX_PERIOD (100UL)
|
|
|
|
/* A delay inserted when the Tx task changes its priority to be above the idle
|
|
task priority to ensure the idle priority tasks get some CPU time before the
|
|
next iteration of the queue set Tx task. */
|
|
#define queuesetTX_LOOP_DELAY pdMS_TO_TICKS((TickType_t)200)
|
|
|
|
/* The allowable maximum deviation between a received value and the expected
|
|
received value. A deviation will occur when data is received from a queue
|
|
inside an ISR in between a task receiving from a queue and the task checking
|
|
the received value. */
|
|
#define queuesetALLOWABLE_RX_DEVIATION 3
|
|
|
|
/* Ignore values that are at the boundaries of allowable values to make the
|
|
testing of limits easier (don't have to deal with wrapping values). */
|
|
#define queuesetIGNORED_BOUNDARY (queuesetALLOWABLE_RX_DEVIATION * 2)
|
|
|
|
typedef enum {
|
|
eEqualPriority = 0, /* Tx and Rx tasks have the same priority. */
|
|
eTxHigherPriority, /* The priority of the Tx task is above that of the Rx task. */
|
|
eTxLowerPriority /* The priority of the Tx task is below that of the Rx task. */
|
|
} eRelativePriorities;
|
|
|
|
/*
|
|
* The task that periodically sends to the queue set.
|
|
*/
|
|
static void prvQueueSetSendingTask(void *pvParameters);
|
|
|
|
/*
|
|
* The task that reads from the queue set.
|
|
*/
|
|
static void prvQueueSetReceivingTask(void *pvParameters);
|
|
|
|
/*
|
|
* Check the value received from a queue is the expected value. Some values
|
|
* originate from the send task, some values originate from the ISR, with the
|
|
* range of the value being used to distinguish between the two message
|
|
* sources.
|
|
*/
|
|
static void prvCheckReceivedValue(uint32_t ulReceived);
|
|
|
|
/*
|
|
* For purposes of test coverage, functions that read from and write to a
|
|
* queue set from an ISR respectively.
|
|
*/
|
|
static void prvReceiveFromQueueInSetFromISR(void);
|
|
static void prvSendToQueueInSetFromISR(void);
|
|
|
|
/*
|
|
* Create the queues and add them to a queue set before resuming the Tx
|
|
* task.
|
|
*/
|
|
static void prvSetupTest(void);
|
|
|
|
/*
|
|
* Checks a value received from a queue falls within the range of expected
|
|
* values.
|
|
*/
|
|
static BaseType_t
|
|
prvCheckReceivedValueWithinExpectedRange(uint32_t ulReceived,
|
|
uint32_t ulExpectedReceived);
|
|
|
|
/*
|
|
* Increase test coverage by occasionally change the priorities of the two tasks
|
|
* relative to each other.
|
|
*/
|
|
static void prvChangeRelativePriorities(void);
|
|
|
|
/*
|
|
* Queue overwrites can only be performed on queues of length of one, requiring
|
|
* a special test function so a queue of length 1 can temporarily be added to a
|
|
* set.
|
|
*/
|
|
static void prvTestQueueOverwriteWithQueueSet(void);
|
|
|
|
/*
|
|
* Test the case where two queues within a set are written to with
|
|
* xQueueOverwrite().
|
|
*/
|
|
static void prvTestQueueOverwriteOnTwoQueusInQueueSet(void);
|
|
static void prvTestQueueOverwriteFromISROnTwoQueusInQueueSet(void);
|
|
|
|
/*
|
|
* Local pseudo random number seed and return functions. Used to avoid calls
|
|
* to the standard library.
|
|
*/
|
|
static size_t prvRand(void);
|
|
static void prvSRand(size_t uxSeed);
|
|
|
|
/*-----------------------------------------------------------*/
|
|
|
|
/* The queues that are added to the set. */
|
|
static QueueHandle_t xQueues[queuesetNUM_QUEUES_IN_SET] = { 0 };
|
|
|
|
/* Counts how many times each queue in the set is used to ensure all the
|
|
queues are used. */
|
|
static uint32_t ulQueueUsedCounter[queuesetNUM_QUEUES_IN_SET] = { 0 };
|
|
|
|
/* The handle of the queue set to which the queues are added. */
|
|
static QueueSetHandle_t xQueueSet;
|
|
|
|
/* If the prvQueueSetReceivingTask() task has not detected any errors then
|
|
it increments ulCycleCounter on each iteration.
|
|
xAreQueueSetTasksStillRunning() returns pdPASS if the value of
|
|
ulCycleCounter has changed between consecutive calls, and pdFALSE if
|
|
ulCycleCounter has stopped incrementing (indicating an error condition). */
|
|
static volatile uint32_t ulCycleCounter = 0UL;
|
|
|
|
/* Set to pdFAIL if an error is detected by any queue set task.
|
|
ulCycleCounter will only be incremented if xQueueSetTasksSatus equals pdPASS. */
|
|
static volatile BaseType_t xQueueSetTasksStatus = pdPASS;
|
|
|
|
/* Just a flag to let the function that writes to a queue from an ISR know that
|
|
the queues are setup and can be used. */
|
|
static volatile BaseType_t xSetupComplete = pdFALSE;
|
|
|
|
/* The value sent to the queue from the ISR is file scope so the
|
|
xAreQueeuSetTasksStillRunning() function can check it is incrementing as
|
|
expected. */
|
|
static volatile uint32_t ulISRTxValue = queuesetINITIAL_ISR_TX_VALUE;
|
|
|
|
/* Used by the pseudo random number generator. */
|
|
static size_t uxNextRand = 0;
|
|
|
|
/* The task handles are stored so their priorities can be changed. */
|
|
TaskHandle_t xQueueSetSendingTask, xQueueSetReceivingTask;
|
|
|
|
/*-----------------------------------------------------------*/
|
|
|
|
void vStartQueueSetTasks(void)
|
|
{
|
|
/* Create the tasks. */
|
|
xTaskCreate(prvQueueSetSendingTask, "SetTx", configMINIMAL_STACK_SIZE,
|
|
NULL, queuesetMEDIUM_PRIORITY, &xQueueSetSendingTask);
|
|
|
|
if (xQueueSetSendingTask != NULL) {
|
|
xTaskCreate(prvQueueSetReceivingTask, "SetRx",
|
|
configMINIMAL_STACK_SIZE,
|
|
(void *)xQueueSetSendingTask,
|
|
queuesetMEDIUM_PRIORITY, &xQueueSetReceivingTask);
|
|
|
|
/* It is important that the sending task does not attempt to write to a
|
|
queue before the queue has been created. It is therefore placed into
|
|
the suspended state before the scheduler has started. It is resumed by
|
|
the receiving task after the receiving task has created the queues and
|
|
added the queues to the queue set. */
|
|
vTaskSuspend(xQueueSetSendingTask);
|
|
}
|
|
}
|
|
/*-----------------------------------------------------------*/
|
|
|
|
BaseType_t xAreQueueSetTasksStillRunning(void)
|
|
{
|
|
static uint32_t ulLastCycleCounter, ulLastISRTxValue = 0;
|
|
static uint32_t ulLastQueueUsedCounter[queuesetNUM_QUEUES_IN_SET] = {
|
|
0
|
|
};
|
|
BaseType_t xReturn = pdPASS, x;
|
|
|
|
if (ulLastCycleCounter == ulCycleCounter) {
|
|
/* The cycle counter is no longer being incremented. Either one of the
|
|
tasks is stalled or an error has been detected. */
|
|
xReturn = pdFAIL;
|
|
}
|
|
|
|
ulLastCycleCounter = ulCycleCounter;
|
|
|
|
/* Ensure that all the queues in the set have been used. This ensures the
|
|
test is working as intended and guards against the rand() in the Tx task
|
|
missing some values. */
|
|
for (x = 0; x < queuesetNUM_QUEUES_IN_SET; x++) {
|
|
if (ulLastQueueUsedCounter[x] == ulQueueUsedCounter[x]) {
|
|
xReturn = pdFAIL;
|
|
}
|
|
|
|
ulLastQueueUsedCounter[x] = ulQueueUsedCounter[x];
|
|
}
|
|
|
|
/* Check the global status flag. */
|
|
if (xQueueSetTasksStatus != pdPASS) {
|
|
xReturn = pdFAIL;
|
|
}
|
|
|
|
/* Check that the ISR is still sending values to the queues too. */
|
|
if (ulISRTxValue == ulLastISRTxValue) {
|
|
xReturn = pdFAIL;
|
|
} else {
|
|
ulLastISRTxValue = ulISRTxValue;
|
|
}
|
|
|
|
return xReturn;
|
|
}
|
|
/*-----------------------------------------------------------*/
|
|
|
|
static void prvQueueSetSendingTask(void *pvParameters)
|
|
{
|
|
uint32_t ulTaskTxValue = 0;
|
|
size_t uxQueueToWriteTo;
|
|
QueueHandle_t xQueueInUse;
|
|
|
|
/* Remove compiler warning about the unused parameter. */
|
|
(void)pvParameters;
|
|
|
|
/* Seed mini pseudo random number generator. */
|
|
prvSRand((size_t)&ulTaskTxValue);
|
|
|
|
for (;;) {
|
|
/* Generate the index for the queue to which a value is to be sent. */
|
|
uxQueueToWriteTo = prvRand() % queuesetNUM_QUEUES_IN_SET;
|
|
xQueueInUse = xQueues[uxQueueToWriteTo];
|
|
|
|
/* Note which index is being written to to ensure all the queues are
|
|
used. */
|
|
(ulQueueUsedCounter[uxQueueToWriteTo])++;
|
|
|
|
/* Send to the queue to unblock the task that is waiting for data to
|
|
arrive on a queue within the queue set to which this queue belongs. */
|
|
if (xQueueSendToBack(xQueueInUse, &ulTaskTxValue,
|
|
portMAX_DELAY) != pdPASS) {
|
|
/* The send should always pass as an infinite block time was
|
|
used. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
|
|
#if (configUSE_PREEMPTION == 0)
|
|
taskYIELD();
|
|
#endif
|
|
|
|
ulTaskTxValue++;
|
|
|
|
/* If the Tx value has reached the range used by the ISR then set it
|
|
back to 0. */
|
|
if (ulTaskTxValue == queuesetINITIAL_ISR_TX_VALUE) {
|
|
ulTaskTxValue = 0;
|
|
}
|
|
|
|
/* Increase test coverage by occasionally change the priorities of the
|
|
two tasks relative to each other. */
|
|
prvChangeRelativePriorities();
|
|
}
|
|
}
|
|
/*-----------------------------------------------------------*/
|
|
|
|
static void prvChangeRelativePriorities(void)
|
|
{
|
|
static UBaseType_t ulLoops = 0;
|
|
static eRelativePriorities ePriorities = eEqualPriority;
|
|
|
|
/* Occasionally change the task priority relative to the priority of
|
|
the receiving task. */
|
|
ulLoops++;
|
|
if (ulLoops >= queuesetPRIORITY_CHANGE_LOOPS) {
|
|
ulLoops = 0;
|
|
|
|
switch (ePriorities) {
|
|
case eEqualPriority:
|
|
/* Both tasks are running with medium priority. Now lower the
|
|
priority of the receiving task so the Tx task has the higher
|
|
relative priority. */
|
|
vTaskPrioritySet(xQueueSetReceivingTask,
|
|
queuesetLOW_PRIORITY);
|
|
ePriorities = eTxHigherPriority;
|
|
break;
|
|
|
|
case eTxHigherPriority:
|
|
/* The Tx task is running with a higher priority than the Rx
|
|
task. Switch the priorities around so the Rx task has the
|
|
higher relative priority. */
|
|
vTaskPrioritySet(xQueueSetReceivingTask,
|
|
queuesetMEDIUM_PRIORITY);
|
|
vTaskPrioritySet(xQueueSetSendingTask,
|
|
queuesetLOW_PRIORITY);
|
|
ePriorities = eTxLowerPriority;
|
|
break;
|
|
|
|
case eTxLowerPriority:
|
|
/* The Tx task is running with a lower priority than the Rx
|
|
task. Make the priorities equal again. */
|
|
vTaskPrioritySet(xQueueSetSendingTask,
|
|
queuesetMEDIUM_PRIORITY);
|
|
ePriorities = eEqualPriority;
|
|
|
|
/* When both tasks are using a non-idle priority the queue set
|
|
tasks will starve idle priority tasks of execution time - so
|
|
relax a bit before the next iteration to minimise the impact. */
|
|
vTaskDelay(queuesetTX_LOOP_DELAY);
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
/*-----------------------------------------------------------*/
|
|
|
|
static void prvQueueSetReceivingTask(void *pvParameters)
|
|
{
|
|
uint32_t ulReceived;
|
|
QueueHandle_t xActivatedQueue;
|
|
TickType_t xBlockTime;
|
|
|
|
/* Remove compiler warnings. */
|
|
(void)pvParameters;
|
|
|
|
/* Create the queues and add them to the queue set before resuming the Tx
|
|
task. */
|
|
prvSetupTest();
|
|
|
|
for (;;) {
|
|
/* For test coverage reasons, the block time is dependent on the
|
|
priority of this task - which changes during the test. When the task
|
|
is at the idle priority it polls the queue set. */
|
|
if (uxTaskPriorityGet(NULL) == tskIDLE_PRIORITY) {
|
|
xBlockTime = 0;
|
|
} else {
|
|
xBlockTime = portMAX_DELAY;
|
|
}
|
|
|
|
/* Wait for a message to arrive on one of the queues in the set. */
|
|
xActivatedQueue = xQueueSelectFromSet(xQueueSet, portMAX_DELAY);
|
|
|
|
if (xActivatedQueue == NULL) {
|
|
if (xBlockTime != 0) {
|
|
/* This should not happen as an infinite delay was used. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
} else {
|
|
/* Reading from the queue should pass with a zero block time as
|
|
this task will only run when something has been posted to a task
|
|
in the queue set. */
|
|
if (xQueueReceive(xActivatedQueue, &ulReceived,
|
|
queuesetDONT_BLOCK) != pdPASS) {
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
|
|
/* Ensure the value received was the value expected. This function
|
|
manipulates file scope data and is also called from an ISR, hence
|
|
the critical section. */
|
|
taskENTER_CRITICAL();
|
|
{
|
|
prvCheckReceivedValue(ulReceived);
|
|
}
|
|
taskEXIT_CRITICAL();
|
|
|
|
if (xQueueSetTasksStatus == pdPASS) {
|
|
ulCycleCounter++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/*-----------------------------------------------------------*/
|
|
|
|
void vQueueSetAccessQueueSetFromISR(void)
|
|
{
|
|
static uint32_t ulCallCount = 0;
|
|
|
|
/* xSetupComplete is set to pdTRUE when the queues have been created and
|
|
are available for use. */
|
|
if (xSetupComplete == pdTRUE) {
|
|
/* It is intended that this function is called from the tick hook
|
|
function, so each call is one tick period apart. */
|
|
ulCallCount++;
|
|
if (ulCallCount > queuesetISR_TX_PERIOD) {
|
|
ulCallCount = 0;
|
|
|
|
/* First attempt to read from the queue set. */
|
|
prvReceiveFromQueueInSetFromISR();
|
|
|
|
/* Then write to the queue set. */
|
|
prvSendToQueueInSetFromISR();
|
|
}
|
|
}
|
|
}
|
|
/*-----------------------------------------------------------*/
|
|
|
|
static void prvCheckReceivedValue(uint32_t ulReceived)
|
|
{
|
|
static uint32_t ulExpectedReceivedFromTask = 0,
|
|
ulExpectedReceivedFromISR =
|
|
queuesetINITIAL_ISR_TX_VALUE;
|
|
|
|
/* Values are received in tasks and interrupts. It is likely that the
|
|
receiving task will sometimes get preempted by the receiving interrupt
|
|
between reading a value from the queue and calling this function. When
|
|
that happens, if the receiving interrupt calls this function the values
|
|
will get passed into this function slightly out of order. For that
|
|
reason the value passed in is tested against a small range of expected
|
|
values, rather than a single absolute value. To make the range testing
|
|
easier values in the range limits are ignored. */
|
|
|
|
/* If the received value is equal to or greater than
|
|
queuesetINITIAL_ISR_TX_VALUE then it was sent by an ISR. */
|
|
if (ulReceived >= queuesetINITIAL_ISR_TX_VALUE) {
|
|
/* The value was sent from the ISR. */
|
|
if ((ulReceived - queuesetINITIAL_ISR_TX_VALUE) <
|
|
queuesetIGNORED_BOUNDARY) {
|
|
/* The value received is at the lower limit of the expected range.
|
|
Don't test it and expect to receive one higher next time. */
|
|
} else if ((ULONG_MAX - ulReceived) <=
|
|
queuesetIGNORED_BOUNDARY) {
|
|
/* The value received is at the higher limit of the expected range.
|
|
Don't test it and expect to wrap soon. */
|
|
} else {
|
|
/* Check the value against its expected value range. */
|
|
if (prvCheckReceivedValueWithinExpectedRange(
|
|
ulReceived, ulExpectedReceivedFromISR) !=
|
|
pdPASS) {
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
}
|
|
|
|
configASSERT(xQueueSetTasksStatus);
|
|
|
|
/* It is expected to receive an incrementing number. */
|
|
ulExpectedReceivedFromISR++;
|
|
if (ulExpectedReceivedFromISR == 0) {
|
|
ulExpectedReceivedFromISR =
|
|
queuesetINITIAL_ISR_TX_VALUE;
|
|
}
|
|
} else {
|
|
/* The value was sent from the Tx task. */
|
|
if (ulReceived < queuesetIGNORED_BOUNDARY) {
|
|
/* The value received is at the lower limit of the expected range.
|
|
Don't test it, and expect to receive one higher next time. */
|
|
} else if (((queuesetINITIAL_ISR_TX_VALUE - 1) - ulReceived) <=
|
|
queuesetIGNORED_BOUNDARY) {
|
|
/* The value received is at the higher limit of the expected range.
|
|
Don't test it and expect to wrap soon. */
|
|
} else {
|
|
/* Check the value against its expected value range. */
|
|
if (prvCheckReceivedValueWithinExpectedRange(
|
|
ulReceived, ulExpectedReceivedFromTask) !=
|
|
pdPASS) {
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
}
|
|
|
|
configASSERT(xQueueSetTasksStatus);
|
|
|
|
/* It is expected to receive an incrementing number. */
|
|
ulExpectedReceivedFromTask++;
|
|
if (ulExpectedReceivedFromTask >=
|
|
queuesetINITIAL_ISR_TX_VALUE) {
|
|
ulExpectedReceivedFromTask = 0;
|
|
}
|
|
}
|
|
}
|
|
/*-----------------------------------------------------------*/
|
|
|
|
static BaseType_t
|
|
prvCheckReceivedValueWithinExpectedRange(uint32_t ulReceived,
|
|
uint32_t ulExpectedReceived)
|
|
{
|
|
BaseType_t xReturn = pdPASS;
|
|
|
|
if (ulReceived > ulExpectedReceived) {
|
|
configASSERT((ulReceived - ulExpectedReceived) <=
|
|
queuesetALLOWABLE_RX_DEVIATION);
|
|
if ((ulReceived - ulExpectedReceived) >
|
|
queuesetALLOWABLE_RX_DEVIATION) {
|
|
xReturn = pdFALSE;
|
|
}
|
|
} else {
|
|
configASSERT((ulExpectedReceived - ulReceived) <=
|
|
queuesetALLOWABLE_RX_DEVIATION);
|
|
if ((ulExpectedReceived - ulReceived) >
|
|
queuesetALLOWABLE_RX_DEVIATION) {
|
|
xReturn = pdFALSE;
|
|
}
|
|
}
|
|
|
|
return xReturn;
|
|
}
|
|
/*-----------------------------------------------------------*/
|
|
|
|
static void prvReceiveFromQueueInSetFromISR(void)
|
|
{
|
|
QueueSetMemberHandle_t xActivatedQueue;
|
|
uint32_t ulReceived;
|
|
|
|
/* See if any of the queues in the set contain data. */
|
|
xActivatedQueue = xQueueSelectFromSetFromISR(xQueueSet);
|
|
|
|
if (xActivatedQueue != NULL) {
|
|
/* Reading from the queue for test purposes only. */
|
|
if (xQueueReceiveFromISR(xActivatedQueue, &ulReceived, NULL) !=
|
|
pdPASS) {
|
|
/* Data should have been available as the handle was returned from
|
|
xQueueSelectFromSetFromISR(). */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
|
|
/* Ensure the value received was the value expected. */
|
|
prvCheckReceivedValue(ulReceived);
|
|
}
|
|
}
|
|
/*-----------------------------------------------------------*/
|
|
|
|
static void prvSendToQueueInSetFromISR(void)
|
|
{
|
|
static BaseType_t xQueueToWriteTo = 0;
|
|
uint32_t ulTxValueSnapshot = ulISRTxValue;
|
|
|
|
if (xQueueSendFromISR(xQueues[xQueueToWriteTo],
|
|
(void *)&ulTxValueSnapshot, NULL) == pdPASS) {
|
|
ulISRTxValue++;
|
|
|
|
/* If the Tx value has wrapped then set it back to its initial value. */
|
|
if (ulISRTxValue == 0UL) {
|
|
ulISRTxValue = queuesetINITIAL_ISR_TX_VALUE;
|
|
}
|
|
|
|
/* Use a different queue next time. */
|
|
xQueueToWriteTo++;
|
|
if (xQueueToWriteTo >= queuesetNUM_QUEUES_IN_SET) {
|
|
xQueueToWriteTo = 0;
|
|
}
|
|
}
|
|
}
|
|
/*-----------------------------------------------------------*/
|
|
|
|
static void prvTestQueueOverwriteWithQueueSet(void)
|
|
{
|
|
uint32_t ulValueToSend = 0, ulValueReceived = 0;
|
|
QueueHandle_t xQueueHandle = NULL, xReceivedHandle = NULL;
|
|
const UBaseType_t xLengthOfOne = (UBaseType_t)1;
|
|
|
|
/* Create a queue that has a length of one - a requirement in order to call
|
|
xQueueOverwrite. This will get deleted again when this test completes. */
|
|
xQueueHandle = xQueueCreate(xLengthOfOne, sizeof(uint32_t));
|
|
configASSERT(xQueueHandle);
|
|
|
|
if (xQueueHandle != NULL) {
|
|
xQueueAddToSet(xQueueHandle, xQueueSet);
|
|
|
|
/* Add an item to the queue then ensure the queue set correctly
|
|
indicates that one item is available, and that item is indeed the
|
|
queue written to. */
|
|
xQueueOverwrite(xQueueHandle, (void *)&ulValueToSend);
|
|
if (uxQueueMessagesWaiting(xQueueSet) != (UBaseType_t)1) {
|
|
/* Expected one item in the queue set. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
xQueuePeek(xQueueSet, &xReceivedHandle, queuesetDONT_BLOCK);
|
|
if (xReceivedHandle != xQueueHandle) {
|
|
/* Wrote to xQueueHandle so expected xQueueHandle to be the handle
|
|
held in the queue set. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
|
|
/* Now overwrite the value in the queue and ensure the queue set state
|
|
doesn't change as the number of items in the queues within the set have
|
|
not changed. */
|
|
ulValueToSend++;
|
|
xQueueOverwrite(xQueueHandle, (void *)&ulValueToSend);
|
|
if (uxQueueMessagesWaiting(xQueueSet) != (UBaseType_t)1) {
|
|
/* Still expected one item in the queue set. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
xReceivedHandle =
|
|
xQueueSelectFromSet(xQueueSet, queuesetDONT_BLOCK);
|
|
if (xReceivedHandle != xQueueHandle) {
|
|
/* Wrote to xQueueHandle so expected xQueueHandle to be the handle
|
|
held in the queue set. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
|
|
/* Also ensure the value received from the queue is the overwritten
|
|
value, not the value originally written. */
|
|
xQueueReceive(xQueueHandle, &ulValueReceived,
|
|
queuesetDONT_BLOCK);
|
|
if (ulValueReceived != ulValueToSend) {
|
|
/* Unexpected value received from the queue. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
|
|
/* Should be anything in the queue set now. */
|
|
if (uxQueueMessagesWaiting(xQueueSet) != (UBaseType_t)0) {
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
xReceivedHandle =
|
|
xQueueSelectFromSet(xQueueSet, queuesetDONT_BLOCK);
|
|
if (xReceivedHandle != NULL) {
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
|
|
/* Clean up. */
|
|
xQueueRemoveFromSet(xQueueHandle, xQueueSet);
|
|
vQueueDelete(xQueueHandle);
|
|
}
|
|
}
|
|
/*-----------------------------------------------------------*/
|
|
|
|
static void prvTestQueueOverwriteOnTwoQueusInQueueSet(void)
|
|
{
|
|
uint32_t ulValueToSend1 = 1, ulValueToSend2 = 2UL, ulValueReceived = 0;
|
|
QueueHandle_t xQueueHandle1 = NULL, xQueueHandle2 = NULL,
|
|
xReceivedHandle = NULL;
|
|
const UBaseType_t xLengthOfOne = (UBaseType_t)1;
|
|
|
|
/* Create two queues that have a length of one - a requirement in order to call
|
|
xQueueOverwrite. These will get deleted again when this test completes. */
|
|
xQueueHandle1 = xQueueCreate(xLengthOfOne, sizeof(uint32_t));
|
|
configASSERT(xQueueHandle1);
|
|
xQueueHandle2 = xQueueCreate(xLengthOfOne, sizeof(uint32_t));
|
|
configASSERT(xQueueHandle2);
|
|
|
|
if ((xQueueHandle1 != NULL) && (xQueueHandle2 != NULL)) {
|
|
/* Add both queues to the queue set. */
|
|
xQueueAddToSet(xQueueHandle1, xQueueSet);
|
|
xQueueAddToSet(xQueueHandle2, xQueueSet);
|
|
|
|
/* Add an item using the first queue. */
|
|
xQueueOverwrite(xQueueHandle1, (void *)&ulValueToSend1);
|
|
if (uxQueueMessagesWaiting(xQueueSet) != (UBaseType_t)1) {
|
|
/* Expected one item in the queue set. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
|
|
xQueuePeek(xQueueSet, &xReceivedHandle, queuesetDONT_BLOCK);
|
|
if (xReceivedHandle != xQueueHandle1) {
|
|
/* Wrote to xQueueHandle so expected xQueueHandle to be the handle
|
|
held in the queue set. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
|
|
/* Next add an item to the second queue. */
|
|
xQueueOverwrite(xQueueHandle2, (void *)&ulValueToSend2);
|
|
if (uxQueueMessagesWaiting(xQueueSet) != (UBaseType_t)2) {
|
|
/* Expected two items in the queue set. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
|
|
/* The head of the queue set should not have changed though. */
|
|
xQueuePeek(xQueueSet, &xReceivedHandle, queuesetDONT_BLOCK);
|
|
if (xReceivedHandle != xQueueHandle1) {
|
|
/* Wrote to xQueueHandle so expected xQueueHandle to be the handle
|
|
held in the queue set. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
|
|
/* Now overwrite the value in the queue and ensure the queue set state
|
|
doesn't change as the number of items in the queues within the set have
|
|
not changed. NOTE: after this queue 1 should hold ulValueToSend2 and queue
|
|
2 should hold the value ulValueToSend1. */
|
|
xQueueOverwrite(xQueueHandle1, (void *)&ulValueToSend2);
|
|
if (uxQueueMessagesWaiting(xQueueSet) != (UBaseType_t)2) {
|
|
/* Still expected two items in the queue set. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
xQueueOverwrite(xQueueHandle2, (void *)&ulValueToSend1);
|
|
if (uxQueueMessagesWaiting(xQueueSet) != (UBaseType_t)2) {
|
|
/* Still expected two items in the queue set. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
|
|
/* Repeat the above to ensure the queue set state doesn't change. */
|
|
xQueueOverwrite(xQueueHandle1, (void *)&ulValueToSend2);
|
|
if (uxQueueMessagesWaiting(xQueueSet) != (UBaseType_t)2) {
|
|
/* Still expected two items in the queue set. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
xQueueOverwrite(xQueueHandle2, (void *)&ulValueToSend1);
|
|
if (uxQueueMessagesWaiting(xQueueSet) != (UBaseType_t)2) {
|
|
/* Still expected two items in the queue set. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
|
|
/* Now when reading from the queue set we expect the handle to the first
|
|
queue to be received first, and for that queue to hold ulValueToSend2 as the
|
|
originally written value was overwritten. Likewise the second handle received
|
|
from the set should be that of the second queue, and that queue should hold
|
|
ulValueToSend1 as the originally written value was overwritten. */
|
|
xReceivedHandle =
|
|
xQueueSelectFromSet(xQueueSet, queuesetDONT_BLOCK);
|
|
if (xReceivedHandle != xQueueHandle1) {
|
|
/* Wrote to xQueueHandle1 first so expected that handle to be read from
|
|
the set first. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
if (uxQueueMessagesWaiting(xQueueSet) != (UBaseType_t)1) {
|
|
/* One value was read from the set, so now only expect a single value
|
|
in the set. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
xQueueReceive(xReceivedHandle, &ulValueReceived,
|
|
queuesetDONT_BLOCK);
|
|
if (ulValueReceived != ulValueToSend2) {
|
|
/* Unexpected value received from the queue. ulValueToSend1 was written
|
|
first, but then overwritten with ulValueToSend2; */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
|
|
xReceivedHandle =
|
|
xQueueSelectFromSet(xQueueSet, queuesetDONT_BLOCK);
|
|
if (xReceivedHandle != xQueueHandle2) {
|
|
/* xQueueHandle1 has already been removed from the set so expect only
|
|
xQueueHandle2 to be left. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
if (uxQueueMessagesWaiting(xQueueSet) != (UBaseType_t)0) {
|
|
/* The last value was read from the set so don't expect any more. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
xQueueReceive(xReceivedHandle, &ulValueReceived,
|
|
queuesetDONT_BLOCK);
|
|
if (ulValueReceived != ulValueToSend1) {
|
|
/* Unexpected value received from the queue. ulValueToSend2 was written
|
|
first, but then overwritten with ulValueToSend1. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
|
|
/* Should be anything in the queue set now. */
|
|
xReceivedHandle =
|
|
xQueueSelectFromSet(xQueueSet, queuesetDONT_BLOCK);
|
|
if (xReceivedHandle != NULL) {
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
|
|
/* Clean up. */
|
|
xQueueRemoveFromSet(xQueueHandle1, xQueueSet);
|
|
xQueueRemoveFromSet(xQueueHandle2, xQueueSet);
|
|
vQueueDelete(xQueueHandle1);
|
|
vQueueDelete(xQueueHandle2);
|
|
}
|
|
}
|
|
/*-----------------------------------------------------------*/
|
|
|
|
static void prvTestQueueOverwriteFromISROnTwoQueusInQueueSet(void)
|
|
{
|
|
uint32_t ulValueToSend1 = 1, ulValueToSend2 = 2UL, ulValueReceived = 0;
|
|
QueueHandle_t xQueueHandle1 = NULL, xQueueHandle2 = NULL,
|
|
xReceivedHandle = NULL;
|
|
const UBaseType_t xLengthOfOne = (UBaseType_t)1;
|
|
|
|
/* Create two queues that have a length of one - a requirement in order to call
|
|
xQueueOverwrite. These will get deleted again when this test completes. */
|
|
xQueueHandle1 = xQueueCreate(xLengthOfOne, sizeof(uint32_t));
|
|
configASSERT(xQueueHandle1);
|
|
xQueueHandle2 = xQueueCreate(xLengthOfOne, sizeof(uint32_t));
|
|
configASSERT(xQueueHandle2);
|
|
|
|
if ((xQueueHandle1 != NULL) && (xQueueHandle2 != NULL)) {
|
|
/* Add both queues to the queue set. */
|
|
xQueueAddToSet(xQueueHandle1, xQueueSet);
|
|
xQueueAddToSet(xQueueHandle2, xQueueSet);
|
|
|
|
/* Add an item using the first queue using the 'FromISR' version of the
|
|
overwrite function. */
|
|
xQueueOverwriteFromISR(xQueueHandle1, (void *)&ulValueToSend1,
|
|
NULL);
|
|
if (uxQueueMessagesWaiting(xQueueSet) != (UBaseType_t)1) {
|
|
/* Expected one item in the queue set. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
|
|
xQueuePeek(xQueueSet, &xReceivedHandle, queuesetDONT_BLOCK);
|
|
if (xReceivedHandle != xQueueHandle1) {
|
|
/* Wrote to xQueueHandle so expected xQueueHandle to be the handle
|
|
held in the queue set. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
|
|
/* Next add an item to the second queue using the 'FromISR' version of the
|
|
overwrite function. */
|
|
xQueueOverwriteFromISR(xQueueHandle2, (void *)&ulValueToSend2,
|
|
NULL);
|
|
if (uxQueueMessagesWaiting(xQueueSet) != (UBaseType_t)2) {
|
|
/* Expected two items in the queue set. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
|
|
/* The head of the queue set should not have changed though. */
|
|
xQueuePeek(xQueueSet, &xReceivedHandle, queuesetDONT_BLOCK);
|
|
if (xReceivedHandle != xQueueHandle1) {
|
|
/* Wrote to xQueueHandle so expected xQueueHandle to be the handle
|
|
held in the queue set. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
|
|
/* Now overwrite the value in the queue and ensure the queue set state
|
|
doesn't change as the number of items in the queues within the set have
|
|
not changed. NOTE: after this queue 1 should hold ulValueToSend2 and queue
|
|
2 should hold the value ulValueToSend1. */
|
|
xQueueOverwriteFromISR(xQueueHandle1, (void *)&ulValueToSend2,
|
|
NULL);
|
|
if (uxQueueMessagesWaiting(xQueueSet) != (UBaseType_t)2) {
|
|
/* Still expected two items in the queue set. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
xQueueOverwriteFromISR(xQueueHandle2, (void *)&ulValueToSend1,
|
|
NULL);
|
|
if (uxQueueMessagesWaiting(xQueueSet) != (UBaseType_t)2) {
|
|
/* Still expected two items in the queue set. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
|
|
/* Repeat the above to ensure the queue set state doesn't change. */
|
|
xQueueOverwriteFromISR(xQueueHandle1, (void *)&ulValueToSend2,
|
|
NULL);
|
|
if (uxQueueMessagesWaiting(xQueueSet) != (UBaseType_t)2) {
|
|
/* Still expected two items in the queue set. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
xQueueOverwriteFromISR(xQueueHandle2, (void *)&ulValueToSend1,
|
|
NULL);
|
|
if (uxQueueMessagesWaiting(xQueueSet) != (UBaseType_t)2) {
|
|
/* Still expected two items in the queue set. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
|
|
/* Now when reading from the queue set we expect the handle to the first
|
|
queue to be received first, and for that queue to hold ulValueToSend2 as the
|
|
originally written value was overwritten. Likewise the second handle received
|
|
from the set should be that of the second queue, and that queue should hold
|
|
ulValueToSend1 as the originally written value was overwritten. */
|
|
xReceivedHandle =
|
|
xQueueSelectFromSet(xQueueSet, queuesetDONT_BLOCK);
|
|
if (xReceivedHandle != xQueueHandle1) {
|
|
/* Wrote to xQueueHandle1 first so expected that handle to be read from
|
|
the set first. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
if (uxQueueMessagesWaiting(xQueueSet) != (UBaseType_t)1) {
|
|
/* One value was read from the set, so now only expect a single value
|
|
in the set. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
xQueueReceive(xReceivedHandle, &ulValueReceived,
|
|
queuesetDONT_BLOCK);
|
|
if (ulValueReceived != ulValueToSend2) {
|
|
/* Unexpected value received from the queue. ulValueToSend1 was written
|
|
first, but then overwritten with ulValueToSend2; */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
|
|
xReceivedHandle =
|
|
xQueueSelectFromSet(xQueueSet, queuesetDONT_BLOCK);
|
|
if (xReceivedHandle != xQueueHandle2) {
|
|
/* xQueueHandle1 has already been removed from the set so expect only
|
|
xQueueHandle2 to be left. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
if (uxQueueMessagesWaiting(xQueueSet) != (UBaseType_t)0) {
|
|
/* The last value was read from the set so don't expect any more. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
xQueueReceive(xReceivedHandle, &ulValueReceived,
|
|
queuesetDONT_BLOCK);
|
|
if (ulValueReceived != ulValueToSend1) {
|
|
/* Unexpected value received from the queue. ulValueToSend2 was written
|
|
first, but then overwritten with ulValueToSend1. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
|
|
/* Should be anything in the queue set now. */
|
|
xReceivedHandle =
|
|
xQueueSelectFromSet(xQueueSet, queuesetDONT_BLOCK);
|
|
if (xReceivedHandle != NULL) {
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
|
|
/* Clean up. */
|
|
xQueueRemoveFromSet(xQueueHandle1, xQueueSet);
|
|
xQueueRemoveFromSet(xQueueHandle2, xQueueSet);
|
|
vQueueDelete(xQueueHandle1);
|
|
vQueueDelete(xQueueHandle2);
|
|
}
|
|
}
|
|
/*-----------------------------------------------------------*/
|
|
|
|
static void prvSetupTest(void)
|
|
{
|
|
BaseType_t x;
|
|
uint32_t ulValueToSend = 0;
|
|
|
|
/* Ensure the queues are created and the queue set configured before the
|
|
sending task is unsuspended.
|
|
|
|
First Create the queue set such that it will be able to hold a message for
|
|
every space in every queue in the set. */
|
|
xQueueSet = xQueueCreateSet(queuesetNUM_QUEUES_IN_SET *
|
|
queuesetQUEUE_LENGTH);
|
|
|
|
for (x = 0; x < queuesetNUM_QUEUES_IN_SET; x++) {
|
|
/* Create the queue and add it to the set. The queue is just holding
|
|
uint32_t value. */
|
|
xQueues[x] =
|
|
xQueueCreate(queuesetQUEUE_LENGTH, sizeof(uint32_t));
|
|
configASSERT(xQueues[x]);
|
|
if (xQueueAddToSet(xQueues[x], xQueueSet) != pdPASS) {
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
} else {
|
|
/* The queue has now been added to the queue set and cannot be added to
|
|
another. */
|
|
if (xQueueAddToSet(xQueues[x], xQueueSet) != pdFAIL) {
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Attempt to remove a queue from a queue set it does not belong
|
|
to (NULL being passed as the queue set in this case). */
|
|
if (xQueueRemoveFromSet(xQueues[0], NULL) != pdFAIL) {
|
|
/* It is not possible to successfully remove a queue from a queue
|
|
set it does not belong to. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
|
|
/* Attempt to remove a queue from the queue set it does belong to. */
|
|
if (xQueueRemoveFromSet(xQueues[0], xQueueSet) != pdPASS) {
|
|
/* It should be possible to remove the queue from the queue set it
|
|
does belong to. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
|
|
/* Add an item to the queue before attempting to add it back into the
|
|
set. */
|
|
xQueueSend(xQueues[0], (void *)&ulValueToSend, 0);
|
|
if (xQueueAddToSet(xQueues[0], xQueueSet) != pdFAIL) {
|
|
/* Should not be able to add a non-empty queue to a set. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
|
|
/* Remove the item from the queue before adding the queue back into the
|
|
set so the dynamic tests can begin. */
|
|
xQueueReceive(xQueues[0], &ulValueToSend, 0);
|
|
if (xQueueAddToSet(xQueues[0], xQueueSet) != pdPASS) {
|
|
/* If the queue was successfully removed from the queue set then it
|
|
should be possible to add it back in again. */
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
|
|
/* The task that sends to the queues is not running yet, so attempting to
|
|
read from the queue set should fail. */
|
|
if (xQueueSelectFromSet(xQueueSet, queuesetSHORT_DELAY) != NULL) {
|
|
xQueueSetTasksStatus = pdFAIL;
|
|
}
|
|
|
|
/* Testing the behaviour of queue sets when a queue overwrite operation is
|
|
performed on a set member requires a special test as overwrites can only
|
|
be performed on queues that have a length of 1. */
|
|
prvTestQueueOverwriteWithQueueSet();
|
|
|
|
/* Test the case where two queues within a set are written to with
|
|
xQueueOverwrite(). */
|
|
prvTestQueueOverwriteOnTwoQueusInQueueSet();
|
|
prvTestQueueOverwriteFromISROnTwoQueusInQueueSet();
|
|
|
|
/* In case any of the above have already indicated a failure. */
|
|
configASSERT(xQueueSetTasksStatus != pdFAIL);
|
|
|
|
/* Resume the task that writes to the queues. */
|
|
vTaskResume(xQueueSetSendingTask);
|
|
|
|
/* Let the ISR access the queues also. */
|
|
xSetupComplete = pdTRUE;
|
|
}
|
|
/*-----------------------------------------------------------*/
|
|
|
|
static size_t prvRand(void)
|
|
{
|
|
uxNextRand = (uxNextRand * (size_t)1103515245) + (size_t)12345;
|
|
return (uxNextRand / (size_t)65536) % (size_t)32768;
|
|
}
|
|
/*-----------------------------------------------------------*/
|
|
|
|
static void prvSRand(size_t uxSeed)
|
|
{
|
|
uxNextRand = uxSeed;
|
|
}
|
|
|
|
#endif /* ( configUSE_QUEUE_SETS == 1 ) */
|