#error configMAX_API_CALL_INTERRUPT_PRIORITY must be greater than ( configUNIQUE_INTERRUPT_PRIORITIES / 2 )\r
#endif\r
\r
+#ifndef configINSTALL_FREERTOS_VECTOR_TABLE\r
+ #warning configINSTALL_FREERTOS_VECTOR_TABLE was undefined. Defaulting configINSTALL_FREERTOS_VECTOR_TABLE to 0.\r
+#endif\r
+\r
/* A critical section is exited when the critical section nesting count reaches\r
this value. */\r
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )\r
#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )\r
\r
/* Constants required to setup the initial task context. */\r
-#define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */\r
+#warning FIQ is disabled\r
+#define portINITIAL_SPSR ( ( StackType_t ) 0x5f ) /* System mode, ARM mode, IRQ enabled FIQ disabled. 1f is required to enable FIQ. */\r
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )\r
#define portINTERRUPT_ENABLE_BIT ( 0x80UL )\r
#define portTHUMB_MODE_ADDRESS ( 0x01UL )\r
#define portCLEAR_INTERRUPT_MASK() \\r
{ \\r
__asm volatile ( "cpsid i" ); \\r
+ __asm volatile ( "dsb" ); \\r
+ __asm volatile ( "isb" ); \\r
portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE; \\r
__asm( "DSB \n" \\r
"ISB \n" ); \\r
__asm volatile( "cpsie i" ); \\r
+ __asm volatile ( "dsb" ); \\r
+ __asm volatile ( "isb" ); \\r
}\r
\r
+#define portINTERRUPT_PRIORITY_REGISTER_OFFSET 0x400UL\r
+#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff )\r
+#define portBIT_0_SET ( ( uint8_t ) 0x01 )\r
+\r
/*-----------------------------------------------------------*/\r
\r
/*\r
\r
__attribute__(( used )) const uint32_t ulICCIAR = portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS;\r
__attribute__(( used )) const uint32_t ulICCEOIR = portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS;\r
+__attribute__(( used )) const uint32_t ulICCPMR = portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS;\r
+__attribute__(( used )) const uint32_t ulMaxAPIPriorityMask = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );\r
\r
/*-----------------------------------------------------------*/\r
\r
{\r
uint32_t ulAPSR;\r
\r
+ #if( configASSERT_DEFINED == 1 )\r
+ {\r
+ volatile uint32_t ulOriginalPriority;\r
+ volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + portINTERRUPT_PRIORITY_REGISTER_OFFSET );\r
+ volatile uint8_t ucMaxPriorityValue;\r
+\r
+ /* Determine how many priority bits are implemented in the GIC.\r
+\r
+ Save the interrupt priority value that is about to be clobbered. */\r
+ ulOriginalPriority = *pucFirstUserPriorityRegister;\r
+\r
+ /* Determine the number of priority bits available. First write to\r
+ all possible bits. */\r
+ *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;\r
+\r
+ /* Read the value back to see how many bits stuck. */\r
+ ucMaxPriorityValue = *pucFirstUserPriorityRegister;\r
+\r
+ /* Shift to the least significant bits. */\r
+ while( ( ucMaxPriorityValue & portBIT_0_SET ) != portBIT_0_SET )\r
+ {\r
+ ucMaxPriorityValue >>= ( uint8_t ) 0x01;\r
+ }\r
+\r
+ /* Sanity check configUNIQUE_INTERRUPT_PRIORITIES matches the read\r
+ value. */\r
+ configASSERT( ucMaxPriorityValue == portLOWEST_INTERRUPT_PRIORITY );\r
+\r
+ /* Restore the clobbered interrupt priority register to its original\r
+ value. */\r
+ *pucFirstUserPriorityRegister = ulOriginalPriority;\r
+ }\r
+ #endif /* conifgASSERT_DEFINED */\r
+\r
+\r
/* Only continue if the CPU is not in User mode. The CPU must be in a\r
Privileged mode for the scheduler to start. */\r
__asm volatile ( "MRS %0, APSR" : "=r" ( ulAPSR ) );\r
ulAPSR &= portAPSR_MODE_BITS_MASK;\r
configASSERT( ulAPSR != portAPSR_USER_MODE );\r
\r
+ #if configINSTALL_FREERTOS_VECTOR_TABLE == 1\r
+ {\r
+ vPortInstallFreeRTOSVectorTable();\r
+ }\r
+ #endif\r
+\r
+\r
if( ulAPSR != portAPSR_USER_MODE )\r
{\r
/* Only continue if the binary point value is set to its lowest possible\r
/* Start the timer that generates the tick ISR. */\r
configSETUP_TICK_INTERRUPT();\r
\r
- __asm volatile( "cpsie i" );\r
+// __asm volatile( "cpsie i" );\r
vPortRestoreTaskContext();\r
}\r
}\r
handler runs at the lowest priority, so interrupts cannot already be masked,\r
so there is no need to save and restore the current mask value. */\r
__asm volatile( "cpsid i" );\r
+ __asm volatile ( "dsb" );\r
+ __asm volatile ( "isb" );\r
portICCPMR_PRIORITY_MASK_REGISTER = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );\r
__asm( "dsb \n"\r
"isb \n"\r
- "cpsie i ");\r
+ "cpsie i \n"\r
+ "dsb \n"\r
+ "isb" );\r
\r
/* Increment the RTOS tick. */\r
if( xTaskIncrementTick() != pdFALSE )\r
uint32_t ulReturn;\r
\r
__asm volatile ( "cpsid i" );\r
+ __asm volatile ( "dsb" );\r
+ __asm volatile ( "isb" );\r
if( portICCPMR_PRIORITY_MASK_REGISTER == ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) )\r
{\r
/* Interrupts were already masked. */\r
"isb \n" );\r
}\r
__asm volatile ( "cpsie i" );\r
+ __asm volatile ( "dsb" );\r
+ __asm volatile ( "isb" );\r
\r
return ulReturn;\r
}\r
#endif /* configASSERT_DEFINED */\r
/*-----------------------------------------------------------*/\r
\r
-void vPortRestoreTaskContext( void )\r
-{\r
-}\r
-\r
-void vPortRestoreContext( void )\r
-{\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-\r
*/\r
\r
\r
- .org 0\r
.text\r
\r
.set SYS_MODE, 0x1f\r
.set SVC_MODE, 0x13\r
.set IRQ_MODE, 0x12\r
\r
- .extern _boot\r
- .extern vTaskSwitchContext\r
.extern ulICCIAR\r
.extern ulICCEOIR\r
+ .extern ulMaxAPIPriorityMask\r
+ .extern ulICCPMR\r
+ .extern _freertos_vector_table\r
\r
- .global _vector_table\r
+ .global FreeRTOS_vector_table\r
.global FIQInterrupt\r
.global Undefined\r
.global PrefetchAbortHandler\r
.global DataAbortInterrupt\r
+\r
+ .extern pxCurrentTCB\r
+ .extern XIntc_DeviceInterruptHandler\r
+ .extern vTaskSwitchContext\r
+ .extern uxCriticalNesting\r
+ .extern pulISRStack\r
+ .extern ulTaskSwitchRequested\r
+ .extern vPortExceptionHandler\r
+ .extern pulStackPointerOnFunctionEntry\r
+\r
.global FreeRTOS_IRQ_Handler\r
.global FreeRTOS_SWI_Handler\r
+ .global vPortRestoreTaskContext\r
+ .global vPortInstallFreeRTOSVectorTable\r
+\r
+\r
+\r
+\r
+.macro portSAVE_CONTEXT\r
+\r
+ /* Save the LR and SPSR onto the system mode stack before switching to\r
+ system mode to save the remaining system mode registers. */\r
+ SRSDB sp!, #SYS_MODE\r
+ CPS #SYS_MODE\r
+ PUSH {R0-R12, R14}\r
+\r
+ /* Push the critical nesting count. */\r
+ LDR R2, =ulCriticalNesting\r
+ LDR R1, [R2]\r
+ PUSH {R1}\r
+\r
+ /* Does the task have a floating point context that needs saving? If\r
+ ulPortTaskHasFPUContext is 0 then no. */\r
+ LDR R2, =ulPortTaskHasFPUContext\r
+ LDR R3, [R2]\r
+ CMP R3, #0\r
+\r
+ /* Save the floating point context, if any. */\r
+ FMRXNE R1, FPSCR\r
+ VPUSHNE {D0-D15}\r
+ VPUSHNE {D16-D31}\r
+ PUSHNE {R1}\r
+\r
+ /* Save ulPortTaskHasFPUContext itself. */\r
+ PUSH {R3}\r
+\r
+ /* Save the stack pointer in the TCB. */\r
+ LDR R0, =pxCurrentTCB\r
+ LDR R1, [R0]\r
+ STR SP, [R1]\r
+\r
+ .endm\r
+\r
+; /**********************************************************************/\r
+\r
+.macro portRESTORE_CONTEXT\r
+\r
+ /* Switch to system mode. */\r
+ CPS #SYS_MODE\r
+\r
+ /* Set the SP to point to the stack of the task being restored. */\r
+ LDR R0, =pxCurrentTCB\r
+ LDR R1, [R0]\r
+ LDR SP, [R1]\r
+\r
+ /* Is there a floating point context to restore? If the restored\r
+ ulPortTaskHasFPUContext is zero then no. */\r
+ LDR R0, =ulPortTaskHasFPUContext\r
+ POP {R1}\r
+ STR R1, [R0]\r
+ CMP R1, #0\r
+\r
+ /* Restore the floating point context, if any. */\r
+ POPNE {R0}\r
+ VPOPNE {D16-D31}\r
+ VPOPNE {D0-D15}\r
+ VMSRNE FPSCR, R0\r
+\r
+ /* Restore the critical section nesting depth. */\r
+ LDR R0, =ulCriticalNesting\r
+ POP {R1}\r
+ STR R1, [R0]\r
+\r
+ /* Ensure the priority mask is correct for the critical nesting depth. */\r
+ LDR R2, =ulICCPMR\r
+ CMP R1, #0\r
+ MOVEQ R4, #255\r
+ LDRNE R4, =ulMaxAPIPriorityMask\r
+ STR R4, [r2]\r
+\r
+ /* Restore all system mode registers other than the SP (which is already\r
+ being used). */\r
+ POP {R0-R12, R14}\r
+\r
+ /* Return to the task code, loading CPSR on the way. */\r
+ RFEIA sp!\r
+\r
+ .endm\r
\r
- .section .vectors\r
\r
-_vector_table:\r
- B _boot\r
- B Undefined\r
- ldr pc, _swi\r
- B PrefetchAbortHandler\r
- B DataAbortHandler\r
- NOP /* Placeholder for address exception vector*/\r
- LDR PC, _irq\r
- B FIQHandler\r
\r
-_irq: .word FreeRTOS_IRQ_Handler\r
-_swi: .word FreeRTOS_SWI_Handler\r
\r
/******************************************************************************\r
* SVC handler is used to start the scheduler and yield a task.\r
FreeRTOS_SWI_Handler:\r
\r
/* Save the context of the current task and select a new task to run. */\r
-// portSAVE_CONTEXT\r
+ /* Save the LR and SPSR onto the system mode stack before switching to\r
+ system mode to save the remaining system mode registers. */\r
+ SRSDB sp!, #SYS_MODE\r
+ CPS #SYS_MODE\r
+ PUSH {R0-R12, R14}\r
+\r
+ /* Push the critical nesting count. */\r
+ LDR R2, =ulCriticalNesting\r
+ LDR R1, [R2]\r
+ PUSH {R1}\r
+\r
+ /* Does the task have a floating point context that needs saving? If\r
+ ulPortTaskHasFPUContext is 0 then no. */\r
+ LDR R2, =ulPortTaskHasFPUContext\r
+ LDR R3, [R2]\r
+ CMP R3, #0\r
+\r
+ /* Save the floating point context, if any. */\r
+ FMRXNE R1, FPSCR\r
+ VPUSHNE {D0-D15}\r
+ VPUSHNE {D16-D31}\r
+ PUSHNE {R1}\r
+\r
+ /* Save ulPortTaskHasFPUContext itself. */\r
+ PUSH {R3}\r
+\r
+ /* Save the stack pointer in the TCB. */\r
+ LDR R0, =pxCurrentTCB\r
+ LDR R1, [R0]\r
+ STR SP, [R1]\r
+\r
LDR R0, =vTaskSwitchContext\r
BLX R0\r
\r
vPortRestoreTaskContext:\r
-// portRESTORE_CONTEXT\r
+ portRESTORE_CONTEXT\r
\r
FreeRTOS_IRQ_Handler:\r
/* Return to the interrupted instruction. */\r
POP {LR}\r
MSR SPSR_cxsf, LR\r
POP {LR}\r
-// portSAVE_CONTEXT\r
+ portSAVE_CONTEXT\r
\r
/* Call the function that selects the new task to execute.\r
vTaskSwitchContext() if vTaskSwitchContext() uses LDRD or STRD\r
\r
/* Restore the context of, and branch to, the task selected to execute\r
next. */\r
-// portRESTORE_CONTEXT\r
+ portRESTORE_CONTEXT\r
\r
ulICCIARConst: .word ulICCIAR\r
ulICCEOIRConst: .word ulICCEOIR\r
\r
+vPortInstallFreeRTOSVectorTable:\r
+ /* Set VBAR to the vector table that contains the FreeRTOS handlers. */\r
+ ldr r0, =_freertos_vector_table\r
+ mcr p15, 0, r0, c12, c0, 0\r
+ dsb\r
+ isb\r
+ bx lr\r
\r
-Undefined:\r
- B .\r
-\r
-PrefetchAbortHandler:\r
- B .\r
-\r
-FIQHandler:\r
- B .\r
-\r
-DataAbortHandler:\r
- B .\r
\r
.end\r
\r
+++ /dev/null
-;/*\r
-; FreeRTOS V8.0.0:rc1 - Copyright (C) 2014 Real Time Engineers Ltd.\r
-; All rights reserved\r
-;\r
-;\r
-; ***************************************************************************\r
-; * *\r
-; * FreeRTOS tutorial books are available in pdf and paperback. *\r
-; * Complete, revised, and edited pdf reference manuals are also *\r
-; * available. *\r
-; * *\r
-; * Purchasing FreeRTOS documentation will not only help you, by *\r
-; * ensuring you get running as quickly as possible and with an *\r
-; * in-depth knowledge of how to use FreeRTOS, it will also help *\r
-; * the FreeRTOS project to continue with its mission of providing *\r
-; * professional grade, cross platform, de facto standard solutions *\r
-; * for microcontrollers - completely free of charge! *\r
-; * *\r
-; * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
-; * *\r
-; * Thank you for using FreeRTOS, and thank you for your support! *\r
-; * *\r
-; ***************************************************************************\r
-;\r
-;\r
-; This file is part of the FreeRTOS distribution.\r
-;\r
-; FreeRTOS is free software; you can redistribute it and/or modify it under\r
-; the terms of the GNU General Public License (version 2) as published by the\r
-; Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
-; >>>NOTE<<< The modification to the GPL is included to allow you to\r
-; distribute a combined work that includes FreeRTOS without being obliged to\r
-; provide the source code for proprietary components outside of the FreeRTOS\r
-; kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
-; WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
-; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
-; more details. You should have received a copy of the GNU General Public\r
-; License and the FreeRTOS license exception along with FreeRTOS; if not it\r
-; can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
-; by writing to Richard Barry, contact details for whom are available on the\r
-; FreeRTOS WEB site.\r
-;\r
-; 1 tab == 4 spaces!\r
-;\r
-; http://www.FreeRTOS.org - Documentation, latest information, license and\r
-; contact details.\r
-;\r
-; http://www.SafeRTOS.com - A version that is certified for use in safety\r
-; critical systems.\r
-;\r
-; http://www.OpenRTOS.com - Commercial support, development, porting,\r
-; licensing and training services.\r
-;*/\r
-\r
- EXTERN vTaskSwitchContext\r
- EXTERN ulCriticalNesting\r
- EXTERN pxCurrentTCB\r
- EXTERN ulPortTaskHasFPUContext\r
- EXTERN ulAsmAPIPriorityMask\r
-\r
-portSAVE_CONTEXT macro\r
-\r
- ; Save the LR and SPSR onto the system mode stack before switching to\r
- ; system mode to save the remaining system mode registers\r
- SRSDB sp!, #SYS_MODE\r
- CPS #SYS_MODE\r
- PUSH {R0-R12, R14}\r
-\r
- ; Push the critical nesting count\r
- LDR R2, =ulCriticalNesting\r
- LDR R1, [R2]\r
- PUSH {R1}\r
-\r
- ; Does the task have a floating point context that needs saving? If\r
- ; ulPortTaskHasFPUContext is 0 then no.\r
- LDR R2, =ulPortTaskHasFPUContext\r
- LDR R3, [R2]\r
- CMP R3, #0\r
-\r
- ; Save the floating point context, if any\r
- FMRXNE R1, FPSCR\r
- VPUSHNE {D0-D15}\r
- VPUSHNE {D16-D31}\r
- PUSHNE {R1}\r
-\r
- ; Save ulPortTaskHasFPUContext itself\r
- PUSH {R3}\r
-\r
- ; Save the stack pointer in the TCB\r
- LDR R0, =pxCurrentTCB\r
- LDR R1, [R0]\r
- STR SP, [R1]\r
-\r
- endm\r
-\r
-; /**********************************************************************/\r
-\r
-portRESTORE_CONTEXT macro\r
-\r
- ; Switch to system mode\r
- CPS #SYS_MODE\r
-\r
- ; Set the SP to point to the stack of the task being restored.\r
- LDR R0, =pxCurrentTCB\r
- LDR R1, [R0]\r
- LDR SP, [R1]\r
-\r
- ; Is there a floating point context to restore? If the restored\r
- ; ulPortTaskHasFPUContext is zero then no.\r
- LDR R0, =ulPortTaskHasFPUContext\r
- POP {R1}\r
- STR R1, [R0]\r
- CMP R1, #0\r
-\r
- ; Restore the floating point context, if any\r
- LDMFDNE SP!, {R0}\r
- VPOPNE {D16-D31}\r
- VPOPNE {D0-D15}\r
- VMSRNE FPSCR, R0\r
-\r
- ; Restore the critical section nesting depth\r
- LDR R0, =ulCriticalNesting\r
- POP {R1}\r
- STR R1, [R0]\r
-\r
- ; Ensure the priority mask is correct for the critical nesting depth\r
- LDR R2, =portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS\r
- CMP R1, #0\r
- MOVEQ R4, #255\r
- LDRNE R4, =( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT )\r
- STR R4, [r2]\r
-\r
- ; Restore all system mode registers other than the SP (which is already\r
- ; being used)\r
- POP {R0-R12, R14}\r
-\r
- ; Return to the task code, loading CPSR on the way.\r
- RFEIA sp!\r
-\r
- endm\r
-\r
-\r
-\r
-\r
-\r