diff --git a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/CLICommands/UDPCommandServer.c b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/CLICommands/UDPCommandServer.c
index e1211c18e6..bcc805bb12 100644
--- a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/CLICommands/UDPCommandServer.c
+++ b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/CLICommands/UDPCommandServer.c
@@ -85,7 +85,7 @@
#define cmdMAX_INPUT_SIZE 60
/* Dimensions the buffer into which string outputs can be placed. */
-#define cmdMAX_OUTPUT_SIZE 1024
+#define cmdMAX_OUTPUT_SIZE 1250
/* Dimensions the buffer passed to the recvfrom() call. */
#define cmdSOCKET_INPUT_BUFFER_SIZE 60
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-UDP/FreeRTOS_UDP_IP.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-UDP/FreeRTOS_UDP_IP.c
index e9006adf74..a4d204b58f 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-UDP/FreeRTOS_UDP_IP.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-UDP/FreeRTOS_UDP_IP.c
@@ -392,7 +392,7 @@ xIPStackEvent_t xReceivedEvent;
/* Create the ARP timer, but don't start it until the network has
connected. */
- xARPTimer = xTimerCreate( "ARPTimer", ( ipARP_TIMER_PERIOD_MS / portTICK_RATE_MS ), pdTRUE, ( void * ) eARPTimerEvent, vIPFunctionsTimerCallback );
+ xARPTimer = xTimerCreate( "ARPTimer", ( ipARP_TIMER_PERIOD_MS / portTICK_RATE_MS ), pdTRUE, ( void * ) eARPTimerEvent, vIPFunctionsTimerCallback );
configASSERT( xARPTimer );
/* Generate a dummy message to say that the network connection has gone
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-UDP/portable/NetworkInterface/SAM4E/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-UDP/portable/NetworkInterface/SAM4E/NetworkInterface.c
index 619bdee3af..0d262194ad 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-UDP/portable/NetworkInterface/SAM4E/NetworkInterface.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-UDP/portable/NetworkInterface/SAM4E/NetworkInterface.c
@@ -81,13 +81,12 @@ static void prvGMACRxCallback( uint32_t ulStatus );
/* The queue used to communicate Ethernet events to the IP task. */
extern xQueueHandle xNetworkEventQueue;
-/* The semaphore used to wake the deferred interrupt handler task when an Rx
-interrupt is received. */
-static xSemaphoreHandle xGMACRxEventSemaphore = NULL;
-
/* The GMAC driver instance. */
static gmac_device_t xGMACStruct;
+/* Handle of the task used to process MAC events. */
+static TaskHandle_t xMACEventHandlingTask = NULL;
+
/*-----------------------------------------------------------*/
BaseType_t xNetworkInterfaceInitialise( void )
@@ -123,20 +122,6 @@ BaseType_t xReturn = pdFALSE;
vTaskDelay( xPHYDelay_400ms * 2UL );
if( ethernet_phy_set_link( GMAC, BOARD_GMAC_PHY_ADDR, 1 ) == GMAC_OK )
{
- /* Create the event semaphore if it has not already been
- created. */
- if( xGMACRxEventSemaphore == NULL )
- {
- xGMACRxEventSemaphore = xSemaphoreCreateCounting( ULONG_MAX, 0 );
- #if ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS == 1
- {
- /* If the trace recorder code is included name the semaphore for
- viewing in FreeRTOS+Trace. */
- vTraceSetQueueName( xGMACRxEventSemaphore, "MAC_RX" );
- }
- #endif /* ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS == 1 */
- }
-
/* Register the callbacks. */
gmac_dev_set_rx_callback( &xGMACStruct, prvGMACRxCallback );
@@ -149,7 +134,7 @@ BaseType_t xReturn = pdFALSE;
configMINIMAL_STACK_SIZE, /* Stack allocated to the task (defined in words, not bytes). */
NULL, /* The task parameter is not used. */
configMAX_PRIORITIES - 1, /* The priority assigned to the task. */
- NULL ); /* The handle is not required, so NULL is passed. */
+ &xMACEventHandlingTask ); /* The handle is stored so the ISR knows which task to notify. */
/* Enable the interrupt and set its priority as configured.
THIS DRIVER REQUIRES configMAC_INTERRUPT_PRIORITY TO BE DEFINED,
@@ -169,10 +154,12 @@ static void prvGMACRxCallback( uint32_t ulStatus )
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+ configASSERT( xMACEventHandlingTask );
+
/* Unblock the deferred interrupt handler task if the event was an Rx. */
if( ulStatus == GMAC_RSR_REC )
{
- xSemaphoreGiveFromISR( xGMACRxEventSemaphore, &xHigherPriorityTaskWoken );
+ xTaskNotifyGiveFromISR( xMACEventHandlingTask, &xHigherPriorityTaskWoken );
}
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
@@ -220,8 +207,9 @@ xIPStackEvent_t xRxEvent = { eEthernetRxEvent, NULL };
static const TickType_t xBufferWaitDelay = 1500UL / portTICK_RATE_MS;
uint32_t ulReturned;
+ /* This is a very simply but also inefficient implementation. */
+
( void ) pvParameters;
- configASSERT( xGMACRxEventSemaphore );
for( ;; )
{
@@ -229,9 +217,9 @@ uint32_t ulReturned;
received. The while() loop is only needed if INCLUDE_vTaskSuspend is
set to 0 in FreeRTOSConfig.h. If INCLUDE_vTaskSuspend is set to 1
then portMAX_DELAY would be an indefinite block time and
- xSemaphoreTake() would only return when the semaphore was actually
- obtained. */
- while( xSemaphoreTake( xGMACRxEventSemaphore, portMAX_DELAY ) == pdFALSE );
+ xTaskNotifyTake() would only return when the task was actually
+ notified. */
+ while( ulTaskNotifyTake( pdFALSE, portMAX_DELAY ) == 0 );
/* Allocate a buffer to hold the data. */
pxNetworkBuffer = pxNetworkBufferGet( ipTOTAL_ETHERNET_FRAME_SIZE, xBufferWaitDelay );
diff --git a/FreeRTOS/Demo/CORTEX_M4F_Infineon_XMC4000_Keil/RTOSDemo.uvopt b/FreeRTOS/Demo/CORTEX_M4F_Infineon_XMC4000_Keil/RTOSDemo.uvopt
index 4d3070ec6d..40c44a1b15 100644
--- a/FreeRTOS/Demo/CORTEX_M4F_Infineon_XMC4000_Keil/RTOSDemo.uvopt
+++ b/FreeRTOS/Demo/CORTEX_M4F_Infineon_XMC4000_Keil/RTOSDemo.uvopt
@@ -73,7 +73,7 @@
1
0
- 1
+ 0
255
@@ -98,16 +98,6 @@
datashts\arm\cortex_m4\r0p1\DUI0553A_CORTEX_M4_DGUG.PDF
-
- SARMCM3.DLL
- -MPU -REMAP
- DCM.DLL
- -pCM4
- SARMCM3.DLL
- -MPU
- TCM.DLL
- -pCM4
-
0
1
@@ -126,9 +116,11 @@
0
1
0
+ 1
+ 1
0
0
- 7
+ 6
@@ -191,6 +183,7 @@
1
5
0x0C000000
+ 0
@@ -280,7 +273,7 @@
1
0
- 0
+ 1
255
@@ -305,16 +298,6 @@
datashts\arm\cortex_m4\r0p1\DUI0553A_CORTEX_M4_DGUG.PDF
-
- SARMCM3.DLL
- -MPU -REMAP
- DCM.DLL
- -pCM4
- SARMCM3.DLL
- -MPU
- TCM.DLL
- -pCM4
-
0
1
@@ -333,9 +316,11 @@
0
1
0
+ 1
+ 1
0
0
- 7
+ 6
@@ -391,6 +376,7 @@
1
2
0x20005f90
+ 0
@@ -399,7 +385,7 @@
0
1
- 1
+ 0
0
0
0
@@ -505,16 +491,6 @@
datashts\arm\cortex_m4\r0p1\DUI0553A_CORTEX_M4_DGUG.PDF
-
- SARMCM3.DLL
- -MPU -REMAP
- DCM.DLL
- -pCM4
- SARMCM3.DLL
- -MPU
- TCM.DLL
- -pCM4
-
0
1
@@ -533,6 +509,8 @@
0
1
0
+ 1
+ 1
0
0
7
@@ -591,6 +569,7 @@
1
5
0x0C000000
+ 0
@@ -639,10 +618,7 @@
2
0
0
- 0
0
- 277
- 289
0
.\startup_XMC4500.s
startup_XMC4500.s
@@ -655,10 +631,7 @@
1
0
0
- 0
0
- 0
- 0
0
.\System_XMC4500.c
System_XMC4500.c
@@ -671,10 +644,7 @@
2
0
0
- 0
0
- 276
- 288
0
.\startup_XMC4200.s
startup_XMC4200.s
@@ -687,10 +657,7 @@
1
0
0
- 0
0
- 0
- 0
0
.\system_XMC4200.c
system_XMC4200.c
@@ -703,10 +670,7 @@
1
0
0
- 7
0
- 0
- 0
0
.\system_XMC4400.c
system_XMC4400.c
@@ -719,10 +683,7 @@
2
0
0
- 0
0
- 276
- 288
0
.\startup_XMC4400.s
startup_XMC4400.s
@@ -743,10 +704,7 @@
1
0
0
- 45
0
- 63
- 97
0
.\main.c
main.c
@@ -759,10 +717,7 @@
5
0
0
- 0
0
- 1
- 1
0
.\FreeRTOSConfig.h
FreeRTOSConfig.h
@@ -775,10 +730,7 @@
1
0
0
- 0
0
- 0
- 0
0
.\RegTest.c
RegTest.c
@@ -791,10 +743,7 @@
1
0
0
- 0
0
- 0
- 0
0
.\main_full.c
main_full.c
@@ -807,10 +756,7 @@
1
0
0
- 0
0
- 0
- 0
0
.\main_blinky.c
main_blinky.c
@@ -831,10 +777,7 @@
1
0
0
- 0
0
- 0
- 0
0
..\..\Source\timers.c
timers.c
@@ -847,10 +790,7 @@
1
0
0
- 0
0
- 0
- 0
0
..\..\Source\list.c
list.c
@@ -863,10 +803,7 @@
1
0
0
- 0
0
- 552
- 560
0
..\..\Source\queue.c
queue.c
@@ -879,10 +816,7 @@
1
0
0
- 0
0
- 0
- 0
0
..\..\Source\tasks.c
tasks.c
@@ -895,10 +829,7 @@
1
0
0
- 0
0
- 420
- 428
0
..\..\Source\portable\RVDS\ARM_CM4F\port.c
port.c
@@ -911,10 +842,7 @@
1
0
0
- 0
0
- 0
- 0
0
..\..\Source\portable\MemMang\heap_4.c
heap_4.c
@@ -935,10 +863,7 @@
1
0
0
- 0
0
- 0
- 0
0
..\Common\Minimal\semtest.c
semtest.c
@@ -951,10 +876,7 @@
1
0
0
- 0
0
- 254
- 262
0
..\Common\Minimal\sp_flop.c
sp_flop.c
@@ -967,10 +889,7 @@
1
0
0
- 0
0
- 0
- 0
0
..\Common\Minimal\blocktim.c
blocktim.c
@@ -983,10 +902,7 @@
1
0
0
- 0
0
- 0
- 0
0
..\Common\Minimal\countsem.c
countsem.c
@@ -999,10 +915,7 @@
1
0
0
- 0
0
- 0
- 0
0
..\Common\Minimal\dynamic.c
dynamic.c
@@ -1015,10 +928,7 @@
1
0
0
- 0
0
- 0
- 0
0
..\Common\Minimal\GenQTest.c
GenQTest.c
@@ -1031,10 +941,7 @@
1
0
0
- 0
0
- 0
- 0
0
..\Common\Minimal\recmutex.c
recmutex.c
diff --git a/FreeRTOS/Demo/CORTEX_M4F_Infineon_XMC4000_Keil/RTOSDemo.uvproj b/FreeRTOS/Demo/CORTEX_M4F_Infineon_XMC4000_Keil/RTOSDemo.uvproj
index eed7550aa9..54126d504a 100644
--- a/FreeRTOS/Demo/CORTEX_M4F_Infineon_XMC4000_Keil/RTOSDemo.uvproj
+++ b/FreeRTOS/Demo/CORTEX_M4F_Infineon_XMC4000_Keil/RTOSDemo.uvproj
@@ -30,6 +30,7 @@
SFD\Infineon\XMC4500\xmc4500.sfr
+ 0
0
@@ -71,6 +72,8 @@
0
0
+ 0
+ 0
0
@@ -97,6 +100,7 @@
3
+ 1
SARMCM3.DLL
@@ -126,6 +130,7 @@
1
1
0
+ 1
1
@@ -137,9 +142,10 @@
0
1
0
+ 1
0
- 7
+ 6
@@ -169,6 +175,10 @@
BIN\UL2CM3.DLL
"" ()
+
+
+
+ 0
@@ -347,6 +357,8 @@
0
0
0
+ 0
+ 0
--cpu Cortex-M4.fp --no_allow_fpreg_for_nonfpdata
rvkdm PART_XMC4500
@@ -363,6 +375,7 @@
0
0
0
+ 0
@@ -379,6 +392,7 @@
0
0x0C000000
0x10000000
+
@@ -421,6 +435,7 @@
11
+ 1
@@ -432,6 +447,7 @@
2
2
2
+ 2
@@ -461,6 +477,7 @@
11
+ 1
@@ -477,6 +494,8 @@
0
2
2
+ 2
+ 2
@@ -506,6 +525,7 @@
11
+ 1
@@ -522,6 +542,8 @@
0
2
2
+ 2
+ 2
@@ -551,6 +573,7 @@
11
+ 1
@@ -562,6 +585,7 @@
2
2
2
+ 2
@@ -705,6 +729,7 @@
SFD\Infineon\XMC4400\xmc4400.SFR
+ 0
0
@@ -746,6 +771,8 @@
0
0
+ 0
+ 0
0
@@ -772,6 +799,7 @@
3
+ 1
SARMCM3.DLL
@@ -801,6 +829,7 @@
1
1
0
+ 1
1
@@ -812,9 +841,10 @@
0
1
0
+ 1
0
- 7
+ 6
@@ -844,6 +874,10 @@
BIN\UL2CM3.DLL
+
+
+
+ 0
@@ -1010,7 +1044,7 @@
1
- 2
+ 1
0
0
0
@@ -1022,6 +1056,8 @@
0
0
0
+ 0
+ 0
--cpu Cortex-M4.fp --no_allow_fpreg_for_nonfpdata
rvkdm PART_XMC4400
@@ -1038,6 +1074,7 @@
0
0
0
+ 0
@@ -1054,6 +1091,7 @@
0
0x0C000000
0x10000000
+
@@ -1086,6 +1124,7 @@
11
+ 1
@@ -1097,6 +1136,7 @@
2
2
2
+ 2
@@ -1126,6 +1166,7 @@
11
+ 1
@@ -1142,6 +1183,8 @@
0
2
2
+ 2
+ 2
@@ -1171,6 +1214,7 @@
11
+ 1
@@ -1182,6 +1226,7 @@
2
2
2
+ 2
@@ -1211,6 +1256,7 @@
11
+ 1
@@ -1227,6 +1273,8 @@
0
2
2
+ 2
+ 2
@@ -1380,6 +1428,7 @@
SFD\Infineon\XMC4200-4100\xmc4200.SFR
+ 0
0
@@ -1421,6 +1470,8 @@
0
0
+ 0
+ 0
0
@@ -1447,6 +1498,7 @@
3
+ 1
SARMCM3.DLL
@@ -1476,6 +1528,7 @@
1
1
0
+ 1
1
@@ -1487,6 +1540,7 @@
0
1
0
+ 1
0
7
@@ -1519,6 +1573,10 @@
BIN\UL2CM3.DLL
"" ()
+
+
+
+ 0
@@ -1697,6 +1755,8 @@
0
0
0
+ 0
+ 0
--cpu Cortex-M4.fp --no_allow_fpreg_for_nonfpdata
rvkdm PART_XMC4200
@@ -1713,6 +1773,7 @@
0
0
0
+ 0
@@ -1729,6 +1790,7 @@
0
0x0C000000
0x10000000
+
@@ -1761,6 +1823,7 @@
11
+ 1
@@ -1772,6 +1835,7 @@
2
2
2
+ 2
@@ -1801,6 +1865,7 @@
11
+ 1
@@ -1817,6 +1882,8 @@
0
2
2
+ 2
+ 2
@@ -1856,6 +1923,7 @@
11
+ 1
@@ -1872,6 +1940,8 @@
0
2
2
+ 2
+ 2
@@ -1901,6 +1971,7 @@
11
+ 1
@@ -1912,6 +1983,7 @@
2
2
2
+ 2
diff --git a/FreeRTOS/Demo/CORTEX_M4_ATSAM4E_Atmel_Studio/RTOSDemo.atsuo b/FreeRTOS/Demo/CORTEX_M4_ATSAM4E_Atmel_Studio/RTOSDemo.atsuo
index 4cebd75297..08cf7bfc19 100644
Binary files a/FreeRTOS/Demo/CORTEX_M4_ATSAM4E_Atmel_Studio/RTOSDemo.atsuo and b/FreeRTOS/Demo/CORTEX_M4_ATSAM4E_Atmel_Studio/RTOSDemo.atsuo differ
diff --git a/FreeRTOS/Demo/CORTEX_M4_ATSAM4E_Atmel_Studio/RTOSDemo.cproj b/FreeRTOS/Demo/CORTEX_M4_ATSAM4E_Atmel_Studio/RTOSDemo.cproj
index b917a2836c..e3941f3a68 100644
--- a/FreeRTOS/Demo/CORTEX_M4_ATSAM4E_Atmel_Studio/RTOSDemo.cproj
+++ b/FreeRTOS/Demo/CORTEX_M4_ATSAM4E_Atmel_Studio/RTOSDemo.cproj
@@ -15,8 +15,9 @@
-
+
+
@@ -173,6 +174,8 @@
+
+
@@ -207,12 +210,12 @@
false
- 12000000
+ 7020000
SWD
com.atmel.avrdbg.tool.samice
- 000158000789
+ 158000789
J-Link
SWD
@@ -261,6 +264,7 @@
../src/ASF/sam/components/display/aat31xx
../src/ASF/sam/components/display/ili93xx
../src/ASF/sam/drivers/ebi/smc
+ ../src/ASF/sam/drivers/tc
Optimize for size (-Os)
@@ -310,6 +314,7 @@
../src/ASF/sam/components/display/aat31xx
../src/ASF/sam/components/display/ili93xx
../src/ASF/sam/drivers/ebi/smc
+ ../src/ASF/sam/drivers/tc
@@ -372,6 +377,7 @@
../src/ASF/sam/components/display/ili93xx
../src/ASF/sam/drivers/ebi/smc
../../../../FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/EchoClients
+ ../src/ASF/sam/drivers/tc
-fdata-sections
@@ -391,6 +397,7 @@
True
+
-Wl,--entry=Reset_Handler -Wl,--cref -mthumb -T../src/ASF/sam/utils/linker_scripts/sam4e/sam4e16e/gcc/flash.ld
Default (-g)
-DARM_MATH_CM4=true -DBOARD=SAM4E_EK -D__SAM4E16E__ -Dprintf=iprintf
@@ -422,6 +429,7 @@
../src/ASF/sam/components/display/aat31xx
../src/ASF/sam/components/display/ili93xx
../src/ASF/sam/drivers/ebi/smc
+ ../src/ASF/sam/drivers/tc
Default (-Wa,-g)
@@ -525,6 +533,14 @@
compile
src\Common Demo Tasks\GenQTest.c
+
+ compile
+ src\Common Demo Tasks\IntQueue.c
+
+
+ compile
+ src\Common Demo Tasks\IntSemTest.c
+
compile
src\Common Demo Tasks\QPeek.c
@@ -545,6 +561,14 @@
compile
src\Common Demo Tasks\semtest.c
+
+ compile
+ src\Common Demo Tasks\TaskNotify.c
+
+
+ compile
+ src\Common Demo Tasks\TimerDemo.c
+
compile
@@ -569,6 +593,12 @@
compile
+
+ compile
+
+
+ compile
+
compile
@@ -590,6 +620,9 @@
compile
+
+ compile
+
compile
@@ -1102,6 +1135,7 @@
+
diff --git a/FreeRTOS/Demo/CORTEX_M4_ATSAM4E_Atmel_Studio/src/ASF/sam/drivers/tc/tc.c b/FreeRTOS/Demo/CORTEX_M4_ATSAM4E_Atmel_Studio/src/ASF/sam/drivers/tc/tc.c
new file mode 100644
index 0000000000..dd95a52eac
--- /dev/null
+++ b/FreeRTOS/Demo/CORTEX_M4_ATSAM4E_Atmel_Studio/src/ASF/sam/drivers/tc/tc.c
@@ -0,0 +1,596 @@
+/**
+ * \file
+ *
+ * \brief Timer Counter (TC) driver for SAM.
+ *
+ * Copyright (c) 2011-2013 Atmel Corporation. All rights reserved.
+ *
+ * \asf_license_start
+ *
+ * \page License
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The name of Atmel may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * 4. This software may only be redistributed and used in connection with an
+ * Atmel microcontroller product.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * \asf_license_stop
+ *
+ */
+
+#include
+#include "tc.h"
+
+/// @cond 0
+/**INDENT-OFF**/
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**INDENT-ON**/
+/// @endcond
+
+#define TC_WPMR_WPKEY_VALUE TC_WPMR_WPKEY((uint32_t)0x54494D)
+
+/**
+ * \defgroup sam_drivers_tc_group Timer Counter (TC)
+ *
+ * The Timer Counter (TC) includes three identical 32-bit Timer Counter
+ * channels. Each channel can be independently programmed to perform a wide
+ * range of functions including frequency measurement, event counting,
+ * interval measurement, pulse generation, delay timing and pulse width
+ * modulation.
+ *
+ * @{
+ */
+
+/**
+ * \brief Configure TC for timer, waveform generation or capture.
+ *
+ * \param p_tc Pointer to a TC instance.
+ * \param ul_channel Channel to configure.
+ * \param ul_mode Control mode register value to set.
+ *
+ * \attention If the TC is configured for waveform generation, the external
+ * event selection (EEVT) should only be set to \c TC_CMR_EEVT_TIOB or the
+ * equivalent value \c 0 if it really is the intention to use TIOB as an
+ * external event trigger.\n
+ * This is because the setting forces TIOB to be an input even if the
+ * external event trigger has not been enabled with \c TC_CMR_ENETRG, and
+ * thus prevents normal operation of TIOB.
+ */
+void tc_init(Tc *p_tc, uint32_t ul_channel, uint32_t ul_mode)
+{
+ TcChannel *tc_channel;
+
+ Assert(ul_channel <
+ (sizeof(p_tc->TC_CHANNEL) / sizeof(p_tc->TC_CHANNEL[0])));
+ tc_channel = p_tc->TC_CHANNEL + ul_channel;
+
+ /* Disable TC clock. */
+ tc_channel->TC_CCR = TC_CCR_CLKDIS;
+
+ /* Disable interrupts. */
+ tc_channel->TC_IDR = 0xFFFFFFFF;
+
+ /* Clear status register. */
+ tc_channel->TC_SR;
+
+ /* Set mode. */
+ tc_channel->TC_CMR = ul_mode;
+}
+
+/**
+ * \brief Asserts a SYNC signal to generate a software trigger to
+ * all channels.
+ *
+ * \param p_tc Pointer to a TC instance.
+ *
+ */
+void tc_sync_trigger(Tc *p_tc)
+{
+ p_tc->TC_BCR = TC_BCR_SYNC;
+}
+
+/**
+ * \brief Configure TC Block mode.
+ * \note tc_init() must be called first.
+ *
+ * \param p_tc Pointer to a TC instance.
+ * \param ul_blockmode Block mode register value to set.
+ *
+ */
+void tc_set_block_mode(Tc *p_tc, uint32_t ul_blockmode)
+{
+ p_tc->TC_BMR = ul_blockmode;
+}
+
+#if (!SAM3U)
+
+/**
+ * \brief Configure TC for 2-bit Gray Counter for Stepper Motor.
+ * \note tc_init() must be called first.
+ *
+ * \param p_tc Pointer to a TC instance.
+ * \param ul_channel Channel to configure.
+ * \param ul_steppermode Stepper motor mode register value to set.
+ *
+ * \return 0 for OK.
+ */
+uint32_t tc_init_2bit_gray(Tc *p_tc, uint32_t ul_channel,
+ uint32_t ul_steppermode)
+{
+ Assert(ul_channel <
+ (sizeof(p_tc->TC_CHANNEL) / sizeof(p_tc->TC_CHANNEL[0])));
+
+ p_tc->TC_CHANNEL[ul_channel].TC_SMMR = ul_steppermode;
+ return 0;
+}
+
+#endif
+
+/**
+ * \brief Start TC clock counter on the selected channel.
+ *
+ * \param p_tc Pointer to a TC instance.
+ * \param ul_channel Channel to configure.
+ */
+void tc_start(Tc *p_tc, uint32_t ul_channel)
+{
+ Assert(ul_channel <
+ (sizeof(p_tc->TC_CHANNEL) / sizeof(p_tc->TC_CHANNEL[0])));
+
+ p_tc->TC_CHANNEL[ul_channel].TC_CCR = TC_CCR_CLKEN | TC_CCR_SWTRG;
+}
+
+/**
+ * \brief Stop TC clock counter on the selected channel.
+ *
+ * \param p_tc Pointer to a TC instance.
+ * \param ul_channel Channel to configure.
+ */
+void tc_stop(Tc *p_tc, uint32_t ul_channel)
+{
+ Assert(ul_channel <
+ (sizeof(p_tc->TC_CHANNEL) / sizeof(p_tc->TC_CHANNEL[0])));
+
+ p_tc->TC_CHANNEL[ul_channel].TC_CCR = TC_CCR_CLKDIS;
+}
+
+/**
+ * \brief Read counter value on the selected channel.
+ *
+ * \param p_tc Pointer to a TC instance.
+ * \param ul_channel Channel to configure.
+ *
+ * \return Counter value.
+ */
+uint32_t tc_read_cv(Tc *p_tc, uint32_t ul_channel)
+{
+ Assert(ul_channel <
+ (sizeof(p_tc->TC_CHANNEL) / sizeof(p_tc->TC_CHANNEL[0])));
+
+ return p_tc->TC_CHANNEL[ul_channel].TC_CV;
+}
+
+/**
+ * \brief Read RA TC counter on the selected channel.
+ *
+ * \param p_tc Pointer to a TC instance.
+ * \param ul_channel Channel to configure.
+ *
+ * \return RA value.
+ */
+uint32_t tc_read_ra(Tc *p_tc, uint32_t ul_channel)
+{
+ Assert(ul_channel <
+ (sizeof(p_tc->TC_CHANNEL) / sizeof(p_tc->TC_CHANNEL[0])));
+
+ return p_tc->TC_CHANNEL[ul_channel].TC_RA;
+}
+
+/**
+ * \brief Read RB TC counter on the selected channel.
+ *
+ * \param p_tc Pointer to a TC instance.
+ * \param ul_channel Channel to configure.
+ *
+ * \return RB value.
+ */
+uint32_t tc_read_rb(Tc *p_tc, uint32_t ul_channel)
+{
+ Assert(ul_channel <
+ (sizeof(p_tc->TC_CHANNEL) / sizeof(p_tc->TC_CHANNEL[0])));
+
+ return p_tc->TC_CHANNEL[ul_channel].TC_RB;
+}
+
+/**
+ * \brief Read RC TC counter on the selected channel.
+ *
+ * \param p_tc Pointer to a TC instance.
+ * \param ul_channel Channel to configure.
+ *
+ * \return RC value.
+ */
+uint32_t tc_read_rc(Tc *p_tc, uint32_t ul_channel)
+{
+ Assert(ul_channel <
+ (sizeof(p_tc->TC_CHANNEL) / sizeof(p_tc->TC_CHANNEL[0])));
+
+ return p_tc->TC_CHANNEL[ul_channel].TC_RC;
+}
+
+/**
+ * \brief Write RA TC counter on the selected channel.
+ *
+ * \param p_tc Pointer to a TC instance.
+ * \param ul_channel Channel to configure.
+ * \param ul_value Value to set in register.
+ */
+void tc_write_ra(Tc *p_tc, uint32_t ul_channel,
+ uint32_t ul_value)
+{
+ Assert(ul_channel <
+ (sizeof(p_tc->TC_CHANNEL) / sizeof(p_tc->TC_CHANNEL[0])));
+
+ p_tc->TC_CHANNEL[ul_channel].TC_RA = ul_value;
+}
+
+/**
+ * \brief Write RB TC counter on the selected channel.
+ *
+ * \param p_tc Pointer to a TC instance.
+ * \param ul_channel Channel to configure.
+ * \param ul_value Value to set in register.
+ */
+void tc_write_rb(Tc *p_tc, uint32_t ul_channel,
+ uint32_t ul_value)
+{
+ Assert(ul_channel <
+ (sizeof(p_tc->TC_CHANNEL) / sizeof(p_tc->TC_CHANNEL[0])));
+
+ p_tc->TC_CHANNEL[ul_channel].TC_RB = ul_value;
+}
+
+/**
+ * \brief Write RC TC counter on the selected channel.
+ *
+ * \param p_tc Pointer to a TC instance.
+ * \param ul_channel Channel to configure.
+ * \param ul_value Value to set in register.
+ */
+void tc_write_rc(Tc *p_tc, uint32_t ul_channel,
+ uint32_t ul_value)
+{
+ Assert(ul_channel <
+ (sizeof(p_tc->TC_CHANNEL) / sizeof(p_tc->TC_CHANNEL[0])));
+
+ p_tc->TC_CHANNEL[ul_channel].TC_RC = ul_value;
+}
+
+/**
+ * \brief Enable TC interrupts on the selected channel.
+ *
+ * \param p_tc Pointer to a TC instance.
+ * \param ul_channel Channel to configure.
+ * \param ul_sources Interrupt sources bit map.
+ */
+void tc_enable_interrupt(Tc *p_tc, uint32_t ul_channel,
+ uint32_t ul_sources)
+{
+ TcChannel *tc_channel;
+
+ Assert(ul_channel <
+ (sizeof(p_tc->TC_CHANNEL) / sizeof(p_tc->TC_CHANNEL[0])));
+ tc_channel = p_tc->TC_CHANNEL + ul_channel;
+ tc_channel->TC_IER = ul_sources;
+}
+
+/**
+ * \brief Disable TC interrupts on the selected channel.
+ *
+ * \param p_tc Pointer to a TC instance.
+ * \param ul_channel Channel to configure.
+ * \param ul_sources Interrupt sources bit map.
+ */
+void tc_disable_interrupt(Tc *p_tc, uint32_t ul_channel,
+ uint32_t ul_sources)
+{
+ TcChannel *tc_channel;
+
+ Assert(ul_channel <
+ (sizeof(p_tc->TC_CHANNEL) / sizeof(p_tc->TC_CHANNEL[0])));
+ tc_channel = p_tc->TC_CHANNEL + ul_channel;
+ tc_channel->TC_IDR = ul_sources;
+}
+
+/**
+ * \brief Read TC interrupt mask on the selected channel.
+ *
+ * \param p_tc Pointer to a TC instance.
+ * \param ul_channel Channel to configure.
+ *
+ * \return The interrupt mask value.
+ */
+uint32_t tc_get_interrupt_mask(Tc *p_tc, uint32_t ul_channel)
+{
+ TcChannel *tc_channel;
+
+ Assert(ul_channel <
+ (sizeof(p_tc->TC_CHANNEL) / sizeof(p_tc->TC_CHANNEL[0])));
+ tc_channel = p_tc->TC_CHANNEL + ul_channel;
+ return tc_channel->TC_IMR;
+}
+
+/**
+ * \brief Get current status on the selected channel.
+ *
+ * \param p_tc Pointer to a TC instance.
+ * \param ul_channel Channel to configure.
+ *
+ * \return The current TC status.
+ */
+uint32_t tc_get_status(Tc *p_tc, uint32_t ul_channel)
+{
+ TcChannel *tc_channel;
+
+ Assert(ul_channel <
+ (sizeof(p_tc->TC_CHANNEL) / sizeof(p_tc->TC_CHANNEL[0])));
+ tc_channel = p_tc->TC_CHANNEL + ul_channel;
+ return tc_channel->TC_SR;
+}
+
+/* TC divisor used to find the lowest acceptable timer frequency */
+#define TC_DIV_FACTOR 65536
+
+#if (!SAM4L)
+
+#ifndef FREQ_SLOW_CLOCK_EXT
+#define FREQ_SLOW_CLOCK_EXT 32768 /* External slow clock frequency (hz) */
+#endif
+
+/**
+ * \brief Find the best MCK divisor.
+ *
+ * Finds the best MCK divisor given the timer frequency and MCK. The result
+ * is guaranteed to satisfy the following equation:
+ * \code
+ * (MCK / (DIV * 65536)) <= freq <= (MCK / DIV)
+ * \endcode
+ * with DIV being the lowest possible value,
+ * to maximize timing adjust resolution.
+ *
+ * \param ul_freq Desired timer frequency.
+ * \param ul_mck Master clock frequency.
+ * \param p_uldiv Divisor value.
+ * \param p_ultcclks TCCLKS field value for divisor.
+ * \param ul_boardmck Board clock frequency.
+ *
+ * \return 1 if a proper divisor has been found, otherwise 0.
+ */
+uint32_t tc_find_mck_divisor(uint32_t ul_freq, uint32_t ul_mck,
+ uint32_t *p_uldiv, uint32_t *p_ultcclks, uint32_t ul_boardmck)
+{
+ const uint32_t divisors[5] = { 2, 8, 32, 128,
+ ul_boardmck / FREQ_SLOW_CLOCK_EXT };
+ uint32_t ul_index;
+ uint32_t ul_high, ul_low;
+
+ /* Satisfy frequency bound. */
+ for (ul_index = 0;
+ ul_index < (sizeof(divisors) / sizeof(divisors[0]));
+ ul_index++) {
+ ul_high = ul_mck / divisors[ul_index];
+ ul_low = ul_high / TC_DIV_FACTOR;
+ if (ul_freq > ul_high) {
+ return 0;
+ } else if (ul_freq >= ul_low) {
+ break;
+ }
+ }
+ if (ul_index >= (sizeof(divisors) / sizeof(divisors[0]))) {
+ return 0;
+ }
+
+ /* Store results. */
+ if (p_uldiv) {
+ *p_uldiv = divisors[ul_index];
+ }
+
+ if (p_ultcclks) {
+ *p_ultcclks = ul_index;
+ }
+
+ return 1;
+}
+
+#endif
+
+#if (SAM4L)
+/**
+ * \brief Find the best PBA clock divisor.
+ *
+ * Finds the best divisor given the timer frequency and PBA clock. The result
+ * is guaranteed to satisfy the following equation:
+ * \code
+ * (ul_pbaclk / (2* DIV * 65536)) <= freq <= (ul_pbaclk / (2* DIV))
+ * \endcode
+ * with DIV being the lowest possible value,
+ * to maximize timing adjust resolution.
+ *
+ * \param ul_freq Desired timer frequency.
+ * \param ul_mck PBA clock frequency.
+ * \param p_uldiv Divisor value.
+ * \param p_ultcclks TCCLKS field value for divisor.
+ * \param ul_boardmck useless here.
+ *
+ * \return 1 if a proper divisor has been found, otherwise 0.
+ */
+uint32_t tc_find_mck_divisor(uint32_t ul_freq, uint32_t ul_mck,
+ uint32_t *p_uldiv, uint32_t *p_ultcclks, uint32_t ul_boardmck)
+{
+ const uint32_t divisors[5] = { 0, 2, 8, 32, 128};
+ uint32_t ul_index;
+ uint32_t ul_high, ul_low;
+
+ UNUSED(ul_boardmck);
+
+ /* Satisfy frequency bound. */
+ for (ul_index = 1;
+ ul_index < (sizeof(divisors) / sizeof(divisors[0]));
+ ul_index++) {
+ ul_high = ul_mck / divisors[ul_index];
+ ul_low = ul_high / TC_DIV_FACTOR;
+ if (ul_freq > ul_high) {
+ return 0;
+ } else if (ul_freq >= ul_low) {
+ break;
+ }
+ }
+ if (ul_index >= (sizeof(divisors) / sizeof(divisors[0]))) {
+ return 0;
+ }
+
+ /* Store results. */
+ if (p_uldiv) {
+ *p_uldiv = divisors[ul_index];
+ }
+
+ if (p_ultcclks) {
+ *p_ultcclks = ul_index;
+ }
+
+ return 1;
+}
+
+#endif
+
+#if (!SAM4L)
+
+/**
+ * \brief Enable TC QDEC interrupts.
+ *
+ * \param p_tc Pointer to a TC instance.
+ * \param ul_sources Interrupts to be enabled.
+ */
+void tc_enable_qdec_interrupt(Tc *p_tc, uint32_t ul_sources)
+{
+ p_tc->TC_QIER = ul_sources;
+}
+
+/**
+ * \brief Disable TC QDEC interrupts.
+ *
+ * \param p_tc Pointer to a TC instance.
+ * \param ul_sources Interrupts to be disabled.
+ */
+void tc_disable_qdec_interrupt(Tc *p_tc, uint32_t ul_sources)
+{
+ p_tc->TC_QIDR = ul_sources;
+}
+
+/**
+ * \brief Read TC QDEC interrupt mask.
+ *
+ * \param p_tc Pointer to a TC instance.
+ *
+ * \return The interrupt mask value.
+ */
+uint32_t tc_get_qdec_interrupt_mask(Tc *p_tc)
+{
+ return p_tc->TC_QIMR;
+}
+
+/**
+ * \brief Get current QDEC status.
+ *
+ * \param p_tc Pointer to a TC instance.
+ *
+ * \return The current TC status.
+ */
+uint32_t tc_get_qdec_interrupt_status(Tc *p_tc)
+{
+ return p_tc->TC_QISR;
+}
+
+#endif
+
+#if (!SAM3U)
+
+/**
+ * \brief Enable or disable write protection of TC registers.
+ *
+ * \param p_tc Pointer to a TC instance.
+ * \param ul_enable 1 to enable, 0 to disable.
+ */
+void tc_set_writeprotect(Tc *p_tc, uint32_t ul_enable)
+{
+ if (ul_enable) {
+ p_tc->TC_WPMR = TC_WPMR_WPKEY_VALUE | TC_WPMR_WPEN;
+ } else {
+ p_tc->TC_WPMR = TC_WPMR_WPKEY_VALUE;
+ }
+}
+
+#endif
+
+#if SAM4L
+
+/**
+ * \brief Indicate features.
+ *
+ * \param p_tc Pointer to a TC instance.
+ *
+ * \return TC_FEATURES value.
+ */
+uint32_t tc_get_feature(Tc *p_tc)
+{
+ return p_tc->TC_FEATURES;
+}
+
+/**
+ * \brief Indicate version.
+ *
+ * \param p_tc Pointer to a TC instance.
+ *
+ * \return TC_VERSION value.
+ */
+uint32_t tc_get_version(Tc *p_tc)
+{
+ return p_tc->TC_VERSION;
+}
+
+#endif
+
+//@}
+
+/// @cond 0
+/**INDENT-OFF**/
+#ifdef __cplusplus
+}
+#endif
+/**INDENT-ON**/
+/// @endcond
diff --git a/FreeRTOS/Demo/CORTEX_M4_ATSAM4E_Atmel_Studio/src/ASF/sam/drivers/tc/tc.h b/FreeRTOS/Demo/CORTEX_M4_ATSAM4E_Atmel_Studio/src/ASF/sam/drivers/tc/tc.h
new file mode 100644
index 0000000000..5dd1690190
--- /dev/null
+++ b/FreeRTOS/Demo/CORTEX_M4_ATSAM4E_Atmel_Studio/src/ASF/sam/drivers/tc/tc.h
@@ -0,0 +1,114 @@
+/**
+ * \file
+ *
+ * \brief Timer Counter (TC) driver for SAM.
+ *
+ * Copyright (c) 2011-2013 Atmel Corporation. All rights reserved.
+ *
+ * \asf_license_start
+ *
+ * \page License
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The name of Atmel may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * 4. This software may only be redistributed and used in connection with an
+ * Atmel microcontroller product.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * \asf_license_stop
+ *
+ */
+
+#ifndef TC_H_INCLUDED
+#define TC_H_INCLUDED
+
+#include "compiler.h"
+
+/// @cond 0
+/**INDENT-OFF**/
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**INDENT-ON**/
+/// @endcond
+
+void tc_init(Tc *p_tc, uint32_t ul_Channel, uint32_t ul_Mode);
+void tc_sync_trigger(Tc *p_tc);
+void tc_set_block_mode(Tc *p_tc, uint32_t ul_blockmode);
+
+#if (!SAM3U)
+uint32_t tc_init_2bit_gray(Tc *p_tc, uint32_t ul_channel,
+ uint32_t ul_steppermode);
+#endif
+
+void tc_start(Tc *p_tc, uint32_t ul_channel);
+void tc_stop(Tc *p_tc, uint32_t ul_channel);
+
+uint32_t tc_read_cv(Tc *p_tc, uint32_t ul_channel);
+uint32_t tc_read_ra(Tc *p_tc, uint32_t ul_channel);
+uint32_t tc_read_rb(Tc *p_tc, uint32_t ul_channel);
+uint32_t tc_read_rc(Tc *p_tc, uint32_t ul_channel);
+
+void tc_write_ra(Tc *p_tc, uint32_t ul_channel,
+ uint32_t ul_value);
+void tc_write_rb(Tc *p_tc, uint32_t ul_channel,
+ uint32_t ul_value);
+void tc_write_rc(Tc *p_tc, uint32_t ul_channel,
+ uint32_t ul_value);
+
+uint32_t tc_find_mck_divisor(uint32_t ul_freq, uint32_t ul_mck,
+ uint32_t *p_uldiv, uint32_t *ul_tcclks, uint32_t ul_boardmck);
+void tc_enable_interrupt(Tc *p_tc, uint32_t ul_channel,
+ uint32_t ul_sources);
+void tc_disable_interrupt(Tc *p_tc, uint32_t ul_channel,
+ uint32_t ul_sources);
+uint32_t tc_get_interrupt_mask(Tc *p_tc, uint32_t ul_channel);
+uint32_t tc_get_status(Tc *p_tc, uint32_t ul_channel);
+#if (!SAM4L)
+void tc_enable_qdec_interrupt(Tc *p_tc, uint32_t ul_sources);
+void tc_disable_qdec_interrupt(Tc *p_tc, uint32_t ul_sources);
+uint32_t tc_get_qdec_interrupt_mask(Tc *p_tc);
+uint32_t tc_get_qdec_interrupt_status(Tc *p_tc);
+#endif
+
+#if (!SAM3U)
+void tc_set_writeprotect(Tc *p_tc, uint32_t ul_enable);
+#endif
+
+#if SAM4L
+uint32_t tc_get_feature(Tc *p_tc);
+uint32_t tc_get_version(Tc *p_tc);
+
+#endif
+
+/// @cond 0
+/**INDENT-OFF**/
+#ifdef __cplusplus
+}
+#endif
+/**INDENT-ON**/
+/// @endcond
+
+#endif /* TC_H_INCLUDED */
diff --git a/FreeRTOS/Demo/CORTEX_M4_ATSAM4E_Atmel_Studio/src/IntQueueTimer.c b/FreeRTOS/Demo/CORTEX_M4_ATSAM4E_Atmel_Studio/src/IntQueueTimer.c
new file mode 100644
index 0000000000..079cd1e6bb
--- /dev/null
+++ b/FreeRTOS/Demo/CORTEX_M4_ATSAM4E_Atmel_Studio/src/IntQueueTimer.c
@@ -0,0 +1,198 @@
+/*
+ FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd.
+ All rights reserved
+
+ VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
+
+ ***************************************************************************
+ * *
+ * FreeRTOS provides completely free yet professionally developed, *
+ * robust, strictly quality controlled, supported, and cross *
+ * platform software that has become a de facto standard. *
+ * *
+ * Help yourself get started quickly and support the FreeRTOS *
+ * project by purchasing a FreeRTOS tutorial book, reference *
+ * manual, or both from: http://www.FreeRTOS.org/Documentation *
+ * *
+ * Thank you! *
+ * *
+ ***************************************************************************
+
+ This file is part of the FreeRTOS distribution.
+
+ FreeRTOS is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License (version 2) as published by the
+ Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
+
+ >>! NOTE: The modification to the GPL is included to allow you to !<<
+ >>! distribute a combined work that includes FreeRTOS without being !<<
+ >>! obliged to provide the source code for proprietary components !<<
+ >>! outside of the FreeRTOS kernel. !<<
+
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. Full license text is available from the following
+ link: http://www.freertos.org/a00114.html
+
+ 1 tab == 4 spaces!
+
+ ***************************************************************************
+ * *
+ * Having a problem? Start by reading the FAQ "My application does *
+ * not run, what could be wrong?" *
+ * *
+ * http://www.FreeRTOS.org/FAQHelp.html *
+ * *
+ ***************************************************************************
+
+ http://www.FreeRTOS.org - Documentation, books, training, latest versions,
+ license and Real Time Engineers Ltd. contact details.
+
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
+ including FreeRTOS+Trace - an indispensable productivity tool, a DOS
+ compatible FAT file system, and our tiny thread aware UDP/IP stack.
+
+ http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
+ Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
+ licenses offer ticketed support, indemnification and middleware.
+
+ http://www.SafeRTOS.com - High Integrity Systems also provide a safety
+ engineered and independently SIL3 certified version for use in safety and
+ mission critical applications that require provable dependability.
+
+ 1 tab == 4 spaces!
+*/
+
+/*
+ * Provides the two timers sources for the standard demo IntQueue test. Also
+ * includes a high frequency timer to maximise the interrupt nesting achieved.
+ */
+
+/* Standard includes. */
+#include
+
+/* Scheduler includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+
+/* Demo includes. */
+#include "IntQueueTimer.h"
+#include "IntQueue.h"
+
+/* System includes. */
+#include "board.h"
+#include "asf.h"
+
+/* The frequencies at which the first two timers expire are slightly offset to
+ensure they don't remain synchronised. The frequency of the highest priority
+interrupt is 20 times faster so really hammers the interrupt entry and exit
+code. */
+#define tmrTIMER_0_FREQUENCY ( 2000UL )
+#define tmrTIMER_1_FREQUENCY ( 1003UL )
+#define tmrTIMER_2_FREQUENCY ( 20000UL )
+
+/* Priorities used by the timer interrupts - these are set differently to make
+nesting likely/common. The high frequency timer operates above the max
+system call interrupt priority, but does not use the RTOS API. */
+#define tmrTIMER_0_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY )
+#define tmrTIMER_1_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 1 )
+#define tmrTIMER_2_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY - 1 )
+
+/* The channels used within the TC0 timer. */
+#define tmrTIMER_0_CHANNEL ( 0 )
+#define tmrTIMER_1_CHANNEL ( 1 )
+#define tmrTIMER_2_CHANNEL ( 2 )
+
+/* TC register bit specifics. */
+#define tmrTRIGGER_ON_RC ( 1UL << 4UL )
+#define trmDIVIDER ( 128 )
+
+/*-----------------------------------------------------------*/
+
+/* Handers for the timer interrupts. */
+void TC0_Handler( void );
+void TC1_Handler( void );
+void TC2_Handler( void );
+
+/*-----------------------------------------------------------*/
+
+/* Incremented by the high frequency timer, which operates above the max
+syscall interrupt priority. This is just for inspection. */
+volatile uint32_t ulHighFrequencyTimerInterrupts = 0;
+
+/*-----------------------------------------------------------*/
+
+void vInitialiseTimerForIntQueueTest( void )
+{
+uint32_t ulInputFrequency;
+
+ /* Calculate the frequency of the clock that feeds the TC. */
+ ulInputFrequency = configCPU_CLOCK_HZ;
+ ulInputFrequency /= trmDIVIDER;
+
+ /* Three channels are used - two that run at or under
+ configMAX_SYSCALL_INTERRUPT_PRIORITY, and one that runs over
+ configMAX_SYSCALL_INTERRUPT_PRIORITY. */
+ sysclk_enable_peripheral_clock( ID_TC0 );
+ sysclk_enable_peripheral_clock( ID_TC1 );
+ sysclk_enable_peripheral_clock( ID_TC2 );
+
+ /* Init TC channels to waveform mode - up mode clean on RC match. */
+ tc_init( TC0, tmrTIMER_0_CHANNEL, TC_CMR_TCCLKS_TIMER_CLOCK4 | TC_CMR_WAVE | TC_CMR_ACPC_CLEAR | TC_CMR_CPCTRG );
+ tc_init( TC0, tmrTIMER_1_CHANNEL, TC_CMR_TCCLKS_TIMER_CLOCK4 | TC_CMR_WAVE | TC_CMR_ACPC_CLEAR | TC_CMR_CPCTRG );
+ tc_init( TC0, tmrTIMER_2_CHANNEL, TC_CMR_TCCLKS_TIMER_CLOCK4 | TC_CMR_WAVE | TC_CMR_ACPC_CLEAR | TC_CMR_CPCTRG );
+
+ tc_enable_interrupt( TC0, tmrTIMER_0_CHANNEL, tmrTRIGGER_ON_RC );
+ tc_enable_interrupt( TC0, tmrTIMER_1_CHANNEL, tmrTRIGGER_ON_RC );
+ tc_enable_interrupt( TC0, tmrTIMER_2_CHANNEL, tmrTRIGGER_ON_RC );
+
+ tc_write_rc( TC0, tmrTIMER_0_CHANNEL, ( ulInputFrequency / tmrTIMER_0_FREQUENCY ) );
+ tc_write_rc( TC0, tmrTIMER_1_CHANNEL, ( ulInputFrequency / tmrTIMER_1_FREQUENCY ) );
+ tc_write_rc( TC0, tmrTIMER_2_CHANNEL, ( ulInputFrequency / tmrTIMER_2_FREQUENCY ) );
+
+ NVIC_SetPriority( TC0_IRQn, tmrTIMER_0_PRIORITY );
+ NVIC_SetPriority( TC1_IRQn, tmrTIMER_1_PRIORITY );
+ NVIC_SetPriority( TC2_IRQn, tmrTIMER_2_PRIORITY );
+
+ NVIC_EnableIRQ( TC0_IRQn );
+ NVIC_EnableIRQ( TC1_IRQn );
+ NVIC_EnableIRQ( TC2_IRQn );
+
+ tc_start( TC0, tmrTIMER_0_CHANNEL );
+ tc_start( TC0, tmrTIMER_1_CHANNEL );
+ tc_start( TC0, tmrTIMER_2_CHANNEL );
+}
+/*-----------------------------------------------------------*/
+
+void TC0_Handler( void )
+{
+ /* Handler for the first timer in the IntQueue test. Was the interrupt
+ caused by a compare on RC? */
+ if( ( tc_get_status( TC0, tmrTIMER_0_CHANNEL ) & ~TC_SR_CPCS ) != 0 )
+ {
+ portYIELD_FROM_ISR( xFirstTimerHandler() );
+ }
+}
+/*-----------------------------------------------------------*/
+
+void TC1_Handler( void )
+{
+ /* Handler for the second timer in the IntQueue test. Was the interrupt
+ caused by a compare on RC? */
+ if( ( tc_get_status( TC0, tmrTIMER_1_CHANNEL ) & ~TC_SR_CPCS ) != 0 )
+ {
+ portYIELD_FROM_ISR( xSecondTimerHandler() );
+ }
+}
+/*-----------------------------------------------------------*/
+
+void TC2_Handler( void )
+{
+ /* Handler for the high frequency timer that does nothing but increment a
+ variable to give an indication that it is running. Was the interrupt caused
+ by a compare on RC? */
+ if( ( tc_get_status( TC0, tmrTIMER_2_CHANNEL ) & ~TC_SR_CPCS ) != 0 )
+ {
+ ulHighFrequencyTimerInterrupts++;
+ }
+}
diff --git a/FreeRTOS/Demo/CORTEX_M4_ATSAM4E_Atmel_Studio/src/IntQueueTimer.h b/FreeRTOS/Demo/CORTEX_M4_ATSAM4E_Atmel_Studio/src/IntQueueTimer.h
new file mode 100644
index 0000000000..0afe32ac33
--- /dev/null
+++ b/FreeRTOS/Demo/CORTEX_M4_ATSAM4E_Atmel_Studio/src/IntQueueTimer.h
@@ -0,0 +1,74 @@
+/*
+ FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd.
+ All rights reserved
+
+ VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
+
+ ***************************************************************************
+ * *
+ * FreeRTOS provides completely free yet professionally developed, *
+ * robust, strictly quality controlled, supported, and cross *
+ * platform software that has become a de facto standard. *
+ * *
+ * Help yourself get started quickly and support the FreeRTOS *
+ * project by purchasing a FreeRTOS tutorial book, reference *
+ * manual, or both from: http://www.FreeRTOS.org/Documentation *
+ * *
+ * Thank you! *
+ * *
+ ***************************************************************************
+
+ This file is part of the FreeRTOS distribution.
+
+ FreeRTOS is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License (version 2) as published by the
+ Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
+
+ >>! NOTE: The modification to the GPL is included to allow you to !<<
+ >>! distribute a combined work that includes FreeRTOS without being !<<
+ >>! obliged to provide the source code for proprietary components !<<
+ >>! outside of the FreeRTOS kernel. !<<
+
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. Full license text is available from the following
+ link: http://www.freertos.org/a00114.html
+
+ 1 tab == 4 spaces!
+
+ ***************************************************************************
+ * *
+ * Having a problem? Start by reading the FAQ "My application does *
+ * not run, what could be wrong?" *
+ * *
+ * http://www.FreeRTOS.org/FAQHelp.html *
+ * *
+ ***************************************************************************
+
+ http://www.FreeRTOS.org - Documentation, books, training, latest versions,
+ license and Real Time Engineers Ltd. contact details.
+
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
+ including FreeRTOS+Trace - an indispensable productivity tool, a DOS
+ compatible FAT file system, and our tiny thread aware UDP/IP stack.
+
+ http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
+ Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
+ licenses offer ticketed support, indemnification and middleware.
+
+ http://www.SafeRTOS.com - High Integrity Systems also provide a safety
+ engineered and independently SIL3 certified version for use in safety and
+ mission critical applications that require provable dependability.
+
+ 1 tab == 4 spaces!
+*/
+
+#ifndef INT_QUEUE_TIMER_H
+#define INT_QUEUE_TIMER_H
+
+void vInitialiseTimerForIntQueueTest( void );
+BaseType_t xTimer0Handler( void );
+BaseType_t xTimer1Handler( void );
+
+#endif
+
diff --git a/FreeRTOS/Demo/CORTEX_M4_ATSAM4E_Atmel_Studio/src/asf.h b/FreeRTOS/Demo/CORTEX_M4_ATSAM4E_Atmel_Studio/src/asf.h
index cbb258fa46..b5036d0221 100644
--- a/FreeRTOS/Demo/CORTEX_M4_ATSAM4E_Atmel_Studio/src/asf.h
+++ b/FreeRTOS/Demo/CORTEX_M4_ATSAM4E_Atmel_Studio/src/asf.h
@@ -101,4 +101,7 @@
// From module: System Clock Control - SAM4E implementation
#include
+// From module: TC - Timer Counter
+#include
+
#endif // ASF_H
diff --git a/FreeRTOS/Demo/CORTEX_M4_ATSAM4E_Atmel_Studio/src/config/FreeRTOSConfig.h b/FreeRTOS/Demo/CORTEX_M4_ATSAM4E_Atmel_Studio/src/config/FreeRTOSConfig.h
index e5a23c4b90..aaf27b3aa2 100644
--- a/FreeRTOS/Demo/CORTEX_M4_ATSAM4E_Atmel_Studio/src/config/FreeRTOSConfig.h
+++ b/FreeRTOS/Demo/CORTEX_M4_ATSAM4E_Atmel_Studio/src/config/FreeRTOSConfig.h
@@ -87,13 +87,13 @@ extern uint32_t SystemCoreClock;
#define configUSE_PREEMPTION 1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
#define configUSE_QUEUE_SETS 1
-#define configUSE_IDLE_HOOK 0
+#define configUSE_IDLE_HOOK 1
#define configUSE_TICK_HOOK 1
#define configCPU_CLOCK_HZ ( SystemCoreClock )
#define configTICK_RATE_HZ ( 1000 )
#define configMAX_PRIORITIES ( 5 )
-#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 130 )
-#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 46 * 1024 ) )
+#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 120 )
+#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 47 * 1024 ) )
#define configMAX_TASK_NAME_LEN ( 10 )
#define configUSE_TRACE_FACILITY 1
#define configUSE_16_BIT_TICKS 0
@@ -132,7 +132,7 @@ FreeRTOS/Source/tasks.c for limitations. */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY ( 2 )
#define configTIMER_QUEUE_LENGTH 5
-#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )
+#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE )
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
@@ -194,17 +194,17 @@ each node on the network has a unique MAC address. */
/* Default IP address configuration. Used in ipconfigUSE_DNS is set to 0, or
ipconfigUSE_DNS is set to 1 but a DNS server cannot be contacted. */
-#define configIP_ADDR0 192
-#define configIP_ADDR1 168
-#define configIP_ADDR2 0
+#define configIP_ADDR0 172
+#define configIP_ADDR1 25
+#define configIP_ADDR2 218
#define configIP_ADDR3 200
/* Default gateway IP address configuration. Used in ipconfigUSE_DNS is set to
0, or ipconfigUSE_DNS is set to 1 but a DNS server cannot be contacted. */
-#define configGATEWAY_ADDR0 192
-#define configGATEWAY_ADDR1 168
-#define configGATEWAY_ADDR2 0
-#define configGATEWAY_ADDR3 1
+#define configGATEWAY_ADDR0 172
+#define configGATEWAY_ADDR1 25
+#define configGATEWAY_ADDR2 218
+#define configGATEWAY_ADDR3 2
/* Default DNS server configuration. OpenDNS addresses are 208.67.222.222 and
208.67.220.220. Used in ipconfigUSE_DNS is set to 0, or ipconfigUSE_DNS is set
@@ -225,10 +225,10 @@ ipconfigUSE_DNS is set to 1 but a DNS server cannot be contacted. */
UDP echo tasks (when mainINCLUDE_ECHO_CLIENT_TASKS is set to 1 in
FreeRTOSConfig.h.
http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Ethernet_Examples/Common_Echo_Clients.shtml */
-#define configECHO_SERVER_ADDR0 192
-#define configECHO_SERVER_ADDR1 168
-#define configECHO_SERVER_ADDR2 0
-#define configECHO_SERVER_ADDR3 2
+#define configECHO_SERVER_ADDR0 172
+#define configECHO_SERVER_ADDR1 25
+#define configECHO_SERVER_ADDR2 218
+#define configECHO_SERVER_ADDR3 100
/* The priority used by the Ethernet MAC driver interrupt. */
diff --git a/FreeRTOS/Demo/CORTEX_M4_ATSAM4E_Atmel_Studio/src/main.c b/FreeRTOS/Demo/CORTEX_M4_ATSAM4E_Atmel_Studio/src/main.c
index 5adaecdbfa..4f3ddcebb6 100644
--- a/FreeRTOS/Demo/CORTEX_M4_ATSAM4E_Atmel_Studio/src/main.c
+++ b/FreeRTOS/Demo/CORTEX_M4_ATSAM4E_Atmel_Studio/src/main.c
@@ -141,6 +141,8 @@ static void prvSetupHardware( void )
void vApplicationMallocFailedHook( void )
{
+static volatile uint32_t ulCount = 0;
+
/* vApplicationMallocFailedHook() will only be called if
configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
function that will get called if a call to pvPortMalloc() fails.
@@ -150,8 +152,12 @@ void vApplicationMallocFailedHook( void )
heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
to query the size of free heap space that remains (although it does not
- provide information on how the remaining heap might be fragmented). */
- vAssertCalled( __LINE__, __FILE__ );
+ provide information on how the remaining heap might be fragmented).
+
+ Just count the number of malloc fails as some failures may occur simply
+ because the network load is very high, resulting in the consumption of a
+ lot of network buffers. */
+ ulCount++;
}
/*-----------------------------------------------------------*/
diff --git a/FreeRTOS/Demo/CORTEX_M4_ATSAM4E_Atmel_Studio/src/main_full.c b/FreeRTOS/Demo/CORTEX_M4_ATSAM4E_Atmel_Studio/src/main_full.c
index f936c97d7a..fc5ef172e0 100644
--- a/FreeRTOS/Demo/CORTEX_M4_ATSAM4E_Atmel_Studio/src/main_full.c
+++ b/FreeRTOS/Demo/CORTEX_M4_ATSAM4E_Atmel_Studio/src/main_full.c
@@ -136,6 +136,10 @@
#include "QueueSet.h"
#include "recmutex.h"
#include "EventGroupsDemo.h"
+#include "TaskNotify.h"
+#include "IntSemTest.h"
+#include "TimerDemo.h"
+#include "IntQueue.h"
/* The period after which the check timer will expire, in ms, provided no errors
have been reported by any of the standard demo tasks. ms are converted to the
@@ -182,7 +186,7 @@ http://www.FreeRTOS.org/udp */
/* UDP command server and echo task parameters. */
#define mainUDP_CLI_TASK_PRIORITY ( tskIDLE_PRIORITY )
#define mainUDP_CLI_PORT_NUMBER ( 5001UL )
-#define mainUDP_CLI_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE * 2U )
+#define mainUDP_CLI_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE + 90 )
#define mainECHO_CLIENT_STACK_SIZE ( configMINIMAL_STACK_SIZE + 30 )
/* Set to 1 to include the UDP echo client tasks in the build. The echo clients
@@ -191,6 +195,9 @@ configECHO_SERVER_ADDR0 to configECHO_SERVER_ADDR3 constants in
FreeRTOSConfig.h. */
#define mainINCLUDE_ECHO_CLIENT_TASKS 1
+/* Used by the standard demo timer tasks. */
+#define mainTIMER_TEST_PERIOD ( 50 )
+
/*-----------------------------------------------------------*/
/*
@@ -225,6 +232,14 @@ extern void vRegisterUDPCLICommands( void );
*/
extern void vInitialiseLCD( void );
+/*
+ * Register check tasks, and the tasks used to write over and check the contents
+ * of the FPU registers, as described at the top of this file. The nature of
+ * these files necessitates that they are written in an assembly file.
+ */
+static void prvRegTest1Task( void *pvParameters ) __attribute__((naked));
+static void prvRegTest2Task( void *pvParameters ) __attribute__((naked));
+
/*-----------------------------------------------------------*/
/* The default IP and MAC address used by the demo. The address configuration
@@ -241,12 +256,16 @@ probably be read from flash memory or an EEPROM. Here it is just hard coded.
Note each node on a network must have a unique MAC address. */
const uint8_t ucMACAddress[ 6 ] = { configMAC_ADDR0, configMAC_ADDR1, configMAC_ADDR2, configMAC_ADDR3, configMAC_ADDR4, configMAC_ADDR5 };
+/* The following two variables are used to communicate the status of the
+register check tasks to the check software timer. If the variables keep
+incrementing, then the register check tasks has not discovered any errors. If
+a variable stops incrementing, then an error has been found. */
+volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL;
+
/*-----------------------------------------------------------*/
int main_full( void )
{
-TimerHandle_t xTimer = NULL;
-
/* Usage instructions on http://www.FreeRTOS.org/Atmel_SAM4E_RTOS_Demo.html */
/* Initialise the LCD and output a bitmap. The IP address will also be
@@ -284,8 +303,7 @@ TimerHandle_t xTimer = NULL;
has completed if DHCP is used). */
FreeRTOS_IPInit( ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress );
- /* Create all the other standard demo tasks. */
- vStartLEDFlashTimers( mainNUM_FLASH_TIMER_LEDS );
+ /* Create all the other standard demo tasks. */
vCreateBlockTimeTasks();
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY );
@@ -296,19 +314,15 @@ TimerHandle_t xTimer = NULL;
vStartQueueSetTasks();
vStartRecursiveMutexTasks();
vStartEventGroupTasks();
+ vStartTaskNotifyTask();
+ vStartInterruptSemaphoreTasks();
+ vStartTimerDemoTask( mainTIMER_TEST_PERIOD );
+ vStartInterruptQueueTasks();
- /* Create the software timer that performs the 'check' functionality, as
- described at the top of this file. */
- xTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */
- ( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */
- pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
- ( void * ) 0, /* The ID is not used, so can be set to anything. */
- prvCheckTimerCallback ); /* The callback function that inspects the status of all the other tasks. */
-
- if( xTimer != NULL )
- {
- xTimerStart( xTimer, mainDONT_BLOCK );
- }
+ /* Create the register check tasks, as described at the top of this
+ file */
+ xTaskCreate( prvRegTest1Task, "Reg1", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );
+ xTaskCreate( prvRegTest2Task, "Reg2", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );
/* Start the scheduler itself. */
vTaskStartScheduler();
@@ -325,6 +339,7 @@ TimerHandle_t xTimer = NULL;
static void prvCheckTimerCallback( TimerHandle_t xTimer )
{
static long lChangedTimerPeriodAlready = pdFALSE;
+static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
unsigned long ulErrorOccurred = pdFALSE;
/* Avoid compiler warnings. */
@@ -372,6 +387,37 @@ unsigned long ulErrorOccurred = pdFALSE;
{
ulErrorOccurred |= ( 0x01UL << 13UL );
}
+ else if( xAreTaskNotificationTasksStillRunning() != pdTRUE )
+ {
+ ulErrorOccurred |= ( 0x01UL << 14UL );
+ }
+ else if( xAreInterruptSemaphoreTasksStillRunning() != pdTRUE )
+ {
+ ulErrorOccurred |= ( 0x01UL << 15UL );
+ }
+ else if( xAreTimerDemoTasksStillRunning( mainCHECK_TIMER_PERIOD_MS ) != pdTRUE )
+ {
+ ulErrorOccurred |= 1UL << 16UL;
+ }
+ else if( xAreIntQueueTasksStillRunning() != pdTRUE )
+ {
+ ulErrorOccurred |= 1UL << 17UL;
+ }
+
+
+ /* Check that the register test 1 task is still running. */
+ if( ulLastRegTest1Value == ulRegTest1LoopCounter )
+ {
+ ulErrorOccurred |= 1UL << 18UL;
+ }
+ ulLastRegTest1Value = ulRegTest1LoopCounter;
+
+ /* Check that the register test 2 task is still running. */
+ if( ulLastRegTest2Value == ulRegTest2LoopCounter )
+ {
+ ulErrorOccurred |= 1UL << 19UL;
+ }
+ ulLastRegTest2Value = ulRegTest2LoopCounter;
if( ulErrorOccurred != pdFALSE )
{
@@ -464,6 +510,30 @@ char cIPAddress[ 20 ];
void vFullDemoIdleHook( void )
{
+static TimerHandle_t xCheckTimer = NULL;
+
+ if( xCheckTimer == NULL )
+ {
+ /* Create the software timer that performs the 'check'
+ functionality, in the full demo. This is not done before the
+ scheduler is started as to do so would prevent the standard demo
+ timer tasks from passing their tests (they expect the timer
+ command queue to be empty. */
+ xCheckTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */
+ ( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */
+ pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
+ ( void * ) 0, /* The ID is not used, so can be set to anything. */
+ prvCheckTimerCallback ); /* The callback function that inspects the status of all the other tasks. */
+
+ if( xCheckTimer != NULL )
+ {
+ xTimerStart( xCheckTimer, mainDONT_BLOCK );
+ }
+
+ /* Also start some timers that just flash LEDs. */
+ vStartLEDFlashTimers( mainNUM_FLASH_TIMER_LEDS );
+ }
+
/* If the file system is only going to be accessed from one task then
F_FS_THREAD_AWARE can be set to 0 and the set of example files is created
before the RTOS scheduler is started. If the file system is going to be
@@ -497,6 +567,15 @@ void vFullDemoTickHook( void )
/* Call the event group ISR tests. */
vPeriodicEventGroupsProcessing();
+
+ /* Exercise task notifications from interrupts. */
+ xNotifyTaskFromISR();
+
+ /* Use mutexes from interrupts. */
+ vInterruptSemaphorePeriodicTest();
+
+ /* Use timers from an interrupt. */
+ vTimerPeriodicISRTests();
}
/*-----------------------------------------------------------*/
@@ -510,3 +589,384 @@ void vApplicationPingReplyHook( ePingReplyStatus_t eStatus, uint16_t usIdentifie
}
/*-----------------------------------------------------------*/
+/* This is a naked function. */
+static void prvRegTest1Task( void *pvParameters )
+{
+ __asm volatile
+ (
+ " /* Fill the core registers with known values. */ \n"
+ " mov r0, #100 \n"
+ " mov r1, #101 \n"
+ " mov r2, #102 \n"
+ " mov r3, #103 \n"
+ " mov r4, #104 \n"
+ " mov r5, #105 \n"
+ " mov r6, #106 \n"
+ " mov r7, #107 \n"
+ " mov r8, #108 \n"
+ " mov r9, #109 \n"
+ " mov r10, #110 \n"
+ " mov r11, #111 \n"
+ " mov r12, #112 \n"
+ " \n"
+ " /* Fill the VFP registers with known values. */ \n"
+ " vmov d0, r0, r1 \n"
+ " vmov d1, r2, r3 \n"
+ " vmov d2, r4, r5 \n"
+ " vmov d3, r6, r7 \n"
+ " vmov d4, r8, r9 \n"
+ " vmov d5, r10, r11 \n"
+ " vmov d6, r0, r1 \n"
+ " vmov d7, r2, r3 \n"
+ " vmov d8, r4, r5 \n"
+ " vmov d9, r6, r7 \n"
+ " vmov d10, r8, r9 \n"
+ " vmov d11, r10, r11 \n"
+ " vmov d12, r0, r1 \n"
+ " vmov d13, r2, r3 \n"
+ " vmov d14, r4, r5 \n"
+ " vmov d15, r6, r7 \n"
+ " \n"
+ "reg1_loop: \n"
+ " /* Check all the VFP registers still contain the values set above.\n"
+ " First save registers that are clobbered by the test. */ \n"
+ " push { r0-r1 } \n"
+ " \n"
+ " vmov r0, r1, d0 \n"
+ " cmp r0, #100 \n"
+ " bne reg1_error_loopf \n"
+ " cmp r1, #101 \n"
+ " bne reg1_error_loopf \n"
+ " vmov r0, r1, d1 \n"
+ " cmp r0, #102 \n"
+ " bne reg1_error_loopf \n"
+ " cmp r1, #103 \n"
+ " bne reg1_error_loopf \n"
+ " vmov r0, r1, d2 \n"
+ " cmp r0, #104 \n"
+ " bne reg1_error_loopf \n"
+ " cmp r1, #105 \n"
+ " bne reg1_error_loopf \n"
+ " vmov r0, r1, d3 \n"
+ " cmp r0, #106 \n"
+ " bne reg1_error_loopf \n"
+ " cmp r1, #107 \n"
+ " bne reg1_error_loopf \n"
+ " vmov r0, r1, d4 \n"
+ " cmp r0, #108 \n"
+ " bne reg1_error_loopf \n"
+ " cmp r1, #109 \n"
+ " bne reg1_error_loopf \n"
+ " vmov r0, r1, d5 \n"
+ " cmp r0, #110 \n"
+ " bne reg1_error_loopf \n"
+ " cmp r1, #111 \n"
+ " bne reg1_error_loopf \n"
+ " vmov r0, r1, d6 \n"
+ " cmp r0, #100 \n"
+ " bne reg1_error_loopf \n"
+ " cmp r1, #101 \n"
+ " bne reg1_error_loopf \n"
+ " vmov r0, r1, d7 \n"
+ " cmp r0, #102 \n"
+ " bne reg1_error_loopf \n"
+ " cmp r1, #103 \n"
+ " bne reg1_error_loopf \n"
+ " vmov r0, r1, d8 \n"
+ " cmp r0, #104 \n"
+ " bne reg1_error_loopf \n"
+ " cmp r1, #105 \n"
+ " bne reg1_error_loopf \n"
+ " vmov r0, r1, d9 \n"
+ " cmp r0, #106 \n"
+ " bne reg1_error_loopf \n"
+ " cmp r1, #107 \n"
+ " bne reg1_error_loopf \n"
+ " vmov r0, r1, d10 \n"
+ " cmp r0, #108 \n"
+ " bne reg1_error_loopf \n"
+ " cmp r1, #109 \n"
+ " bne reg1_error_loopf \n"
+ " vmov r0, r1, d11 \n"
+ " cmp r0, #110 \n"
+ " bne reg1_error_loopf \n"
+ " cmp r1, #111 \n"
+ " bne reg1_error_loopf \n"
+ " vmov r0, r1, d12 \n"
+ " cmp r0, #100 \n"
+ " bne reg1_error_loopf \n"
+ " cmp r1, #101 \n"
+ " bne reg1_error_loopf \n"
+ " vmov r0, r1, d13 \n"
+ " cmp r0, #102 \n"
+ " bne reg1_error_loopf \n"
+ " cmp r1, #103 \n"
+ " bne reg1_error_loopf \n"
+ " vmov r0, r1, d14 \n"
+ " cmp r0, #104 \n"
+ " bne reg1_error_loopf \n"
+ " cmp r1, #105 \n"
+ " bne reg1_error_loopf \n"
+ " vmov r0, r1, d15 \n"
+ " cmp r0, #106 \n"
+ " bne reg1_error_loopf \n"
+ " cmp r1, #107 \n"
+ " bne reg1_error_loopf \n"
+ " \n"
+ " /* Restore the registers that were clobbered by the test. */\n"
+ " pop {r0-r1} \n"
+ " \n"
+ " /* VFP register test passed. Jump to the core register test. */\n"
+ " b reg1_loopf_pass \n"
+ " \n"
+ "reg1_error_loopf: \n"
+ " /* If this line is hit then a VFP register value was found to be\n"
+ " incorrect. */ \n"
+ " b reg1_error_loopf \n"
+ " \n"
+ "reg1_loopf_pass: \n"
+ " \n"
+ " cmp r0, #100 \n"
+ " bne reg1_error_loop \n"
+ " cmp r1, #101 \n"
+ " bne reg1_error_loop \n"
+ " cmp r2, #102 \n"
+ " bne reg1_error_loop \n"
+ " cmp r3, #103 \n"
+ " bne reg1_error_loop \n"
+ " cmp r4, #104 \n"
+ " bne reg1_error_loop \n"
+ " cmp r5, #105 \n"
+ " bne reg1_error_loop \n"
+ " cmp r6, #106 \n"
+ " bne reg1_error_loop \n"
+ " cmp r7, #107 \n"
+ " bne reg1_error_loop \n"
+ " cmp r8, #108 \n"
+ " bne reg1_error_loop \n"
+ " cmp r9, #109 \n"
+ " bne reg1_error_loop \n"
+ " cmp r10, #110 \n"
+ " bne reg1_error_loop \n"
+ " cmp r11, #111 \n"
+ " bne reg1_error_loop \n"
+ " cmp r12, #112 \n"
+ " bne reg1_error_loop \n"
+ " \n"
+ " /* Everything passed, increment the loop counter. */ \n"
+ " push { r0-r1 } \n"
+ " ldr r0, =ulRegTest1LoopCounter \n"
+ " ldr r1, [r0] \n"
+ " adds r1, r1, #1 \n"
+ " str r1, [r0] \n"
+ " pop { r0-r1 } \n"
+ " \n"
+ " /* Start again. */ \n"
+ " b reg1_loop \n"
+ " \n"
+ "reg1_error_loop: \n"
+ " /* If this line is hit then there was an error in a core register value.\n"
+ " The loop ensures the loop counter stops incrementing. */\n"
+ " b reg1_error_loop \n"
+ " nop "
+ );
+
+ /* Remove compiler warnings about unused parameters. */
+ ( void ) pvParameters;
+}
+/*-----------------------------------------------------------*/
+
+/* This is a naked function. */
+static void prvRegTest2Task( void *pvParameters )
+{
+ __asm volatile
+ (
+ " /* Set all the core registers to known values. */ \n"
+ " mov r0, #-1 \n"
+ " mov r1, #1 \n"
+ " mov r2, #2 \n"
+ " mov r3, #3 \n"
+ " mov r4, #4 \n"
+ " mov r5, #5 \n"
+ " mov r6, #6 \n"
+ " mov r7, #7 \n"
+ " mov r8, #8 \n"
+ " mov r9, #9 \n"
+ " mov r10, #10 \n"
+ " mov r11, #11 \n"
+ " mov r12, #12 \n"
+ " \n"
+ " /* Set all the VFP to known values. */ \n"
+ " vmov d0, r0, r1 \n"
+ " vmov d1, r2, r3 \n"
+ " vmov d2, r4, r5 \n"
+ " vmov d3, r6, r7 \n"
+ " vmov d4, r8, r9 \n"
+ " vmov d5, r10, r11 \n"
+ " vmov d6, r0, r1 \n"
+ " vmov d7, r2, r3 \n"
+ " vmov d8, r4, r5 \n"
+ " vmov d9, r6, r7 \n"
+ " vmov d10, r8, r9 \n"
+ " vmov d11, r10, r11 \n"
+ " vmov d12, r0, r1 \n"
+ " vmov d13, r2, r3 \n"
+ " vmov d14, r4, r5 \n"
+ " vmov d15, r6, r7 \n"
+ " \n"
+ "reg2_loop: \n"
+ " \n"
+ " /* Check all the VFP registers still contain the values set above.\n"
+ " First save registers that are clobbered by the test. */ \n"
+ " push { r0-r1 } \n"
+ " \n"
+ " vmov r0, r1, d0 \n"
+ " cmp r0, #-1 \n"
+ " bne reg2_error_loopf \n"
+ " cmp r1, #1 \n"
+ " bne reg2_error_loopf \n"
+ " vmov r0, r1, d1 \n"
+ " cmp r0, #2 \n"
+ " bne reg2_error_loopf \n"
+ " cmp r1, #3 \n"
+ " bne reg2_error_loopf \n"
+ " vmov r0, r1, d2 \n"
+ " cmp r0, #4 \n"
+ " bne reg2_error_loopf \n"
+ " cmp r1, #5 \n"
+ " bne reg2_error_loopf \n"
+ " vmov r0, r1, d3 \n"
+ " cmp r0, #6 \n"
+ " bne reg2_error_loopf \n"
+ " cmp r1, #7 \n"
+ " bne reg2_error_loopf \n"
+ " vmov r0, r1, d4 \n"
+ " cmp r0, #8 \n"
+ " bne reg2_error_loopf \n"
+ " cmp r1, #9 \n"
+ " bne reg2_error_loopf \n"
+ " vmov r0, r1, d5 \n"
+ " cmp r0, #10 \n"
+ " bne reg2_error_loopf \n"
+ " cmp r1, #11 \n"
+ " bne reg2_error_loopf \n"
+ " vmov r0, r1, d6 \n"
+ " cmp r0, #-1 \n"
+ " bne reg2_error_loopf \n"
+ " cmp r1, #1 \n"
+ " bne reg2_error_loopf \n"
+ " vmov r0, r1, d7 \n"
+ " cmp r0, #2 \n"
+ " bne reg2_error_loopf \n"
+ " cmp r1, #3 \n"
+ " bne reg2_error_loopf \n"
+ " vmov r0, r1, d8 \n"
+ " cmp r0, #4 \n"
+ " bne reg2_error_loopf \n"
+ " cmp r1, #5 \n"
+ " bne reg2_error_loopf \n"
+ " vmov r0, r1, d9 \n"
+ " cmp r0, #6 \n"
+ " bne reg2_error_loopf \n"
+ " cmp r1, #7 \n"
+ " bne reg2_error_loopf \n"
+ " vmov r0, r1, d10 \n"
+ " cmp r0, #8 \n"
+ " bne reg2_error_loopf \n"
+ " cmp r1, #9 \n"
+ " bne reg2_error_loopf \n"
+ " vmov r0, r1, d11 \n"
+ " cmp r0, #10 \n"
+ " bne reg2_error_loopf \n"
+ " cmp r1, #11 \n"
+ " bne reg2_error_loopf \n"
+ " vmov r0, r1, d12 \n"
+ " cmp r0, #-1 \n"
+ " bne reg2_error_loopf \n"
+ " cmp r1, #1 \n"
+ " bne reg2_error_loopf \n"
+ " vmov r0, r1, d13 \n"
+ " cmp r0, #2 \n"
+ " bne reg2_error_loopf \n"
+ " cmp r1, #3 \n"
+ " bne reg2_error_loopf \n"
+ " vmov r0, r1, d14 \n"
+ " cmp r0, #4 \n"
+ " bne reg2_error_loopf \n"
+ " cmp r1, #5 \n"
+ " bne reg2_error_loopf \n"
+ " vmov r0, r1, d15 \n"
+ " cmp r0, #6 \n"
+ " bne reg2_error_loopf \n"
+ " cmp r1, #7 \n"
+ " bne reg2_error_loopf \n"
+ " \n"
+ " /* Restore the registers that were clobbered by the test. */\n"
+ " pop {r0-r1} \n"
+ " \n"
+ " /* VFP register test passed. Jump to the core register test. */\n"
+ " b reg2_loopf_pass \n"
+ " \n"
+ "reg2_error_loopf: \n"
+ " /* If this line is hit then a VFP register value was found to be\n"
+ " incorrect. */ \n"
+ " b reg2_error_loopf \n"
+ " \n"
+ "reg2_loopf_pass: \n"
+ " \n"
+ " cmp r0, #-1 \n"
+ " bne reg2_error_loop \n"
+ " cmp r1, #1 \n"
+ " bne reg2_error_loop \n"
+ " cmp r2, #2 \n"
+ " bne reg2_error_loop \n"
+ " cmp r3, #3 \n"
+ " bne reg2_error_loop \n"
+ " cmp r4, #4 \n"
+ " bne reg2_error_loop \n"
+ " cmp r5, #5 \n"
+ " bne reg2_error_loop \n"
+ " cmp r6, #6 \n"
+ " bne reg2_error_loop \n"
+ " cmp r7, #7 \n"
+ " bne reg2_error_loop \n"
+ " cmp r8, #8 \n"
+ " bne reg2_error_loop \n"
+ " cmp r9, #9 \n"
+ " bne reg2_error_loop \n"
+ " cmp r10, #10 \n"
+ " bne reg2_error_loop \n"
+ " cmp r11, #11 \n"
+ " bne reg2_error_loop \n"
+ " cmp r12, #12 \n"
+ " bne reg2_error_loop \n"
+ " \n"
+ " /* Increment the loop counter to indicate this test is still functioning\n"
+ " correctly. */ \n"
+ " push { r0-r1 } \n"
+ " ldr r0, =ulRegTest2LoopCounter \n"
+ " ldr r1, [r0] \n"
+ " adds r1, r1, #1 \n"
+ " str r1, [r0] \n"
+ " \n"
+ " /* Yield to increase test coverage. */ \n"
+ " movs r0, #0x01 \n"
+ " ldr r1, =0xe000ed04 \n" /* NVIC_INT_CTRL */
+ " lsl r0, #28 \n" /* Shift to PendSV bit */
+ " str r0, [r1] \n"
+ " dsb \n"
+ " pop { r0-r1 } \n"
+ " \n"
+ " /* Start again. */ \n"
+ " b reg2_loop \n"
+ " \n"
+ "reg2_error_loop: \n"
+ " /* If this line is hit then there was an error in a core register value.\n"
+ " This loop ensures the loop counter variable stops incrementing. */\n"
+ " b reg2_error_loop \n"
+ " nop \n"
+ );
+
+ /* Remove compiler warnings about unused parameters. */
+ ( void ) pvParameters;
+}
diff --git a/FreeRTOS/Demo/CORTEX_M4_ATSAM4S_Atmel_Studio/RTOSDemo.atsuo b/FreeRTOS/Demo/CORTEX_M4_ATSAM4S_Atmel_Studio/RTOSDemo.atsuo
index a19959c2db..bbb92eb939 100644
Binary files a/FreeRTOS/Demo/CORTEX_M4_ATSAM4S_Atmel_Studio/RTOSDemo.atsuo and b/FreeRTOS/Demo/CORTEX_M4_ATSAM4S_Atmel_Studio/RTOSDemo.atsuo differ
diff --git a/FreeRTOS/Demo/CORTEX_M4_ATSAM4S_Atmel_Studio/RTOSDemo.cproj b/FreeRTOS/Demo/CORTEX_M4_ATSAM4S_Atmel_Studio/RTOSDemo.cproj
index f953787d32..922bb614c8 100644
--- a/FreeRTOS/Demo/CORTEX_M4_ATSAM4S_Atmel_Studio/RTOSDemo.cproj
+++ b/FreeRTOS/Demo/CORTEX_M4_ATSAM4S_Atmel_Studio/RTOSDemo.cproj
@@ -10,141 +10,141 @@
2.11.1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
ATSAM4S16C
sam4s
@@ -165,7 +165,7 @@
com.atmel.avrdbg.tool.samice
J-Link
- 158002654
+ 158000789
127.0.0.1
1637
diff --git a/FreeRTOS/Demo/CORTEX_M4_ATSAM4S_Atmel_Studio/src/IntQueueTimer.c b/FreeRTOS/Demo/CORTEX_M4_ATSAM4S_Atmel_Studio/src/IntQueueTimer.c
index 079cd1e6bb..b5387a8965 100644
--- a/FreeRTOS/Demo/CORTEX_M4_ATSAM4S_Atmel_Studio/src/IntQueueTimer.c
+++ b/FreeRTOS/Demo/CORTEX_M4_ATSAM4S_Atmel_Studio/src/IntQueueTimer.c
@@ -89,7 +89,7 @@ interrupt is 20 times faster so really hammers the interrupt entry and exit
code. */
#define tmrTIMER_0_FREQUENCY ( 2000UL )
#define tmrTIMER_1_FREQUENCY ( 1003UL )
-#define tmrTIMER_2_FREQUENCY ( 20000UL )
+#define tmrTIMER_2_FREQUENCY ( 5000UL )
/* Priorities used by the timer interrupts - these are set differently to make
nesting likely/common. The high frequency timer operates above the max
diff --git a/FreeRTOS/Demo/CORTEX_MPU_LM3Sxxxx_Rowley/RTOSDemo.hzs b/FreeRTOS/Demo/CORTEX_MPU_LM3Sxxxx_Rowley/RTOSDemo.hzs
index 637fe364e1..6086e553a7 100644
--- a/FreeRTOS/Demo/CORTEX_MPU_LM3Sxxxx_Rowley/RTOSDemo.hzs
+++ b/FreeRTOS/Demo/CORTEX_MPU_LM3Sxxxx_Rowley/RTOSDemo.hzs
@@ -3,6 +3,9 @@
+
+
+
@@ -21,16 +24,16 @@
-
+
-
+
-
+
-
+
@@ -51,7 +54,7 @@
-
+
-
+
diff --git a/FreeRTOS/Demo/Common/Minimal/IntQueue.c b/FreeRTOS/Demo/Common/Minimal/IntQueue.c
index c844887db0..e8c75e6447 100644
--- a/FreeRTOS/Demo/Common/Minimal/IntQueue.c
+++ b/FreeRTOS/Demo/Common/Minimal/IntQueue.c
@@ -139,7 +139,10 @@ from within the interrupts. */
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); \
{ \
uxValueForNormallyEmptyQueue++; \
- xQueueSendFromISR( xNormallyEmptyQueue, ( void * ) &uxValueForNormallyEmptyQueue, &xHigherPriorityTaskWoken ); \
+ if( xQueueSendFromISR( xNormallyEmptyQueue, ( void * ) &uxValueForNormallyEmptyQueue, &xHigherPriorityTaskWoken ) != pdPASS ) \
+ { \
+ uxValueForNormallyEmptyQueue--; \
+ } \
} \
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \
} \
@@ -153,7 +156,10 @@ from within the interrupts. */
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); \
{ \
uxValueForNormallyFullQueue++; \
- xQueueSendFromISR( xNormallyFullQueue, ( void * ) &uxValueForNormallyFullQueue, &xHigherPriorityTaskWoken ); \
+ if( xQueueSendFromISR( xNormallyFullQueue, ( void * ) &uxValueForNormallyFullQueue, &xHigherPriorityTaskWoken ) != pdPASS ) \
+ { \
+ uxValueForNormallyFullQueue--; \
+ } \
} \
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \
} \
diff --git a/FreeRTOS/Source/include/task.h b/FreeRTOS/Source/include/task.h
index c77d422f2e..f9af55730c 100644
--- a/FreeRTOS/Source/include/task.h
+++ b/FreeRTOS/Source/include/task.h
@@ -1728,7 +1728,7 @@ BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, BaseType_t ulBitsToCl
* \defgroup xTaskNotifyWait xTaskNotifyWait
* \ingroup TaskNotifications
*/
-#define xTaskNotifyGiveFromISR( xTaskToNotify, pxHigherPriorityTaskWoken ) xTaskNotifyFromISR( ( xTaskToNotify ), 0, eIncrement, ( pxHigherPriorityTaskWoken ) )
+BaseType_t xTaskNotifyGiveFromISR( TaskHandle_t xTaskToNotify, BaseType_t *pxHigherPriorityTaskWoken );
/**
* task. h
diff --git a/FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h b/FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h
index ae08cbf8ae..fea0f9f4fb 100644
--- a/FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h
+++ b/FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h
@@ -126,7 +126,7 @@ extern void vPortEnterCritical( void );
extern void vPortExitCritical( void );
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortSetBASEPRI(x)
-#define portDISABLE_INTERRUPTS() ulPortRaiseBASEPRI()
+#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI()
#define portENABLE_INTERRUPTS() vPortSetBASEPRI(0)
#define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
@@ -194,6 +194,22 @@ not necessary for to use this port. They are defined so the common demo files
/*-----------------------------------------------------------*/
+portFORCE_INLINE static void vPortRaiseBASEPRI( void )
+{
+uint32_t ulNewBASEPRI;
+
+ __asm volatile
+ (
+ " mov %0, %1 \n" \
+ " msr basepri, %0 \n" \
+ " isb \n" \
+ " dsb \n" \
+ :"=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
+ );
+}
+
+/*-----------------------------------------------------------*/
+
portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void )
{
uint32_t ulOriginalBASEPRI, ulNewBASEPRI;
diff --git a/FreeRTOS/Source/portable/RVDS/ARM_CM4F/portmacro.h b/FreeRTOS/Source/portable/RVDS/ARM_CM4F/portmacro.h
index 2b29b7253a..8d1f5ff130 100644
--- a/FreeRTOS/Source/portable/RVDS/ARM_CM4F/portmacro.h
+++ b/FreeRTOS/Source/portable/RVDS/ARM_CM4F/portmacro.h
@@ -129,7 +129,7 @@ typedef unsigned long UBaseType_t;
extern void vPortEnterCritical( void );
extern void vPortExitCritical( void );
-#define portDISABLE_INTERRUPTS() ulPortRaiseBASEPRI()
+#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI()
#define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 )
#define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
@@ -200,6 +200,21 @@ static portFORCE_INLINE void vPortSetBASEPRI( uint32_t ulBASEPRI )
}
/*-----------------------------------------------------------*/
+static portFORCE_INLINE void vPortRaiseBASEPRI( void )
+{
+uint32_t ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY;
+
+ __asm
+ {
+ /* Set BASEPRI to the max syscall priority to effect a critical
+ section. */
+ msr basepri, ulNewBASEPRI
+ dsb
+ isb
+ }
+}
+/*-----------------------------------------------------------*/
+
static portFORCE_INLINE uint32_t ulPortRaiseBASEPRI( void )
{
uint32_t ulReturn, ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY;
diff --git a/FreeRTOS/Source/tasks.c b/FreeRTOS/Source/tasks.c
index 69aaebb76b..d0be177993 100644
--- a/FreeRTOS/Source/tasks.c
+++ b/FreeRTOS/Source/tasks.c
@@ -180,8 +180,8 @@ typedef struct tskTaskControlBlock
#endif
#if ( configUSE_TASK_NOTIFICATIONS == 1 )
- uint32_t ulNotifiedValue;
- eNotifyValue eNotifyState;
+ volatile uint32_t ulNotifiedValue;
+ volatile eNotifyValue eNotifyState;
#endif
} tskTCB;
@@ -4228,6 +4228,90 @@ TickType_t uxReturn;
#endif /* configUSE_TASK_NOTIFICATIONS */
/*-----------------------------------------------------------*/
+#if( configUSE_TASK_NOTIFICATIONS == 1 )
+
+ BaseType_t xTaskNotifyGiveFromISR( TaskHandle_t xTaskToNotify, BaseType_t *pxHigherPriorityTaskWoken )
+ {
+ TCB_t * pxTCB;
+ eNotifyValue eOriginalNotifyState;
+ BaseType_t xReturn = pdPASS;
+ UBaseType_t uxSavedInterruptStatus;
+
+ configASSERT( xTaskToNotify );
+
+ /* RTOS ports that support interrupt nesting have the concept of a
+ maximum system call (or maximum API call) interrupt priority.
+ Interrupts that are above the maximum system call priority are keep
+ permanently enabled, even when the RTOS kernel is in a critical section,
+ but cannot make any calls to FreeRTOS API functions. If configASSERT()
+ is defined in FreeRTOSConfig.h then
+ portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion
+ failure if a FreeRTOS API function is called from an interrupt that has
+ been assigned a priority above the configured maximum system call
+ priority. Only FreeRTOS functions that end in FromISR can be called
+ from interrupts that have been assigned a priority at or (logically)
+ below the maximum system call interrupt priority. FreeRTOS maintains a
+ separate interrupt safe API to ensure interrupt entry is as fast and as
+ simple as possible. More information (albeit Cortex-M specific) is
+ provided on the following link:
+ http://www.freertos.org/RTOS-Cortex-M3-M4.html */
+ portASSERT_IF_INTERRUPT_PRIORITY_INVALID();
+
+ pxTCB = ( TCB_t * ) xTaskToNotify;
+
+ uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
+ {
+ eOriginalNotifyState = pxTCB->eNotifyState;
+ pxTCB->eNotifyState = eNotified;
+
+ /* 'Giving' is equivalent to incrementing a count in a counting
+ semaphore. */
+ ( pxTCB->ulNotifiedValue )++;
+
+ /* If the task is in the blocked state specifically to wait for a
+ notification then unblock it now. */
+ if( eOriginalNotifyState == eWaitingNotification )
+ {
+ /* The task should not have been on an event list. */
+ configASSERT( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL );
+
+ if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE )
+ {
+ ( void ) uxListRemove( &( pxTCB->xGenericListItem ) );
+ prvAddTaskToReadyList( pxTCB );
+ }
+ else
+ {
+ /* The delayed and ready lists cannot be accessed, so hold
+ this task pending until the scheduler is resumed. */
+ vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) );
+ }
+
+ if( pxTCB->uxPriority > pxCurrentTCB->uxPriority )
+ {
+ /* The notified task has a priority above the currently
+ executing task so a yield is required. */
+ if( pxHigherPriorityTaskWoken != NULL )
+ {
+ *pxHigherPriorityTaskWoken = pdTRUE;
+ }
+ }
+ else
+ {
+ mtCOVERAGE_TEST_MARKER();
+ }
+ }
+ }
+ portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
+
+ return xReturn;
+ }
+
+#endif /* configUSE_TASK_NOTIFICATIONS */
+
+/*-----------------------------------------------------------*/
+
+
#ifdef FREERTOS_MODULE_TEST
#include "tasks_test_access_functions.h"
#endif