summaryrefslogtreecommitdiff
path: root/FreeRTOS
diff options
context:
space:
mode:
authorrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>2018-02-26 21:22:44 +0000
committerrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>2018-02-26 21:22:44 +0000
commitda030c7fd0b1f096ccf5731821db3de3c740b56f (patch)
treedb73609abadb400c26e2d498cd7bcfc9c350c0a8 /FreeRTOS
parent67c1fb11d75e21c357c7b09e2b527b813676e14d (diff)
downloadfreertos-da030c7fd0b1f096ccf5731821db3de3c740b56f.tar.gz
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. git-svn-id: http://svn.code.sf.net/p/freertos/code/trunk@2530 1d2547de-c912-0410-9cb9-b8ca96c0e9e2
Diffstat (limited to 'FreeRTOS')
-rw-r--r--FreeRTOS/Demo/Common/Minimal/QueueSet.c80
-rw-r--r--FreeRTOS/Demo/Common/Minimal/StreamBufferInterrupt.c4
-rw-r--r--FreeRTOS/Demo/WIN32-MSVC/.vs/WIN32/v14/.suobin44032 -> 49664 bytes
-rw-r--r--FreeRTOS/Demo/WIN32-MSVC/main_full.c4
-rw-r--r--FreeRTOS/Demo/WIN32-MingW/.project78
-rw-r--r--FreeRTOS/Demo/WIN32-MingW/FreeRTOSConfig.h6
-rw-r--r--FreeRTOS/Demo/WIN32-MingW/main_blinky.c204
-rw-r--r--FreeRTOS/Demo/WIN32-MingW/main_full.c28
-rw-r--r--FreeRTOS/Source/queue.c16
9 files changed, 314 insertions, 106 deletions
diff --git a/FreeRTOS/Demo/Common/Minimal/QueueSet.c b/FreeRTOS/Demo/Common/Minimal/QueueSet.c
index 9f346bb5a..528ec06c0 100644
--- a/FreeRTOS/Demo/Common/Minimal/QueueSet.c
+++ b/FreeRTOS/Demo/Common/Minimal/QueueSet.c
@@ -138,10 +138,18 @@ 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 );
diff --git a/FreeRTOS/Demo/Common/Minimal/StreamBufferInterrupt.c b/FreeRTOS/Demo/Common/Minimal/StreamBufferInterrupt.c
index 772d5b4c6..112dbf30c 100644
--- a/FreeRTOS/Demo/Common/Minimal/StreamBufferInterrupt.c
+++ b/FreeRTOS/Demo/Common/Minimal/StreamBufferInterrupt.c
@@ -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 );
diff --git a/FreeRTOS/Demo/WIN32-MSVC/.vs/WIN32/v14/.suo b/FreeRTOS/Demo/WIN32-MSVC/.vs/WIN32/v14/.suo
index e28c889a4..87d803022 100644
--- a/FreeRTOS/Demo/WIN32-MSVC/.vs/WIN32/v14/.suo
+++ b/FreeRTOS/Demo/WIN32-MSVC/.vs/WIN32/v14/.suo
Binary files differ
diff --git a/FreeRTOS/Demo/WIN32-MSVC/main_full.c b/FreeRTOS/Demo/WIN32-MSVC/main_full.c
index b99ff8b8d..68488eb37 100644
--- a/FreeRTOS/Demo/WIN32-MSVC/main_full.c
+++ b/FreeRTOS/Demo/WIN32-MSVC/main_full.c
@@ -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 );
/*
diff --git a/FreeRTOS/Demo/WIN32-MingW/.project b/FreeRTOS/Demo/WIN32-MingW/.project
index 3d2741c3b..07f94ab4e 100644
--- a/FreeRTOS/Demo/WIN32-MingW/.project
+++ b/FreeRTOS/Demo/WIN32-MingW/.project
@@ -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>
@@ -245,6 +245,42 @@
</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>
<type>9</type>
diff --git a/FreeRTOS/Demo/WIN32-MingW/FreeRTOSConfig.h b/FreeRTOS/Demo/WIN32-MingW/FreeRTOSConfig.h
index 89331b274..f25119d49 100644
--- a/FreeRTOS/Demo/WIN32-MingW/FreeRTOSConfig.h
+++ b/FreeRTOS/Demo/WIN32-MingW/FreeRTOSConfig.h
@@ -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"
diff --git a/FreeRTOS/Demo/WIN32-MingW/main_blinky.c b/FreeRTOS/Demo/WIN32-MingW/main_blinky.c
index d04658289..822cbd424 100644
--- a/FreeRTOS/Demo/WIN32-MingW/main_blinky.c
+++ b/FreeRTOS/Demo/WIN32-MingW/main_blinky.c
@@ -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 )
+ {
+ printf( "Message received from task\r\n" );
+ }
+ else if( ulReceivedValue == mainVALUE_SENT_FROM_TIMER )
{
- /* 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 software timer\r\n" );
}
+ else
+ {
+ printf( "Unexpected message\r\n" );
+ }
+
+ fflush( stdout );
}
}
/*-----------------------------------------------------------*/
diff --git a/FreeRTOS/Demo/WIN32-MingW/main_full.c b/FreeRTOS/Demo/WIN32-MingW/main_full.c
index 4f3c1676f..b67a6fd0c 100644
--- a/FreeRTOS/Demo/WIN32-MingW/main_full.c
+++ b/FreeRTOS/Demo/WIN32-MingW/main_full.c
@@ -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 );
diff --git a/FreeRTOS/Source/queue.c b/FreeRTOS/Source/queue.c
index 6706629e9..80c976bd3 100644
--- a/FreeRTOS/Source/queue.c
+++ b/FreeRTOS/Source/queue.c
@@ -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 )