Continue work on GCC/Cortex-A port layer.

pull/1/head
Richard Barry 11 years ago
parent 4c9b5d88ae
commit 14f895478d

@ -147,18 +147,28 @@ point is zero. */
mode. */ mode. */
#define portAPSR_USER_MODE ( 0x10 ) #define portAPSR_USER_MODE ( 0x10 )
/* The critical section macros only mask interrupts up to an application
determined priority level. Sometimes it is necessary to turn interrupt off in
the CPU itself before modifying certain hardware registers. */
#define portCPU_IRQ_DISABLE() \
__asm volatile ( "CPSID i" ); \
__asm volatile ( "DSB" ); \
__asm volatile ( "ISB" );
#define portCPU_IRQ_ENABLE() \
__asm volatile ( "CPSIE i" ); \
__asm volatile ( "DSB" ); \
__asm volatile ( "ISB" );
/* Macro to unmask all interrupt priorities. */ /* Macro to unmask all interrupt priorities. */
#define portCLEAR_INTERRUPT_MASK() \ #define portCLEAR_INTERRUPT_MASK() \
{ \ { \
__asm volatile ( "cpsid i" ); \ portCPU_IRQ_DISABLE(); \
__asm volatile ( "dsb" ); \
__asm volatile ( "isb" ); \
portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE; \ portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE; \
__asm( "DSB \n" \ __asm( "DSB \n" \
"ISB \n" ); \ "ISB \n" ); \
__asm volatile( "cpsie i" ); \ portCPU_IRQ_ENABLE(); \
__asm volatile ( "dsb" ); \
__asm volatile ( "isb" ); \
} }
#define portINTERRUPT_PRIORITY_REGISTER_OFFSET 0x400UL #define portINTERRUPT_PRIORITY_REGISTER_OFFSET 0x400UL
@ -322,6 +332,8 @@ uint32_t ulAPSR;
#if configINSTALL_FREERTOS_VECTOR_TABLE == 1 #if configINSTALL_FREERTOS_VECTOR_TABLE == 1
{ {
extern void vPortInstallFreeRTOSVectorTable( void );
vPortInstallFreeRTOSVectorTable(); vPortInstallFreeRTOSVectorTable();
} }
#endif #endif
@ -336,11 +348,12 @@ uint32_t ulAPSR;
if( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE ) if( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE )
{ {
/* Start the timer that generates the tick ISR. */ /* Start the timer that generates the tick ISR. Interrupts are
__asm volatile( "cpsid i" ); turned off in the CPU itself to ensure the tick does not execute
while the scheduler is being started. Interrupts are automatically
turned back on in the CPU when the first task starts executing. */
portCPU_IRQ_DISABLE();
configSETUP_TICK_INTERRUPT(); configSETUP_TICK_INTERRUPT();
// __asm volatile( "cpsie i" );
vPortRestoreTaskContext(); vPortRestoreTaskContext();
} }
} }
@ -362,7 +375,7 @@ void vPortEndScheduler( void )
void vPortEnterCritical( void ) void vPortEnterCritical( void )
{ {
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */ /* Mask interrupts up to the max syscall interrupt priority. */
ulPortSetInterruptMask(); ulPortSetInterruptMask();
/* Now interrupts are disabled ulCriticalNesting can be accessed /* Now interrupts are disabled ulCriticalNesting can be accessed
@ -396,16 +409,14 @@ void FreeRTOS_Tick_Handler( void )
{ {
/* Set interrupt mask before altering scheduler structures. The tick /* Set interrupt mask before altering scheduler structures. The tick
handler runs at the lowest priority, so interrupts cannot already be masked, handler runs at the lowest priority, so interrupts cannot already be masked,
so there is no need to save and restore the current mask value. */ so there is no need to save and restore the current mask value. It is
__asm volatile( "cpsid i" ); necessary to turn off interrupts in the CPU itself while the ICCPMR is being
__asm volatile ( "dsb" ); updated. */
__asm volatile ( "isb" ); portCPU_IRQ_DISABLE();
portICCPMR_PRIORITY_MASK_REGISTER = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ); portICCPMR_PRIORITY_MASK_REGISTER = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
__asm( "dsb \n" __asm( "dsb \n"
"isb \n" "isb \n" );
"cpsie i \n" portCPU_IRQ_ENABLE();
"dsb \n"
"isb" );
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
@ -444,9 +455,9 @@ uint32_t ulPortSetInterruptMask( void )
{ {
uint32_t ulReturn; uint32_t ulReturn;
__asm volatile ( "cpsid i" ); /* Interrupt in the CPU must be turned off while the ICCPMR is being
__asm volatile ( "dsb" ); updated. */
__asm volatile ( "isb" ); portCPU_IRQ_DISABLE();
if( portICCPMR_PRIORITY_MASK_REGISTER == ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) ) if( portICCPMR_PRIORITY_MASK_REGISTER == ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) )
{ {
/* Interrupts were already masked. */ /* Interrupts were already masked. */
@ -459,9 +470,7 @@ uint32_t ulReturn;
__asm( "dsb \n" __asm( "dsb \n"
"isb \n" ); "isb \n" );
} }
__asm volatile ( "cpsie i" ); portCPU_IRQ_ENABLE();
__asm volatile ( "dsb" );
__asm volatile ( "isb" );
return ulReturn; return ulReturn;
} }

@ -256,6 +256,8 @@ FreeRTOS_IRQ_Handler:
ADD sp, sp, r2 ADD sp, sp, r2
CPSID i CPSID i
DSB
ISB
/* Write the value read from ICCIAR to ICCEOIR. */ /* Write the value read from ICCIAR to ICCEOIR. */
LDR r4, ulICCEOIRConst LDR r4, ulICCEOIRConst

Loading…
Cancel
Save