[freertos] add freertos firmware
Change-Id: I4158d66d9b5fc444e28287f55e79ac24e0a1666f
This commit is contained in:
301
freertos/cvitek/task/demo/Common/Minimal/comtest_strings.c
Normal file
301
freertos/cvitek/task/demo/Common/Minimal/comtest_strings.c
Normal file
@ -0,0 +1,301 @@
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/*
|
||||
* Creates a task and a timer that operate on an interrupt driven serial port.
|
||||
* This demo assumes that the characters transmitted on a port will also be
|
||||
* received on the same port. Therefore, the UART must either be connected to
|
||||
* an echo server, or the uart connector must have a loopback connector fitted.
|
||||
* See http://www.serialporttool.com/CommEcho.htm for a suitable echo server
|
||||
* for Windows hosts.
|
||||
*
|
||||
* The timer sends a string to the UART, toggles an LED, then resets itself by
|
||||
* changing its own period. The period is calculated as a pseudo random number
|
||||
* between comTX_MAX_BLOCK_TIME and comTX_MIN_BLOCK_TIME.
|
||||
*
|
||||
* The task blocks on an Rx queue waiting for a character to become available.
|
||||
* Received characters are checked to ensure they match those transmitted by the
|
||||
* Tx timer. An error is latched if characters are missing, incorrect, or
|
||||
* arrive too slowly.
|
||||
*
|
||||
* How characters are actually transmitted and received is port specific. Demos
|
||||
* that include this test/demo file will provide example drivers. The Tx timer
|
||||
* executes in the context of the timer service (daemon) task, and must
|
||||
* therefore never attempt to block.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Scheduler include files. */
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "timers.h"
|
||||
|
||||
#ifndef configUSE_TIMERS
|
||||
#error This demo uses timers. configUSE_TIMERS must be set to 1 in FreeRTOSConfig.h.
|
||||
#endif
|
||||
|
||||
#if configUSE_TIMERS != 1
|
||||
#error This demo uses timers. configUSE_TIMERS must be set to 1 in FreeRTOSConfig.h.
|
||||
#endif
|
||||
|
||||
/* Demo program include files. */
|
||||
#include "serial.h"
|
||||
#include "comtest_strings.h"
|
||||
#include "partest.h"
|
||||
|
||||
/* The size of the stack given to the Rx task. */
|
||||
#define comSTACK_SIZE configMINIMAL_STACK_SIZE
|
||||
|
||||
/* See the comment above the declaraction of the uxBaseLED variable. */
|
||||
#define comTX_LED_OFFSET (0)
|
||||
#define comRX_LED_OFFSET (1)
|
||||
|
||||
/* The Tx timer transmits the sequence of characters at a pseudo random
|
||||
interval that is capped between comTX_MAX_BLOCK_TIME and
|
||||
comTX_MIN_BLOCK_TIME. */
|
||||
#define comTX_MAX_BLOCK_TIME ((TickType_t)0x96)
|
||||
#define comTX_MIN_BLOCK_TIME ((TickType_t)0x32)
|
||||
#define comOFFSET_TIME ((TickType_t)3)
|
||||
|
||||
/* States for the simple state machine implemented in the Rx task. */
|
||||
#define comtstWAITING_START_OF_STRING 0
|
||||
#define comtstWAITING_END_OF_STRING 1
|
||||
|
||||
/* A short delay in ticks - this delay is used to allow the Rx queue to fill up
|
||||
a bit so more than one character can be processed at a time. This is relative
|
||||
to comTX_MIN_BLOCK_TIME to ensure it is never longer than the shortest gap
|
||||
between transmissions. It could be worked out more scientifically from the
|
||||
baud rate being used. */
|
||||
#define comSHORT_DELAY (comTX_MIN_BLOCK_TIME >> (TickType_t)2)
|
||||
|
||||
/* The string that is transmitted and received. */
|
||||
#define comTRANSACTED_STRING \
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
|
||||
|
||||
/* A block time of 0 simply means "don't block". */
|
||||
#define comtstDONT_BLOCK (TickType_t)0
|
||||
|
||||
/* Handle to the com port used by both tasks. */
|
||||
static xComPortHandle xPort = NULL;
|
||||
|
||||
/* The callback function allocated to the transmit timer, as described in the
|
||||
comments at the top of this file. */
|
||||
static void prvComTxTimerCallback(TimerHandle_t xTimer);
|
||||
|
||||
/* The receive task as described in the comments at the top of this file. */
|
||||
static void vComRxTask(void *pvParameters);
|
||||
|
||||
/* The Rx task will toggle LED ( uxBaseLED + comRX_LED_OFFSET). The Tx task
|
||||
will toggle LED ( uxBaseLED + comTX_LED_OFFSET ). */
|
||||
static UBaseType_t uxBaseLED = 0;
|
||||
|
||||
/* The Rx task toggles uxRxLoops on each successful iteration of its defined
|
||||
function - provided no errors have ever been latched. If this variable stops
|
||||
incrementing, then an error has occurred. */
|
||||
static volatile UBaseType_t uxRxLoops = 0UL;
|
||||
|
||||
/* The timer used to periodically transmit the string. This is the timer that
|
||||
has prvComTxTimerCallback allocated to it as its callback function. */
|
||||
static TimerHandle_t xTxTimer = NULL;
|
||||
|
||||
/* The string length is held at file scope so the Tx timer does not need to
|
||||
calculate it each time it executes. */
|
||||
static size_t xStringLength = 0U;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vStartComTestStringsTasks(UBaseType_t uxPriority, uint32_t ulBaudRate,
|
||||
UBaseType_t uxLED)
|
||||
{
|
||||
/* Store values that are used at run time. */
|
||||
uxBaseLED = uxLED;
|
||||
|
||||
/* Calculate the string length here, rather than each time the Tx timer
|
||||
executes. */
|
||||
xStringLength = strlen(comTRANSACTED_STRING);
|
||||
|
||||
/* Include the null terminator in the string length as this is used to
|
||||
detect the end of the string in the Rx task. */
|
||||
xStringLength++;
|
||||
|
||||
/* Initialise the com port, then spawn the Rx task and create the Tx
|
||||
timer. */
|
||||
xSerialPortInitMinimal(ulBaudRate, (xStringLength * 2U));
|
||||
|
||||
/* Create the Rx task and the Tx timer. The timer is started from the
|
||||
Rx task. */
|
||||
xTaskCreate(vComRxTask, "COMRx", comSTACK_SIZE, NULL, uxPriority,
|
||||
(TaskHandle_t *)NULL);
|
||||
xTxTimer = xTimerCreate("TxTimer", comTX_MIN_BLOCK_TIME, pdFALSE, NULL,
|
||||
prvComTxTimerCallback);
|
||||
configASSERT(xTxTimer);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvComTxTimerCallback(TimerHandle_t xTimer)
|
||||
{
|
||||
TickType_t xTimeToWait;
|
||||
|
||||
/* The parameter is not used in this case. */
|
||||
(void)xTimer;
|
||||
|
||||
/* Send the string. How this is actually performed depends on the
|
||||
sample driver provided with this demo. However - as this is a timer,
|
||||
it executes in the context of the timer task and therefore must not
|
||||
block. */
|
||||
vSerialPutString(xPort, comTRANSACTED_STRING, xStringLength);
|
||||
|
||||
/* Toggle an LED to give a visible indication that another transmission
|
||||
has been performed. */
|
||||
vParTestToggleLED(uxBaseLED + comTX_LED_OFFSET);
|
||||
|
||||
/* Wait a pseudo random time before sending the string again. */
|
||||
xTimeToWait = xTaskGetTickCount() + comOFFSET_TIME;
|
||||
|
||||
/* Ensure the time to wait is not greater than comTX_MAX_BLOCK_TIME. */
|
||||
xTimeToWait %= comTX_MAX_BLOCK_TIME;
|
||||
|
||||
/* Ensure the time to wait is not less than comTX_MIN_BLOCK_TIME. */
|
||||
if (xTimeToWait < comTX_MIN_BLOCK_TIME) {
|
||||
xTimeToWait = comTX_MIN_BLOCK_TIME;
|
||||
}
|
||||
|
||||
/* Reset the timer to run again xTimeToWait ticks from now. This function
|
||||
is called from the context of the timer task, so the block time must not
|
||||
be anything other than zero. */
|
||||
xTimerChangePeriod(xTxTimer, xTimeToWait, comtstDONT_BLOCK);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void vComRxTask(void *pvParameters)
|
||||
{
|
||||
BaseType_t xState = comtstWAITING_START_OF_STRING,
|
||||
xErrorOccurred = pdFALSE;
|
||||
char *pcExpectedByte, cRxedChar;
|
||||
const xComPortHandle xPort = NULL;
|
||||
|
||||
/* The parameter is not used in this example. */
|
||||
(void)pvParameters;
|
||||
|
||||
/* Start the Tx timer. This only needs to be started once, as it will
|
||||
reset itself thereafter. */
|
||||
xTimerStart(xTxTimer, portMAX_DELAY);
|
||||
|
||||
/* The first expected Rx character is the first in the string that is
|
||||
transmitted. */
|
||||
pcExpectedByte = comTRANSACTED_STRING;
|
||||
|
||||
for (;;) {
|
||||
/* Wait for the next character. */
|
||||
if (xSerialGetChar(xPort, &cRxedChar,
|
||||
(comTX_MAX_BLOCK_TIME * 2)) == pdFALSE) {
|
||||
/* A character definitely should have been received by now. As a
|
||||
character was not received an error must have occurred (which might
|
||||
just be that the loopback connector is not fitted). */
|
||||
xErrorOccurred = pdTRUE;
|
||||
}
|
||||
|
||||
switch (xState) {
|
||||
case comtstWAITING_START_OF_STRING:
|
||||
if (cRxedChar == *pcExpectedByte) {
|
||||
/* The received character was the first character of the
|
||||
string. Move to the next state to check each character
|
||||
as it comes in until the entire string has been received. */
|
||||
xState = comtstWAITING_END_OF_STRING;
|
||||
pcExpectedByte++;
|
||||
|
||||
/* Block for a short period. This just allows the Rx queue
|
||||
to contain more than one character, and therefore prevent
|
||||
thrashing reads to the queue, and repetitive context
|
||||
switches as each character is received. */
|
||||
vTaskDelay(comSHORT_DELAY);
|
||||
}
|
||||
break;
|
||||
|
||||
case comtstWAITING_END_OF_STRING:
|
||||
if (cRxedChar == *pcExpectedByte) {
|
||||
/* The received character was the expected character. Was
|
||||
it the last character in the string - i.e. the null
|
||||
terminator? */
|
||||
if (cRxedChar == 0x00) {
|
||||
/* The entire string has been received. If no errors
|
||||
have been latched, then increment the loop counter to
|
||||
show this task is still healthy. */
|
||||
if (xErrorOccurred == pdFALSE) {
|
||||
uxRxLoops++;
|
||||
|
||||
/* Toggle an LED to give a visible sign that a
|
||||
complete string has been received. */
|
||||
vParTestToggleLED(
|
||||
uxBaseLED +
|
||||
comRX_LED_OFFSET);
|
||||
}
|
||||
|
||||
/* Go back to wait for the start of the next string. */
|
||||
pcExpectedByte = comTRANSACTED_STRING;
|
||||
xState = comtstWAITING_START_OF_STRING;
|
||||
} else {
|
||||
/* Wait for the next character in the string. */
|
||||
pcExpectedByte++;
|
||||
}
|
||||
} else {
|
||||
/* The character received was not that expected. */
|
||||
xErrorOccurred = pdTRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Should not get here. Stop the Rx loop counter from
|
||||
incrementing to latch the error. */
|
||||
xErrorOccurred = pdTRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xAreComTestTasksStillRunning(void)
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
|
||||
/* If the count of successful reception loops has not changed than at
|
||||
some time an error occurred (i.e. a character was received out of sequence)
|
||||
and false is returned. */
|
||||
if (uxRxLoops == 0UL) {
|
||||
xReturn = pdFALSE;
|
||||
} else {
|
||||
xReturn = pdTRUE;
|
||||
}
|
||||
|
||||
/* Reset the count of successful Rx loops. When this function is called
|
||||
again it should have been incremented again. */
|
||||
uxRxLoops = 0UL;
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
Reference in New Issue
Block a user