diff --git a/FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/AtmelFiles/libboard_sama5d3x-ek/source/board_lowlevel.c b/FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/AtmelFiles/libboard_sama5d3x-ek/source/board_lowlevel.c
index 3e0b86334..64660bfe4 100644
--- a/FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/AtmelFiles/libboard_sama5d3x-ek/source/board_lowlevel.c
+++ b/FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/AtmelFiles/libboard_sama5d3x-ek/source/board_lowlevel.c
@@ -77,11 +77,11 @@ extern WEAK void LowLevelInit( void )
if ((uint32_t)LowLevelInit < DDR_CS_ADDR) /* Code not in external mem */ {
PMC_SelectExt12M_Osc();
PMC_SwitchMck2Main();
- PMC_SetPllA( CKGR_PLLAR_STUCKTO1 |
+ PMC_SetPllA( CKGR_PLLAR_STUCKTO1 |
CKGR_PLLAR_PLLACOUNT(0x3F) |
CKGR_PLLAR_OUTA(0x0) |
- CKGR_PLLAR_MULA(65) |
- CKGR_PLLAR_DIVA(1),
+ CKGR_PLLAR_MULA(65) |
+ CKGR_PLLAR_DIVA(1),
0x3u << 8);
PMC_SetMckPllaDiv(PMC_MCKR_PLLADIV2_DIV2);
PMC_SetMckPrescaler(PMC_MCKR_PRES_CLOCK);
diff --git a/FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/AtmelFiles/libchip_sama5d3x/source/mmu.c b/FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/AtmelFiles/libchip_sama5d3x/source/mmu.c
index a2aeb93a8..d29cae233 100644
--- a/FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/AtmelFiles/libchip_sama5d3x/source/mmu.c
+++ b/FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/AtmelFiles/libchip_sama5d3x/source/mmu.c
@@ -1,5 +1,5 @@
/* ----------------------------------------------------------------------------
- * SAM Software Package License
+ * SAM Software Package License
* ----------------------------------------------------------------------------
* Copyright (c) 2013, Atmel Corporation
*
@@ -26,10 +26,10 @@
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ----------------------------------------------------------------------------
*/
-
+
/** \file */
-/**
+/**
* \addtogroup mmu MMU Initialization
*
* \section Usage
@@ -38,7 +38,7 @@
* translation table entries. TLBs avoid the requirement for every memory access to perform a translation table
* lookup. The ARM architecture does not specify the exact form of the TLB structures for any design. In a
* similar way to the requirements for caches, the architecture only defines certain principles for TLBs:
- *
+ *
* The MMU supports memory accesses based on memory sections or pages:
* Supersections Consist of 16MB blocks of memory. Support for Supersections is optional.
* -# Sections Consist of 1MB blocks of memory.
@@ -54,7 +54,7 @@
* \ref mmu.c\n
* \ref mmu.h \n
*/
-
+
/*------------------------------------------------------------------------------ */
/* Headers */
/*------------------------------------------------------------------------------ */
@@ -240,4 +240,4 @@ void MMU_Initialize(uint32_t *pTB)
CP15_WriteTTB((unsigned int)pTB);
/* Program the domain access register */
CP15_WriteDomainAccessControl(0xC0000000); // only domain 15: access are not checked
-}
\ No newline at end of file
+}
diff --git a/FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/CDCCommandConsole.c b/FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/CDCCommandConsole.c
index 8acbbd3c2..3cb73a4c6 100644
--- a/FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/CDCCommandConsole.c
+++ b/FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/CDCCommandConsole.c
@@ -477,8 +477,9 @@ void USBDCallbacks_Initialized( void )
{
/* CDC specific re-implementation of weak callback function. Invoked after
the USB driver has been initialised. By default, configures the UDP/UDPHS
- interrupt. */
- IRQ_ConfigureIT( ID_UDPHS, 0, USBD_IrqHandler );
+ interrupt. The interrupt priority is set to the highest to ensure the
+ interrupt nesting tests interfer as little as possible with the USB. */
+ IRQ_ConfigureIT( ID_UDPHS, 7, USBD_IrqHandler );
IRQ_EnableIT( ID_UDPHS );
}
/*-----------------------------------------------------------*/
diff --git a/FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/FreeRTOSConfig.h b/FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/FreeRTOSConfig.h
index dcfb963c2..afa4c9380 100644
--- a/FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/FreeRTOSConfig.h
+++ b/FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/FreeRTOSConfig.h
@@ -87,7 +87,7 @@
#define configUSE_TICK_HOOK 1
#define configMAX_PRIORITIES ( 5 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 160 )
-#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 38912 ) )
+#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 45 * 1024 ) )
#define configMAX_TASK_NAME_LEN ( 10 )
#define configUSE_TRACE_FACILITY 1
#define configUSE_16_BIT_TICKS 0
@@ -96,32 +96,32 @@
#define configQUEUE_REGISTRY_SIZE 8
#define configCHECK_FOR_STACK_OVERFLOW 2
#define configUSE_RECURSIVE_MUTEXES 1
-#define configUSE_MALLOC_FAILED_HOOK 0
+#define configUSE_MALLOC_FAILED_HOOK 1
#define configUSE_APPLICATION_TASK_TAG 0
#define configUSE_COUNTING_SEMAPHORES 1
/* Co-routine definitions. */
-#define configUSE_CO_ROUTINES 0
-#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
+#define configUSE_CO_ROUTINES 0
+#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* Software timer definitions. */
-#define configUSE_TIMERS 1
-#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
-#define configTIMER_QUEUE_LENGTH 5
-#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )
+#define configUSE_TIMERS 1
+#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
+#define configTIMER_QUEUE_LENGTH 5
+#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
-#define INCLUDE_vTaskPrioritySet 1
-#define INCLUDE_uxTaskPriorityGet 1
-#define INCLUDE_vTaskDelete 1
-#define INCLUDE_vTaskCleanUpResources 1
-#define INCLUDE_vTaskSuspend 1
-#define INCLUDE_vTaskDelayUntil 1
-#define INCLUDE_vTaskDelay 1
-#define INCLUDE_eTaskGetState 1
-#define INCLUDE_xEventGroupSetBitFromISR 1
-#define INCLUDE_xTimerPendFunctionCall 1
+#define INCLUDE_vTaskPrioritySet 1
+#define INCLUDE_uxTaskPriorityGet 1
+#define INCLUDE_vTaskDelete 1
+#define INCLUDE_vTaskCleanUpResources 1
+#define INCLUDE_vTaskSuspend 1
+#define INCLUDE_vTaskDelayUntil 1
+#define INCLUDE_vTaskDelay 1
+#define INCLUDE_eTaskGetState 1
+#define INCLUDE_xEventGroupSetBitFromISR 1
+#define INCLUDE_xTimerPendFunctionCall 1
/* This demo makes use of one or more example stats formatting functions. These
format the raw data provided by the uxTaskGetSystemState() function in to human
@@ -140,13 +140,16 @@ FreeRTOS/Source/tasks.c for limitations. */
/* Prevent C code being included in assembly files when the IAR compiler is
used. */
#ifndef __IASMARM__
- /* Run time stats gathering definitions. */
- unsigned long ulGetRunTimeCounterValue( void );
- void vInitialiseRunTimeStats( void );
- #define configGENERATE_RUN_TIME_STATS 0
-//_RB_ #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vInitialiseRunTimeStats()
-//_RB_ #define portGET_RUN_TIME_COUNTER_VALUE() ulGetRunTimeCounterValue()
+ /* The interrupt nesting test creates a 20KHz timer. For convenience the
+ 20KHz timer is also used to generate the run time stats time base, removing
+ the need to use a separate timer for that purpose. The 20KHz timer
+ increments ulHighFrequencyTimerCounts, which is used as the time base.
+ Therefore the following macro is not implemented. */
+ #define configGENERATE_RUN_TIME_STATS 1
+ extern volatile uint32_t ulHighFrequencyTimerCounts;
+ #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()
+ #define portGET_RUN_TIME_COUNTER_VALUE() ulHighFrequencyTimerCounts
/* The size of the global output buffer that is available for use when there
are multiple command interpreters running at once (for example, one on a UART
diff --git a/FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/FreeRTOS_tick_config.c b/FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/FreeRTOS_tick_config.c
index d034a4463..e90c521f7 100644
--- a/FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/FreeRTOS_tick_config.c
+++ b/FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/FreeRTOS_tick_config.c
@@ -88,6 +88,8 @@ static void System_Handler( void );
static void System_Handler( void )
{
+ __enable_interrupt();
+
/* See the comments above the function prototype in this file. */
FreeRTOS_Tick_Handler();
}
@@ -113,7 +115,7 @@ void vConfigureTickInterrupt( void )
/* Configure interrupt on PIT. Note this is on the system interrupt, which
is shared with other system peripherals, so System_Handler() must be
installed in place of FreeRTOS_Tick_Handler() if other system handlers are
- required. */
+ required. The tick must be given the lowest priority (0 in the SAMA5 AIC) */
IRQ_ConfigureIT( ID_PIT, 0, FreeRTOS_Tick_Handler );
/* See commend directly above IRQ_ConfigureIT( ID_PIT, 0, System_Handler ); */
IRQ_EnableIT( ID_PIT );
@@ -129,5 +131,3 @@ void vConfigureTickInterrupt( void )
}
/*-----------------------------------------------------------*/
-
-
diff --git a/FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/Full_Demo/IntQueueTimer.c b/FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/Full_Demo/IntQueueTimer.c
index 4c648d874..8a11f5f5a 100644
--- a/FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/Full_Demo/IntQueueTimer.c
+++ b/FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/Full_Demo/IntQueueTimer.c
@@ -66,16 +66,17 @@
/*
* This file initialises three timers as follows:
*
- * Timer 0 and Timer 1 provide the interrupts that are used with the IntQ
+ * TC0 channels 0 and 1 provide the interrupts that are used with the IntQ
* standard demo tasks, which test interrupt nesting and using queues from
- * interrupts. Both these interrupts operate below the maximum syscall
- * interrupt priority.
+ * interrupts. As the interrupt is shared the nesting achieved is not as deep
+ * as normal when this test is executed, but still worth while.
*
- * Timer 2 is a much higher frequency timer that tests the nesting of interrupts
- * that execute above the maximum syscall interrupt priority.
+ * TC2 channel 0 provides a much higher frequency timer that tests the nesting of
+ * interrupts that execute above the maximum syscall interrupt priority.
*
* All the timers can nest with the tick interrupt - creating a maximum
- * interrupt nesting depth of 4.
+ * interrupt nesting depth of 3 (normally 4, if the first two timers used
+ * separate interrupts).
*
* For convenience, the high frequency timer is also used to provide the time
* base for the run time stats.
@@ -88,24 +89,35 @@
#include "IntQueueTimer.h"
#include "IntQueue.h"
+/* Library includes. */
+#include "board.h"
+
/* The frequencies at which the first two timers expire are slightly offset to
-ensure they don't remain synchronised. The frequency of the interrupt that
-operates above the max syscall interrupt priority is 10 times faster so really
-hammers the interrupt entry and exit code. */
+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 tmrTIMERS_USED 3
#define tmrTIMER_0_FREQUENCY ( 2000UL )
-#define tmrTIMER_1_FREQUENCY ( 2001UL )
+#define tmrTIMER_1_FREQUENCY ( 2003UL )
#define tmrTIMER_2_FREQUENCY ( 20000UL )
+/* The channels used in TC0 for generating the three interrupts. */
+#define tmrTC0_CHANNEL_0 0 /* At tmrTIMER_0_FREQUENCY */
+#define tmrTC0_CHANNEL_1 1 /* At tmrTIMER_1_FREQUENCY */
+#define tmrTC1_CHANNEL_0 0 /* At tmrTIMER_2_FREQUENCY */
+
+/* The bit within the RC_SR register that indicates an RC compare. */
+#define tmrRC_COMPARE ( 1UL << 4UL )
+
+/* The high frequency interrupt given the highest priority or all. The priority
+of the lower frequency timers must still be above the tick interrupt priority. */
+#define tmrLOWER_PRIORITY 1
+#define tmrHIGHER_PRIORITY 5
/*-----------------------------------------------------------*/
-/*
- * The single interrupt service routines that is used to service all three
- * timers.
- */
-static void prvTimerHandler( void *CallBackRef );
-
-/*-----------------------------------------------------------*/
+/* Handlers for the three timer channels. */
+static void prvTC0_Handler( void );
+static void prvTC1_Handler( void );
/* Used to provide a means of ensuring the intended interrupt nesting depth is
actually being reached. */
@@ -120,11 +132,76 @@ volatile uint32_t ulHighFrequencyTimerCounts = 0;
void vInitialiseTimerForIntQueueTest( void )
{
+const uint32_t ulDivider = 128UL, ulTCCLKS = 3UL;
+
+ /* Enable the TC clocks. */
+ PMC->PMC_PCER0 = 1 << ID_TC0;
+ PMC->PMC_PCER0 = 1 << ID_TC1;
+
+ /* Configure TC0 channel 0 for a tmrTIMER_0_FREQUENCY frequency and trigger
+ on RC compare. */
+ TC_Configure( TC0, tmrTC0_CHANNEL_0, ulTCCLKS | TC_CMR_CPCTRG );
+ TC0->TC_CHANNEL[ tmrTC0_CHANNEL_0 ].TC_RC = BOARD_MCK / ( tmrTIMER_0_FREQUENCY * ulDivider );
+ TC0->TC_CHANNEL[ tmrTC0_CHANNEL_0 ].TC_IER = TC_IER_CPCS;
+
+ /* Configure TC0 channel 1 for a tmrTIMER_1_FREQUENCY frequency and trigger
+ on RC compare. */
+ TC_Configure( TC0, tmrTC0_CHANNEL_1, ulTCCLKS | TC_CMR_CPCTRG );
+ TC0->TC_CHANNEL[ tmrTC0_CHANNEL_1 ].TC_RC = BOARD_MCK / ( tmrTIMER_1_FREQUENCY * ulDivider );
+ TC0->TC_CHANNEL[ tmrTC0_CHANNEL_1 ].TC_IER = TC_IER_CPCS;
+
+ /* Configure TC1 channel 0 tmrTIMER_2_FREQUENCY frequency and trigger on
+ RC compare. */
+ TC_Configure( TC1, tmrTC1_CHANNEL_0, ulTCCLKS | TC_CMR_CPCTRG );
+ TC1->TC_CHANNEL[ tmrTC1_CHANNEL_0 ].TC_RC = BOARD_MCK / ( tmrTIMER_2_FREQUENCY * ulDivider );
+ TC1->TC_CHANNEL[ tmrTC1_CHANNEL_0 ].TC_IER = TC_IER_CPCS;
+
+ /* Enable interrupts and start the timers. */
+ IRQ_ConfigureIT( ID_TC0, tmrLOWER_PRIORITY, prvTC0_Handler );
+ IRQ_ConfigureIT( ID_TC1, tmrHIGHER_PRIORITY, prvTC1_Handler );
+ IRQ_EnableIT( ID_TC0 );
+ IRQ_EnableIT( ID_TC1 );
+ TC_Start( TC0, tmrTC0_CHANNEL_0 );
+ TC_Start( TC0, tmrTC0_CHANNEL_1 );
+ TC_Start( TC1, tmrTC1_CHANNEL_0 );
}
/*-----------------------------------------------------------*/
-static void prvTimerHandler( void *pvCallBackRef )
+static void prvTC0_Handler( void )
{
- ( void ) pvCallBackRef;
+#warning Why can interrupts only be enabled inside the C function?
+ __enable_interrupt();
+
+ /* Read will clear the status bit. */
+ if( ( TC0->TC_CHANNEL[ tmrTC0_CHANNEL_0 ].TC_SR & tmrRC_COMPARE ) != 0 )
+ {
+ portYIELD_FROM_ISR( xFirstTimerHandler() );
+ }
+
+ if( ( TC0->TC_CHANNEL[ tmrTC0_CHANNEL_1 ].TC_SR & tmrRC_COMPARE ) != 0 )
+ {
+ portYIELD_FROM_ISR( xSecondTimerHandler() );
+ }
+}
+/*-----------------------------------------------------------*/
+
+static void prvTC1_Handler( void )
+{
+volatile uint32_t ulDummy;
+
+ __enable_interrupt();
+
+ /* Dummy read to clear status bit. */
+ ulDummy = TC1->TC_CHANNEL[ tmrTC1_CHANNEL_0 ].TC_SR;
+
+ /* Latch the maximum nesting count. */
+ if( ulPortInterruptNesting > ulMaxRecordedNesting )
+ {
+ ulMaxRecordedNesting = ulPortInterruptNesting;
+ }
+
+ /* Keep a count of the number of interrupts to use as a time base for the
+ run-time stats. */
+ ulHighFrequencyTimerCounts++;
}
diff --git a/FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/Full_Demo/main_full.c b/FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/Full_Demo/main_full.c
index eb60eed62..1eff84509 100644
--- a/FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/Full_Demo/main_full.c
+++ b/FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/Full_Demo/main_full.c
@@ -233,7 +233,7 @@ void main_full( void )
/* Start all the other standard demo/test tasks. They have not particular
functionality, but do demonstrate how to use the FreeRTOS API and test the
kernel port. */
-//_RB_ vStartInterruptQueueTasks();
+ vStartInterruptQueueTasks();
vStartDynamicPriorityTasks();
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vCreateBlockTimeTasks();
@@ -251,7 +251,7 @@ void main_full( void )
vUARTCommandConsoleStart( mainUART_COMMAND_CONSOLE_STACK_SIZE, mainUART_COMMAND_CONSOLE_TASK_PRIORITY );
/* Register the standard CLI commands. */
-// vRegisterSampleCLICommands();
+ vRegisterSampleCLICommands();
/* Create the register check tasks, as described at the top of this file */
xTaskCreate( prvRegTestTaskEntry1, "Reg1", configMINIMAL_STACK_SIZE, mainREG_TEST_TASK_1_PARAMETER, tskIDLE_PRIORITY, NULL );
@@ -313,7 +313,7 @@ unsigned long ulErrorFound = pdFALSE;
that they are all still running, and that none have detected an error. */
if( xAreIntQueueTasksStillRunning() != pdTRUE )
{
-//_RB_ ulErrorFound = pdTRUE;
+ ulErrorFound = pdTRUE;
}
if( xAreMathsTaskStillRunning() != pdTRUE )
@@ -455,9 +455,41 @@ static void prvRegTestTaskEntry2( void *pvParameters )
static void prvPseudoRandomiser( void *pvParameters )
{
-const uint32_t ulMultiplier = 0x015a4e35UL, ulIncrement = 1UL, ulMinDelay = ( 35 / portTICK_PERIOD_MS );
+const uint32_t ulMultiplier = 0x015a4e35UL, ulIncrement = 1UL, ulMinDelay = ( 35 / portTICK_PERIOD_MS ), ulIBit = ( 1UL << 7UL );
volatile uint32_t ulNextRand = ( uint32_t ) &pvParameters, ulValue;
+ /* A few minor port tests before entering the randomiser loop.
+
+ At this point interrupts should be enabled. */
+ configASSERT( ( __get_CPSR() & ulIBit ) == 0 );
+
+ /* The CPU does not have an interrupt mask register, so critical sections
+ have to globally disable interrupts. Therefore entering a critical section
+ should leave the I bit set. */
+ taskENTER_CRITICAL();
+ configASSERT( ( __get_CPSR() & ulIBit ) == ulIBit );
+
+ /* Nest the critical sections. */
+ taskENTER_CRITICAL();
+ configASSERT( ( __get_CPSR() & ulIBit ) == ulIBit );
+
+ /* After yielding the I bit should still be set. Note yielding is possible
+ in a critical section as each task maintains its own critical section
+ nesting count so some tasks are in critical sections and others are not -
+ however this is *not* something task code should do! */
+ taskYIELD();
+ configASSERT( ( __get_CPSR() & ulIBit ) == ulIBit );
+
+ /* The I bit should not be cleared again until both critical sections have
+ been exited. */
+ taskEXIT_CRITICAL();
+ taskYIELD();
+ configASSERT( ( __get_CPSR() & ulIBit ) == ulIBit );
+ taskEXIT_CRITICAL();
+ configASSERT( ( __get_CPSR() & ulIBit ) == 0 );
+ taskYIELD();
+ configASSERT( ( __get_CPSR() & ulIBit ) == 0 );
+
/* This task does nothing other than ensure there is a little bit of
disruption in the scheduling pattern of the other tasks. Normally this is
done by generating interrupts at pseudo random times. */
diff --git a/FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/RTOSDemo.ewp b/FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/RTOSDemo.ewp
index 55d30dbf7..df27bd85a 100644
--- a/FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/RTOSDemo.ewp
+++ b/FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/RTOSDemo.ewp
@@ -174,7 +174,7 @@
CCDefinessama5d3xsram
- TRACE_LEVEL=4
+ TRACE_LEVEL=0