\r
/* Used to program the machine timer compare register. */\r
static uint64_t ullNextTime = 0ULL;\r
+static const uint64_t ullTimerIncrementsForOneTick = ( uint64_t ) ( configCPU_CLOCK_HZ / configTICK_RATE_HZ );\r
static volatile uint64_t * const pullMachineTimerCompareRegister = ( volatile uint64_t * const ) ( configCTRL_BASE + 0x4000 );\r
\r
/*-----------------------------------------------------------*/\r
void vPortSetupTimerInterrupt( void )\r
{\r
uint32_t ulCurrentTimeHigh, ulCurrentTimeLow;\r
-volatile uint32_t * const pulTimeHigh = ( volatile uint32_t * const ) ( configCTRL_BASE + 0xBFF8 );\r
-volatile uint32_t * const pulTimeLow = ( volatile uint32_t * const ) ( configCTRL_BASE + 0xBFFc );\r
+volatile uint32_t * const pulTimeHigh = ( volatile uint32_t * const ) ( configCTRL_BASE + 0xBFFC );\r
+volatile uint32_t * const pulTimeLow = ( volatile uint32_t * const ) ( configCTRL_BASE + 0xBFF8 );\r
\r
do\r
{\r
ullNextTime = ( uint64_t ) ulCurrentTimeHigh;\r
ullNextTime <<= 32ULL;\r
ullNextTime |= ( uint64_t ) ulCurrentTimeLow;\r
- ullNextTime += ( configCPU_CLOCK_HZ / configTICK_RATE_HZ );\r
+ ullNextTime += ullTimerIncrementsForOneTick;\r
*pullMachineTimerCompareRegister = ullNextTime;\r
\r
+ /* Prepare the time to use after the next tick interrupt. */\r
+ ullNextTime += ullTimerIncrementsForOneTick;\r
+\r
/* Enable timer interrupt */\r
__asm volatile( "csrs mie, %0" :: "r"(0x80) );\r
}\r
vTaskSwitchContext();\r
\r
/* Clear software interrupt. */\r
- *ulSoftInterrupt = 0UL;\r
+ *( ( uint32_t * ) configCTRL_BASE ) = 0UL;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void Timer_IRQHandler( void )\r
+{\r
+ /* Reload for the next timer interrupt. */\r
+ *pullMachineTimerCompareRegister = ullNextTime;\r
+ ullNextTime += ullTimerIncrementsForOneTick;\r
+\r
+ if( xTaskIncrementTick() != pdFALSE )\r
+ {\r
+ portYIELD();\r
+ }\r
}\r
/*-----------------------------------------------------------*/\r
\r
+BaseType_t xPortStartScheduler( void )\r
+{\r
+extern void xPortStartFirstTask( void );\r
+\r
+ vPortSetupTimerInterrupt();\r
+ xPortStartFirstTask();\r
+\r
+ /* Should not get here as after calling xPortStartFirstTask() only tasks\r
+ should be executing. */\r
+ return pdFAIL;\r
+}\r
+\r
+\r
\r
\r
#define CONTEXT_SIZE ( 28 * WORD_SIZE )\r
\r
-.global xPortStartScheduler\r
+.global xPortStartFirstTask\r
.global vPortTrapHandler\r
.extern pxCurrentTCB\r
.extern handle_trap\r
/*-----------------------------------------------------------*/\r
\r
.align 8\r
-xPortStartScheduler:\r
+xPortStartFirstTask:\r
+\r
lw sp, pxCurrentTCB /* Load pxCurrentTCB. */\r
lw sp, 0( sp ) /* Read sp from first TCB member. */\r
\r
addi sp, sp, CONTEXT_SIZE\r
csrs mstatus, 8 /* Enable machine interrupts. */\r
csrs mie, 8 /* Enable soft interrupt. */\r
- ret\r
+ ret\r
\r
/*-----------------------------------------------------------*/\r
\r
\r
\r
/* Scheduler utilities. */\r
-#define portYIELD() { volatile uint32_t * const ulSoftInterrupt = ( uint32_t * ) configCTRL_BASE; *ulSoftInterrupt = 1UL; }\r
+#define portYIELD() *( ( uint32_t * ) configCTRL_BASE ) = 1UL\r
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vPortYield()\r
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )\r
/*-----------------------------------------------------------*/\r
#define portCRITICAL_NESTING_IN_TCB 1\r
extern int vPortSetInterruptMask( void );\r
extern void vPortClearInterruptMask( int );\r
+extern void vTaskEnterCritical( void );\r
+extern void vTaskExitCritical( void );\r
\r
#define portSET_INTERRUPT_MASK_FROM_ISR() 0\r
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue )\r
-#define portDISABLE_INTERRUPTS()\r
-#define portENABLE_INTERRUPTS()\r
-#define portENTER_CRITICAL()\r
-#define portEXIT_CRITICAL()\r
+#define portDISABLE_INTERRUPTS() __asm volatile( "csrc mstatus, 8" )\r
+#define portENABLE_INTERRUPTS() __asm volatile( "csrs mstatus, 8" )\r
+#define portENTER_CRITICAL() vTaskEnterCritical()\r
+#define portEXIT_CRITICAL() vTaskExitCritical()\r
\r
/*-----------------------------------------------------------*/\r
\r