Files
Linux_Drivers/freertos/cvitek/task/demo/Common/Minimal/QueueOverwrite.c
sam.xiang cbb030f19f [freertos] add freertos firmware
Change-Id: I4158d66d9b5fc444e28287f55e79ac24e0a1666f
2023-03-10 20:35:49 +08:00

216 lines
6.1 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!
*/
/*
* Basic task to demonstrate the xQueueOverwrite() function. See the comments
* in the function itself.
*/
/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
/* Demo program include files. */
#include "QueueOverwrite.h"
/* A block time of 0 just means "don't block". */
#define qoDONT_BLOCK 0
/* Number of times to overwrite the value in the queue. */
#define qoLOOPS 5
/* The task that uses the queue. */
static void prvQueueOverwriteTask(void *pvParameters);
/* Variable that is incremented on each loop of prvQueueOverwriteTask() provided
prvQueueOverwriteTask() has not found any errors. */
static uint32_t ulLoopCounter = 0;
/* Set to pdFALSE if an error is discovered by the
vQueueOverwritePeriodicISRDemo() function. */
static BaseType_t xISRTestStatus = pdPASS;
/* The queue that is accessed from the ISR. The queue accessed by the task is
created inside the task itself. */
static QueueHandle_t xISRQueue = NULL;
/*-----------------------------------------------------------*/
void vStartQueueOverwriteTask(UBaseType_t uxPriority)
{
const UBaseType_t uxQueueLength = 1;
/* Create the queue used by the ISR. xQueueOverwriteFromISR() should only
be used on queues that have a length of 1. */
xISRQueue = xQueueCreate(uxQueueLength, (UBaseType_t)sizeof(uint32_t));
/* Create the test task. The queue used by the test task is created inside
the task itself. */
xTaskCreate(prvQueueOverwriteTask, "QOver", configMINIMAL_STACK_SIZE,
NULL, uxPriority, (TaskHandle_t *)NULL);
}
/*-----------------------------------------------------------*/
static void prvQueueOverwriteTask(void *pvParameters)
{
QueueHandle_t xTaskQueue;
const UBaseType_t uxQueueLength = 1;
uint32_t ulValue, ulStatus = pdPASS, x;
/* The parameter is not used. */
(void)pvParameters;
/* Create the queue. xQueueOverwrite() should only be used on queues that
have a length of 1. */
xTaskQueue = xQueueCreate(uxQueueLength, (UBaseType_t)sizeof(uint32_t));
configASSERT(xTaskQueue);
for (;;) {
/* The queue is empty. Writing to the queue then reading from the queue
should return the item written. */
ulValue = 10;
xQueueOverwrite(xTaskQueue, &ulValue);
ulValue = 0;
xQueueReceive(xTaskQueue, &ulValue, qoDONT_BLOCK);
if (ulValue != 10) {
ulStatus = pdFAIL;
}
/* Now try writing to the queue several times. Each time the value
in the queue should get overwritten. */
for (x = 0; x < qoLOOPS; x++) {
/* Write to the queue. */
xQueueOverwrite(xTaskQueue, &x);
/* Check the value in the queue is that written, even though the
queue was not necessarily empty. */
xQueuePeek(xTaskQueue, &ulValue, qoDONT_BLOCK);
if (ulValue != x) {
ulStatus = pdFAIL;
}
/* There should always be one item in the queue. */
if (uxQueueMessagesWaiting(xTaskQueue) !=
uxQueueLength) {
ulStatus = pdFAIL;
}
}
/* Empty the queue again. */
xQueueReceive(xTaskQueue, &ulValue, qoDONT_BLOCK);
if (uxQueueMessagesWaiting(xTaskQueue) != 0) {
ulStatus = pdFAIL;
}
if (ulStatus != pdFAIL) {
/* Increment a counter to show this task is still running without
error. */
ulLoopCounter++;
}
#if (configUSE_PREEMPTION == 0)
taskYIELD();
#endif
}
}
/*-----------------------------------------------------------*/
BaseType_t xIsQueueOverwriteTaskStillRunning(void)
{
BaseType_t xReturn;
if (xISRTestStatus != pdPASS) {
xReturn = pdFAIL;
} else if (ulLoopCounter > 0) {
xReturn = pdPASS;
} else {
/* The task has either stalled of discovered an error. */
xReturn = pdFAIL;
}
ulLoopCounter = 0;
return xReturn;
}
/*-----------------------------------------------------------*/
void vQueueOverwritePeriodicISRDemo(void)
{
static uint32_t ulCallCount = 0;
const uint32_t ulTx1 = 10UL, ulTx2 = 20UL, ulNumberOfSwitchCases = 3UL;
uint32_t ulRx;
/* This function should be called from an interrupt, such as the tick hook
function vApplicationTickHook(). */
configASSERT(xISRQueue);
switch (ulCallCount) {
case 0:
/* The queue is empty. Write ulTx1 to the queue. In this demo the
last parameter is not used because there are no tasks blocked on
this queue. */
xQueueOverwriteFromISR(xISRQueue, &ulTx1, NULL);
/* Peek the queue to check it holds the expected value. */
xQueuePeekFromISR(xISRQueue, &ulRx);
if (ulRx != ulTx1) {
xISRTestStatus = pdFAIL;
}
break;
case 1:
/* The queue already holds ulTx1. Overwrite the value in the queue
with ulTx2. */
xQueueOverwriteFromISR(xISRQueue, &ulTx2, NULL);
break;
case 2:
/* Read from the queue to empty the queue again. The value read
should be ulTx2. */
xQueueReceiveFromISR(xISRQueue, &ulRx, NULL);
if (ulRx != ulTx2) {
xISRTestStatus = pdFAIL;
}
break;
}
/* Run the next case in the switch statement above next time this function
is called. */
ulCallCount++;
if (ulCallCount >= ulNumberOfSwitchCases) {
/* Go back to the start. */
ulCallCount = 0;
}
}