mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-20 05:21:59 -04:00
Fix buffer clean up in \FreeRTOS_Plus_TCP_Minimal_Windows_Simulator\demo_logging.c.
Update queue code to allow an overwrite operation on a queue that is in a queue set, and add prvTestQueueOverwriteWithQueueSet() to test function. Update Eclipse Win32 project to bring it closer the the Visual Studio equivalent.
This commit is contained in:
parent
ff74e7aa63
commit
9ed3a9fe18
|
@ -296,8 +296,8 @@ HANDLE xCurrentTask;
|
|||
if( xLength2 < 0 )
|
||||
{
|
||||
/* Clean up. */
|
||||
xLength2 = sizeof( cPrintString ) - 1 - xLength;
|
||||
cPrintString[ sizeof( cPrintString ) - 1 ] = '\0';
|
||||
xLength2 = dlMAX_PRINT_STRING_LENGTH - 1 - xLength;
|
||||
cPrintString[ dlMAX_PRINT_STRING_LENGTH - 1 ] = '\0';
|
||||
}
|
||||
|
||||
xLength += xLength2;
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
Changes since V2.0.0 release
|
||||
|
||||
+ Added FREERTOS_SO_WAKEUP_CALLBACK option so a callback can be executed
|
||||
when data arrives.
|
||||
+ Improve print output when using WinPCap to assist in selecting the
|
||||
correct network interface.
|
||||
+ Update FreeRTOS_gethostbyname() to allow an IP address to be passed in -
|
||||
in which case it is just returned as a uint32_t.
|
||||
+ Introduce ipconfigSOCKET_HAS_USER_WAKE_CALLBACK to FreeRTOS_Sockets.c to
|
||||
allow a user supposed callback function to be executed when socket events
|
||||
occur in the same way that the socket semaphore is currently used.
|
||||
+ Update xNetworkBuffersInitialise() to ensure the semaphore created by the
|
||||
function is not accessed until after the NULL check.
|
||||
+ Improve print messages output by the Win32 port layer version of
|
||||
prvPrintAvailableNetworkInterfaces().
|
||||
|
||||
Changes between 160908 and 160919 releases:
|
||||
|
||||
|
|
|
@ -138,9 +138,17 @@ static BaseType_t prvCheckReceivedValueWithinExpectedRange( uint32_t ulReceived,
|
|||
|
||||
/*
|
||||
* Increase test coverage by occasionally change the priorities of the two tasks
|
||||
* relative to each other. */
|
||||
* 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 );
|
||||
|
||||
/*
|
||||
* Local pseudo random number seed and return functions. Used to avoid calls
|
||||
* to the standard library.
|
||||
|
@ -599,6 +607,71 @@ uint32_t ulTxValueSnapshot = ulISRTxValue;
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
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 ) );
|
||||
|
||||
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 that item is indeed the
|
||||
queue written to. */
|
||||
xQueueSend( xQueueHandle, ( void * ) &ulValueToSend, 0 );
|
||||
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 recevied from the queue. */
|
||||
xQueueSetTasksStatus = pdFAIL;
|
||||
}
|
||||
|
||||
/* Clean up. */
|
||||
xQueueRemoveFromSet( xQueueHandle, xQueueSet );
|
||||
vQueueDelete( xQueueHandle );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvSetupTest( void )
|
||||
{
|
||||
BaseType_t x;
|
||||
|
@ -675,6 +748,11 @@ uint32_t ulValueToSend = 0;
|
|||
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();
|
||||
|
||||
/* Resume the task that writes to the queues. */
|
||||
vTaskResume( xQueueSetSendingTask );
|
||||
|
||||
|
|
|
@ -172,7 +172,7 @@ BaseType_t xNextByte = 0;
|
|||
continuing to look for the end of the string. */
|
||||
xNextByte++;
|
||||
|
||||
configASSERT( xNextByte < sizeof( cRxBuffer ) );
|
||||
configASSERT( ( size_t ) xNextByte < sizeof( cRxBuffer ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -193,7 +193,7 @@ static BaseType_t xCallCount = 0;
|
|||
|
||||
/* Send the next four bytes to the stream buffer. */
|
||||
xStreamBufferSendFromISR( xStreamBuffer,
|
||||
( void * ) ( pcStringToSend + xNextByteToSend ),
|
||||
( const void * ) ( pcStringToSend + xNextByteToSend ),
|
||||
xBytesToSend,
|
||||
NULL );
|
||||
|
||||
|
|
Binary file not shown.
|
@ -141,8 +141,8 @@ static void prvDemonstrateTaskStateAndHandleGetFunctions( void );
|
|||
static void prvDemonstratePendingFunctionCall( void );
|
||||
|
||||
/*
|
||||
* The function that is pended by prvDemonstratePendingFunctionCall().
|
||||
*/
|
||||
* The function that is pended by prvDemonstratePendingFunctionCall().
|
||||
*/
|
||||
static void prvPendedFunction( void *pvParameter1, uint32_t ulParameter2 );
|
||||
|
||||
/*
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
</matcher>
|
||||
</filter>
|
||||
<filter>
|
||||
<id>1507735156304</id>
|
||||
<id>1519407948166</id>
|
||||
<name>Standard_Demo_Tasks</name>
|
||||
<type>5</type>
|
||||
<matcher>
|
||||
|
@ -65,7 +65,7 @@
|
|||
</matcher>
|
||||
</filter>
|
||||
<filter>
|
||||
<id>1507735156307</id>
|
||||
<id>1519407948169</id>
|
||||
<name>Standard_Demo_Tasks</name>
|
||||
<type>5</type>
|
||||
<matcher>
|
||||
|
@ -74,7 +74,7 @@
|
|||
</matcher>
|
||||
</filter>
|
||||
<filter>
|
||||
<id>1507735156310</id>
|
||||
<id>1519407948172</id>
|
||||
<name>Standard_Demo_Tasks</name>
|
||||
<type>5</type>
|
||||
<matcher>
|
||||
|
@ -83,7 +83,7 @@
|
|||
</matcher>
|
||||
</filter>
|
||||
<filter>
|
||||
<id>1507735156313</id>
|
||||
<id>1519407948176</id>
|
||||
<name>Standard_Demo_Tasks</name>
|
||||
<type>5</type>
|
||||
<matcher>
|
||||
|
@ -92,7 +92,7 @@
|
|||
</matcher>
|
||||
</filter>
|
||||
<filter>
|
||||
<id>1507735156316</id>
|
||||
<id>1519407948179</id>
|
||||
<name>Standard_Demo_Tasks</name>
|
||||
<type>5</type>
|
||||
<matcher>
|
||||
|
@ -101,7 +101,7 @@
|
|||
</matcher>
|
||||
</filter>
|
||||
<filter>
|
||||
<id>1507735156319</id>
|
||||
<id>1519407948183</id>
|
||||
<name>Standard_Demo_Tasks</name>
|
||||
<type>5</type>
|
||||
<matcher>
|
||||
|
@ -110,7 +110,7 @@
|
|||
</matcher>
|
||||
</filter>
|
||||
<filter>
|
||||
<id>1507735156323</id>
|
||||
<id>1519407948186</id>
|
||||
<name>Standard_Demo_Tasks</name>
|
||||
<type>5</type>
|
||||
<matcher>
|
||||
|
@ -119,7 +119,7 @@
|
|||
</matcher>
|
||||
</filter>
|
||||
<filter>
|
||||
<id>1507735156327</id>
|
||||
<id>1519407948190</id>
|
||||
<name>Standard_Demo_Tasks</name>
|
||||
<type>5</type>
|
||||
<matcher>
|
||||
|
@ -128,7 +128,7 @@
|
|||
</matcher>
|
||||
</filter>
|
||||
<filter>
|
||||
<id>1507735156330</id>
|
||||
<id>1519407948195</id>
|
||||
<name>Standard_Demo_Tasks</name>
|
||||
<type>5</type>
|
||||
<matcher>
|
||||
|
@ -137,7 +137,7 @@
|
|||
</matcher>
|
||||
</filter>
|
||||
<filter>
|
||||
<id>1507735156333</id>
|
||||
<id>1519407948199</id>
|
||||
<name>Standard_Demo_Tasks</name>
|
||||
<type>5</type>
|
||||
<matcher>
|
||||
|
@ -146,7 +146,7 @@
|
|||
</matcher>
|
||||
</filter>
|
||||
<filter>
|
||||
<id>1507735156337</id>
|
||||
<id>1519407948202</id>
|
||||
<name>Standard_Demo_Tasks</name>
|
||||
<type>5</type>
|
||||
<matcher>
|
||||
|
@ -155,7 +155,7 @@
|
|||
</matcher>
|
||||
</filter>
|
||||
<filter>
|
||||
<id>1507735156340</id>
|
||||
<id>1519407948213</id>
|
||||
<name>Standard_Demo_Tasks</name>
|
||||
<type>5</type>
|
||||
<matcher>
|
||||
|
@ -164,7 +164,7 @@
|
|||
</matcher>
|
||||
</filter>
|
||||
<filter>
|
||||
<id>1507735156343</id>
|
||||
<id>1519407948216</id>
|
||||
<name>Standard_Demo_Tasks</name>
|
||||
<type>5</type>
|
||||
<matcher>
|
||||
|
@ -173,7 +173,7 @@
|
|||
</matcher>
|
||||
</filter>
|
||||
<filter>
|
||||
<id>1507735156347</id>
|
||||
<id>1519407948224</id>
|
||||
<name>Standard_Demo_Tasks</name>
|
||||
<type>5</type>
|
||||
<matcher>
|
||||
|
@ -182,7 +182,7 @@
|
|||
</matcher>
|
||||
</filter>
|
||||
<filter>
|
||||
<id>1507735156350</id>
|
||||
<id>1519407948228</id>
|
||||
<name>Standard_Demo_Tasks</name>
|
||||
<type>5</type>
|
||||
<matcher>
|
||||
|
@ -191,7 +191,7 @@
|
|||
</matcher>
|
||||
</filter>
|
||||
<filter>
|
||||
<id>1507735156353</id>
|
||||
<id>1519407948231</id>
|
||||
<name>Standard_Demo_Tasks</name>
|
||||
<type>5</type>
|
||||
<matcher>
|
||||
|
@ -200,7 +200,7 @@
|
|||
</matcher>
|
||||
</filter>
|
||||
<filter>
|
||||
<id>1507735156356</id>
|
||||
<id>1519407948235</id>
|
||||
<name>Standard_Demo_Tasks</name>
|
||||
<type>5</type>
|
||||
<matcher>
|
||||
|
@ -209,7 +209,7 @@
|
|||
</matcher>
|
||||
</filter>
|
||||
<filter>
|
||||
<id>1507735156359</id>
|
||||
<id>1519407948237</id>
|
||||
<name>Standard_Demo_Tasks</name>
|
||||
<type>5</type>
|
||||
<matcher>
|
||||
|
@ -218,7 +218,7 @@
|
|||
</matcher>
|
||||
</filter>
|
||||
<filter>
|
||||
<id>1507735156362</id>
|
||||
<id>1519407948240</id>
|
||||
<name>Standard_Demo_Tasks</name>
|
||||
<type>5</type>
|
||||
<matcher>
|
||||
|
@ -227,7 +227,7 @@
|
|||
</matcher>
|
||||
</filter>
|
||||
<filter>
|
||||
<id>1507735156366</id>
|
||||
<id>1519407948242</id>
|
||||
<name>Standard_Demo_Tasks</name>
|
||||
<type>5</type>
|
||||
<matcher>
|
||||
|
@ -236,7 +236,7 @@
|
|||
</matcher>
|
||||
</filter>
|
||||
<filter>
|
||||
<id>1507735156369</id>
|
||||
<id>1519407948269</id>
|
||||
<name>Standard_Demo_Tasks</name>
|
||||
<type>5</type>
|
||||
<matcher>
|
||||
|
@ -244,6 +244,42 @@
|
|||
<arguments>1.0-name-matches-false-false-MessageBufferDemo.c</arguments>
|
||||
</matcher>
|
||||
</filter>
|
||||
<filter>
|
||||
<id>1519407948274</id>
|
||||
<name>Standard_Demo_Tasks</name>
|
||||
<type>5</type>
|
||||
<matcher>
|
||||
<id>org.eclipse.ui.ide.multiFilter</id>
|
||||
<arguments>1.0-name-matches-false-false-StreamBufferDemo.c</arguments>
|
||||
</matcher>
|
||||
</filter>
|
||||
<filter>
|
||||
<id>1519407948277</id>
|
||||
<name>Standard_Demo_Tasks</name>
|
||||
<type>5</type>
|
||||
<matcher>
|
||||
<id>org.eclipse.ui.ide.multiFilter</id>
|
||||
<arguments>1.0-name-matches-false-false-StreamBufferInterrupt.c</arguments>
|
||||
</matcher>
|
||||
</filter>
|
||||
<filter>
|
||||
<id>1519407948281</id>
|
||||
<name>Standard_Demo_Tasks</name>
|
||||
<type>5</type>
|
||||
<matcher>
|
||||
<id>org.eclipse.ui.ide.multiFilter</id>
|
||||
<arguments>1.0-name-matches-false-false-MessageBufferDemo.c</arguments>
|
||||
</matcher>
|
||||
</filter>
|
||||
<filter>
|
||||
<id>1519407948286</id>
|
||||
<name>Standard_Demo_Tasks</name>
|
||||
<type>5</type>
|
||||
<matcher>
|
||||
<id>org.eclipse.ui.ide.multiFilter</id>
|
||||
<arguments>1.0-name-matches-false-false-MessageBufferAMP.c</arguments>
|
||||
</matcher>
|
||||
</filter>
|
||||
<filter>
|
||||
<id>0</id>
|
||||
<name>FreeRTOS_Source/portable</name>
|
||||
|
|
|
@ -114,6 +114,12 @@ uses the same semantics as the standard C assert() macro. */
|
|||
extern void vAssertCalled( unsigned long ulLine, const char * const pcFileName );
|
||||
#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __LINE__, __FILE__ )
|
||||
|
||||
#define configINCLUDE_MESSAGE_BUFFER_AMP_DEMO 1
|
||||
#if ( configINCLUDE_MESSAGE_BUFFER_AMP_DEMO == 1 )
|
||||
extern void vGenerateCoreBInterrupt( void * xUpdatedMessageBuffer );
|
||||
#define sbSEND_COMPLETED( pxStreamBuffer ) vGenerateCoreBInterrupt( pxStreamBuffer )
|
||||
#endif /* configINCLUDE_MESSAGE_BUFFER_AMP_DEMO */
|
||||
|
||||
/* Include the FreeRTOS+Trace FreeRTOS trace macro definitions. */
|
||||
#include "trcRecorder.h"
|
||||
|
||||
|
|
|
@ -26,81 +26,87 @@
|
|||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* NOTE 1: The Win32 port is a simulation (or is that emulation?) only! Do not
|
||||
* expect to get real time behaviour from the Win32 port or this demo
|
||||
* application. It is provided as a convenient development and demonstration
|
||||
* test bed only. This was tested using Windows XP on a dual core laptop.
|
||||
*
|
||||
* Windows will not be running the FreeRTOS simulator threads continuously, so
|
||||
* the timing information in the FreeRTOS+Trace logs have no meaningful units.
|
||||
* See the documentation page for the Windows simulator for an explanation of
|
||||
* the slow timing:
|
||||
* NOTE 1: Windows will not be running the FreeRTOS demo threads continuously, so
|
||||
* do not expect to get real time behaviour from the FreeRTOS Windows port, or
|
||||
* this demo application. Also, the timing information in the FreeRTOS+Trace
|
||||
* logs have no meaningful units. See the documentation page for the Windows
|
||||
* port for further information:
|
||||
* http://www.freertos.org/FreeRTOS-Windows-Simulator-Emulator-for-Visual-Studio-and-Eclipse-MingW.html
|
||||
* - READ THE WEB DOCUMENTATION FOR THIS PORT FOR MORE INFORMATION ON USING IT -
|
||||
*
|
||||
* NOTE 2: This project provides two demo applications. A simple blinky style
|
||||
* project, and a more comprehensive test and demo application. The
|
||||
* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting in main.c is used to select
|
||||
* between the two. See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY
|
||||
* in main.c. This file implements the simply blinky style version.
|
||||
* in main.c. This file implements the simply blinky version. Console output
|
||||
* is used in place of the normal LED toggling.
|
||||
*
|
||||
* NOTE 3: This file only contains the source code that is specific to the
|
||||
* basic demo. Generic functions, such FreeRTOS hook functions, are defined
|
||||
* in main.c.
|
||||
******************************************************************************
|
||||
*
|
||||
* main_blinky() creates one queue, and two tasks. It then starts the
|
||||
* scheduler.
|
||||
* main_blinky() creates one queue, one software timer, and two tasks. It then
|
||||
* starts the scheduler.
|
||||
*
|
||||
* The Queue Send Task:
|
||||
* The queue send task is implemented by the prvQueueSendTask() function in
|
||||
* this file. prvQueueSendTask() sits in a loop that causes it to repeatedly
|
||||
* block for 200 (simulated as far as the scheduler is concerned, but in
|
||||
* reality much longer - see notes above) milliseconds, before sending the
|
||||
* value 100 to the queue that was created within main_blinky(). Once the
|
||||
* value is sent, the task loops back around to block for another 200
|
||||
* (simulated) milliseconds.
|
||||
* this file. It uses vTaskDelayUntil() to create a periodic task that sends
|
||||
* the value 100 to the queue every 200 milliseconds (please read the notes
|
||||
* above regarding the accuracy of timing under Windows).
|
||||
*
|
||||
* The Queue Send Software Timer:
|
||||
* The timer is an auto-reload timer with a period of two seconds. The timer's
|
||||
* callback function writes the value 200 to the queue. The callback function
|
||||
* is implemented by prvQueueSendTimerCallback() within this file.
|
||||
*
|
||||
* The Queue Receive Task:
|
||||
* The queue receive task is implemented by the prvQueueReceiveTask() function
|
||||
* in this file. prvQueueReceiveTask() sits in a loop where it repeatedly
|
||||
* blocks on attempts to read data from the queue that was created within
|
||||
* main_blinky(). When data is received, the task checks the value of the
|
||||
* data, and if the value equals the expected 100, outputs a message. The
|
||||
* 'block time' parameter passed to the queue receive function specifies that
|
||||
* the task should be held in the Blocked state indefinitely to wait for data
|
||||
* to be available on the queue. The queue receive task will only leave the
|
||||
* Blocked state when the queue send task writes to the queue. As the queue
|
||||
* send task writes to the queue every 200 (simulated - see notes above)
|
||||
* milliseconds, the queue receive task leaves the Blocked state every 200
|
||||
* milliseconds, and therefore outputs a message every 200 milliseconds.
|
||||
* in this file. prvQueueReceiveTask() waits for data to arrive on the queue.
|
||||
* When data is received, the task checks the value of the data, then outputs a
|
||||
* message to indicate if the data came from the queue send task or the queue
|
||||
* send software timer.
|
||||
*
|
||||
* Expected Behaviour:
|
||||
* - The queue send task writes to the queue every 200ms, so every 200ms the
|
||||
* queue receive task will output a message indicating that data was received
|
||||
* on the queue from the queue send task.
|
||||
* - The queue send software timer has a period of two seconds, and is reset
|
||||
* each time a key is pressed. So if two seconds expire without a key being
|
||||
* pressed then the queue receive task will output a message indicating that
|
||||
* data was received on the queue from the queue send software timer.
|
||||
*
|
||||
* NOTE: Console input and output relies on Windows system calls, which can
|
||||
* interfere with the execution of the FreeRTOS Windows port. This demo only
|
||||
* uses Windows system call occasionally. Heavier use of Windows system calls
|
||||
* can crash the port.
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdio.h>
|
||||
#include <conio.h>
|
||||
|
||||
/* Kernel includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "timers.h"
|
||||
#include "semphr.h"
|
||||
|
||||
/* Priorities at which the tasks are created. */
|
||||
#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
|
||||
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
|
||||
|
||||
/* The rate at which data is sent to the queue. The 200ms value is converted
|
||||
to ticks using the portTICK_PERIOD_MS constant. */
|
||||
#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS )
|
||||
/* The rate at which data is sent to the queue. The times are converted from
|
||||
milliseconds to ticks using the pdMS_TO_TICKS() macro. */
|
||||
#define mainTASK_SEND_FREQUENCY_MS pdMS_TO_TICKS( 200UL )
|
||||
#define mainTIMER_SEND_FREQUENCY_MS pdMS_TO_TICKS( 2000UL )
|
||||
|
||||
/* The number of items the queue can hold. This is 1 as the receive task
|
||||
will remove items as they are added, meaning the send task should always find
|
||||
the queue empty. */
|
||||
#define mainQUEUE_LENGTH ( 1 )
|
||||
/* The number of items the queue can hold at once. */
|
||||
#define mainQUEUE_LENGTH ( 2 )
|
||||
|
||||
/* Values passed to the two tasks just to check the task parameter
|
||||
functionality. */
|
||||
#define mainQUEUE_SEND_PARAMETER ( 0x1111UL )
|
||||
#define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL )
|
||||
/* The values sent to the queue receive task from the queue send task and the
|
||||
queue send software timer respectively. */
|
||||
#define mainVALUE_SENT_FROM_TASK ( 100UL )
|
||||
#define mainVALUE_SENT_FROM_TIMER ( 200UL )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -110,30 +116,53 @@ functionality. */
|
|||
static void prvQueueReceiveTask( void *pvParameters );
|
||||
static void prvQueueSendTask( void *pvParameters );
|
||||
|
||||
/*
|
||||
* The callback function executed when the software timer expires.
|
||||
*/
|
||||
static void prvQueueSendTimerCallback( TimerHandle_t xTimerHandle );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* The queue used by both tasks. */
|
||||
static QueueHandle_t xQueue = NULL;
|
||||
|
||||
/* A software timer that is started from the tick hook. */
|
||||
static TimerHandle_t xTimer = NULL;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*** SEE THE COMMENTS AT THE TOP OF THIS FILE ***/
|
||||
void main_blinky( void )
|
||||
{
|
||||
const TickType_t xTimerPeriod = mainTIMER_SEND_FREQUENCY_MS;
|
||||
|
||||
/* Create the queue. */
|
||||
xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) );
|
||||
xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( uint32_t ) );
|
||||
|
||||
if( xQueue != NULL )
|
||||
{
|
||||
/* Start the two tasks as described in the comments at the top of this
|
||||
file. */
|
||||
xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */
|
||||
"Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
|
||||
configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */
|
||||
( void * ) mainQUEUE_RECEIVE_PARAMETER, /* The parameter passed to the task - just to check the functionality. */
|
||||
mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */
|
||||
NULL ); /* The task handle is not required, so NULL is passed. */
|
||||
xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */
|
||||
"Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
|
||||
configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */
|
||||
NULL, /* The parameter passed to the task - not used in this simple case. */
|
||||
mainQUEUE_RECEIVE_TASK_PRIORITY,/* The priority assigned to the task. */
|
||||
NULL ); /* The task handle is not required, so NULL is passed. */
|
||||
|
||||
xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, ( void * ) mainQUEUE_SEND_PARAMETER, mainQUEUE_SEND_TASK_PRIORITY, NULL );
|
||||
xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL );
|
||||
|
||||
/* Create the software timer, but don't start it yet. */
|
||||
xTimer = xTimerCreate( "Timer", /* The text name assigned to the software timer - for debug only as it is not used by the kernel. */
|
||||
xTimerPeriod, /* The period of the software timer in ticks. */
|
||||
pdTRUE, /* xAutoReload is set to pdTRUE. */
|
||||
NULL, /* The timer's ID is not used. */
|
||||
prvQueueSendTimerCallback );/* The function executed when the timer expires. */
|
||||
|
||||
if( xTimer != NULL )
|
||||
{
|
||||
xTimerStart( xTimer, 0 );
|
||||
}
|
||||
|
||||
/* Start the tasks and timer running. */
|
||||
vTaskStartScheduler();
|
||||
|
@ -151,65 +180,86 @@ void main_blinky( void )
|
|||
static void prvQueueSendTask( void *pvParameters )
|
||||
{
|
||||
TickType_t xNextWakeTime;
|
||||
const unsigned long ulValueToSend = 100UL;
|
||||
const TickType_t xBlockTime = pdMS_TO_TICKS( mainQUEUE_SEND_FREQUENCY_MS );
|
||||
const TickType_t xBlockTime = mainTASK_SEND_FREQUENCY_MS;
|
||||
const uint32_t ulValueToSend = mainVALUE_SENT_FROM_TASK;
|
||||
|
||||
/* Remove compiler warning in the case that configASSERT() is not
|
||||
defined. */
|
||||
/* Prevent the compiler warning about the unused parameter. */
|
||||
( void ) pvParameters;
|
||||
|
||||
/* Check the task parameter is as expected. */
|
||||
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_SEND_PARAMETER );
|
||||
|
||||
/* Initialise xNextWakeTime - this only needs to be done once. */
|
||||
xNextWakeTime = xTaskGetTickCount();
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
/* Place this task in the blocked state until it is time to run again.
|
||||
The block time is specified in ticks, the constant used converts ticks
|
||||
to ms. While in the Blocked state this task will not consume any CPU
|
||||
time. */
|
||||
The block time is specified in ticks, pdMS_TO_TICKS() was used to
|
||||
convert a time specified in milliseconds into a time specified in ticks.
|
||||
While in the Blocked state this task will not consume any CPU time. */
|
||||
vTaskDelayUntil( &xNextWakeTime, xBlockTime );
|
||||
|
||||
/* Send to the queue - causing the queue receive task to unblock and
|
||||
toggle the LED. 0 is used as the block time so the sending operation
|
||||
write to the console. 0 is used as the block time so the send operation
|
||||
will not block - it shouldn't need to block as the queue should always
|
||||
be empty at this point in the code. */
|
||||
have at least one space at this point in the code. */
|
||||
xQueueSend( xQueue, &ulValueToSend, 0U );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvQueueSendTimerCallback( TimerHandle_t xTimerHandle )
|
||||
{
|
||||
const uint32_t ulValueToSend = mainVALUE_SENT_FROM_TIMER;
|
||||
|
||||
/* This is the software timer callback function. The software timer has a
|
||||
period of two seconds and is reset each time a key is pressed. This
|
||||
callback function will execute if the timer expires, which will only happen
|
||||
if a key is not pressed for two seconds. */
|
||||
|
||||
/* Avoid compiler warnings resulting from the unused parameter. */
|
||||
( void ) xTimerHandle;
|
||||
|
||||
/* Send to the queue - causing the queue receive task to unblock and
|
||||
write out a message. This function is called from the timer/daemon task, so
|
||||
must not block. Hence the block time is set to 0. */
|
||||
xQueueSend( xQueue, &ulValueToSend, 0U );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvQueueReceiveTask( void *pvParameters )
|
||||
{
|
||||
unsigned long ulReceivedValue;
|
||||
uint32_t ulReceivedValue;
|
||||
|
||||
/* Remove compiler warning in the case that configASSERT() is not
|
||||
defined. */
|
||||
/* Prevent the compiler warning about the unused parameter. */
|
||||
( void ) pvParameters;
|
||||
|
||||
/* Check the task parameter is as expected. */
|
||||
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
/* Wait until something arrives in the queue - this task will block
|
||||
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
|
||||
FreeRTOSConfig.h. */
|
||||
FreeRTOSConfig.h. It will not use any CPU time while it is in the
|
||||
Blocked state. */
|
||||
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
|
||||
|
||||
/* To get here something must have been received from the queue, but
|
||||
is it the expected value? If it is, toggle the LED. */
|
||||
if( ulReceivedValue == 100UL )
|
||||
/* To get here something must have been received from the queue, but
|
||||
is it an expected value? Normally calling printf() from a task is not
|
||||
a good idea. Here there is lots of stack space and only one task is
|
||||
using console IO so it is ok. However, note the comments at the top of
|
||||
this file about the risks of making Windows system calls (such as
|
||||
console output) from a FreeRTOS task. */
|
||||
if( ulReceivedValue == mainVALUE_SENT_FROM_TASK )
|
||||
{
|
||||
/* Normally calling printf() from a task is not a good idea. Here
|
||||
there is lots of stack space and only one task is using console IO
|
||||
so it is ok. */
|
||||
printf( "Message received\r\n" );
|
||||
fflush( stdout );
|
||||
ulReceivedValue = 0U;
|
||||
printf( "Message received from task\r\n" );
|
||||
}
|
||||
else if( ulReceivedValue == mainVALUE_SENT_FROM_TIMER )
|
||||
{
|
||||
printf( "Message received from software timer\r\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "Unexpected message\r\n" );
|
||||
}
|
||||
|
||||
fflush( stdout );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
|
@ -102,6 +102,8 @@
|
|||
#include "AbortDelay.h"
|
||||
#include "MessageBufferDemo.h"
|
||||
#include "StreamBufferDemo.h"
|
||||
#include "StreamBufferInterrupt.h"
|
||||
#include "MessageBufferAMP.h"
|
||||
|
||||
/* Priorities at which the tasks are created. */
|
||||
#define mainCHECK_TASK_PRIORITY ( configMAX_PRIORITIES - 2 )
|
||||
|
@ -204,6 +206,8 @@ int main_full( void )
|
|||
|
||||
vStartMessageBufferTasks();
|
||||
vStartStreamBufferTasks();
|
||||
vStartStreamBufferInterruptDemo();
|
||||
vStartMessageBufferAMPTasks();
|
||||
|
||||
#if( configUSE_PREEMPTION != 0 )
|
||||
{
|
||||
|
@ -342,10 +346,28 @@ const TickType_t xCycleFrequency = pdMS_TO_TICKS( 2500UL );
|
|||
{
|
||||
pcStatusMessage = "Error: Abort delay";
|
||||
}
|
||||
else if( xIsInterruptStreamBufferDemoStillRunning() != pdPASS )
|
||||
{
|
||||
pcStatusMessage = "Error: Stream buffer interrupt";
|
||||
}
|
||||
else if( xAreMessageBufferAMPTasksStillRunning() != pdPASS )
|
||||
{
|
||||
pcStatusMessage = "Error: Message buffer AMP";
|
||||
}
|
||||
|
||||
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
else if( xAreStaticAllocationTasksStillRunning() != pdPASS )
|
||||
{
|
||||
pcStatusMessage = "Error: Static allocation";
|
||||
}
|
||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
|
||||
/* This is the only task that uses stdout so its ok to call printf()
|
||||
directly. */
|
||||
printf( ( char * ) "%s - %u\r\n", pcStatusMessage, ( unsigned int ) xTaskGetTickCount() );
|
||||
printf( "%s - tick count %u - free heap %u - min free heap %u\r\n", pcStatusMessage,
|
||||
xTaskGetTickCount(),
|
||||
xPortGetFreeHeapSize(),
|
||||
xPortGetMinimumEverFreeHeapSize() );
|
||||
fflush( stdout );
|
||||
}
|
||||
}
|
||||
|
@ -454,6 +476,10 @@ TaskHandle_t xTimerTask;
|
|||
level functionality. */
|
||||
vPeriodicStreamBufferProcessing();
|
||||
|
||||
/* Writes a string to a string buffer four bytes at a time to demonstrate
|
||||
a stream being sent from an interrupt to a task. */
|
||||
vBasicStreamBufferSendFromISR();
|
||||
|
||||
/* For code coverage purposes. */
|
||||
xTimerTask = xTimerGetTimerDaemonTaskHandle();
|
||||
configASSERT( uxTaskPriorityGetFromISR( xTimerTask ) == configTIMER_TASK_PRIORITY );
|
||||
|
|
|
@ -752,13 +752,23 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||
if( ( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) || ( xCopyPosition == queueOVERWRITE ) )
|
||||
{
|
||||
traceQUEUE_SEND( pxQueue );
|
||||
xYieldRequired = prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
|
||||
|
||||
#if ( configUSE_QUEUE_SETS == 1 )
|
||||
{
|
||||
UBaseType_t uxPreviousMessagesWaiting = pxQueue->uxMessagesWaiting;
|
||||
|
||||
xYieldRequired = prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
|
||||
|
||||
if( pxQueue->pxQueueSetContainer != NULL )
|
||||
{
|
||||
if( prvNotifyQueueSetContainer( pxQueue, xCopyPosition ) != pdFALSE )
|
||||
if( ( xCopyPosition == queueOVERWRITE ) && ( uxPreviousMessagesWaiting != ( UBaseType_t ) 0 ) )
|
||||
{
|
||||
/* Do not notify the queue set as an existing item
|
||||
was overwritten in the queue so the number of items
|
||||
in the queue has not changed. */
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
else if( prvNotifyQueueSetContainer( pxQueue, xCopyPosition ) != pdFALSE )
|
||||
{
|
||||
/* The queue is a member of a queue set, and posting
|
||||
to the queue set caused a higher priority task to
|
||||
|
@ -805,6 +815,8 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||
}
|
||||
#else /* configUSE_QUEUE_SETS */
|
||||
{
|
||||
xYieldRequired = prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
|
||||
|
||||
/* If there was a task waiting for data to arrive on the
|
||||
queue then unblock it now. */
|
||||
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
|
||||
|
|
Loading…
Reference in a new issue