From c3ad5844ac02866e0ca3710c6ac4531af973c006 Mon Sep 17 00:00:00 2001 From: rtel Date: Thu, 27 Sep 2018 17:25:17 +0000 Subject: [PATCH] RISC-V tasks now context switching to each other using taskYIELD() - not fully tested yet. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2585 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- .../Source/portable/GCC/RISC-V-RV32/port.c | 18 +- .../Source/portable/GCC/RISC-V-RV32/portASM.S | 207 +++++++++--------- .../portable/GCC/RISC-V-RV32/portmacro.h | 2 +- 3 files changed, 121 insertions(+), 106 deletions(-) diff --git a/FreeRTOS/Source/portable/GCC/RISC-V-RV32/port.c b/FreeRTOS/Source/portable/GCC/RISC-V-RV32/port.c index 5e66d08c4..24611a9be 100644 --- a/FreeRTOS/Source/portable/GCC/RISC-V-RV32/port.c +++ b/FreeRTOS/Source/portable/GCC/RISC-V-RV32/port.c @@ -50,14 +50,14 @@ static void prvTaskExitError( void ); /* Used to program the machine timer compare register. */ static uint64_t ullNextTime = 0ULL; -static volatile uint64_t * const pullMachineTimerCompareRegister = ( volatile uint64_t * const ) 0x2004000; +static volatile uint64_t * const pullMachineTimerCompareRegister = ( volatile uint64_t * const ) ( configCTRL_BASE + 0x4000 ); /*-----------------------------------------------------------*/ void prvTaskExitError( void ) { volatile uint32_t ulx = 0; -#warning prvTaskExitError not used yet. + /* A function that implements a task must not exit or attempt to return to its caller as there is nothing to return to. If a task wants to exit it should instead call vTaskDelete( NULL ). @@ -154,6 +154,8 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px // pxTopOfStack--; // *pxTopOfStack = ( StackType_t ) 2; /* Stack pointer. */ // pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) prvTaskExitError; + pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; return pxTopOfStack; @@ -163,8 +165,8 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px void vPortSetupTimerInterrupt( void ) { uint32_t ulCurrentTimeHigh, ulCurrentTimeLow; -volatile uint32_t * const pulTimeHigh = ( volatile uint32_t * const ) 0x200BFF8; -volatile uint32_t * const pulTimeLow = ( volatile uint32_t * const ) 0x200BFFc; +volatile uint32_t * const pulTimeHigh = ( volatile uint32_t * const ) ( configCTRL_BASE + 0xBFF8 ); +volatile uint32_t * const pulTimeLow = ( volatile uint32_t * const ) ( configCTRL_BASE + 0xBFFc ); do { @@ -185,9 +187,13 @@ volatile uint32_t * const pulTimeLow = ( volatile uint32_t * const ) 0x200BFFc; void Software_IRQHandler( void ) { - vTaskSwitchContext(); -} +volatile uint32_t * const ulSoftInterrupt = ( uint32_t * ) configCTRL_BASE; + vTaskSwitchContext(); + /* Clear software interrupt. */ + *ulSoftInterrupt = 0UL; +} +/*-----------------------------------------------------------*/ diff --git a/FreeRTOS/Source/portable/GCC/RISC-V-RV32/portASM.S b/FreeRTOS/Source/portable/GCC/RISC-V-RV32/portASM.S index d86757e8c..5efe94f07 100644 --- a/FreeRTOS/Source/portable/GCC/RISC-V-RV32/portASM.S +++ b/FreeRTOS/Source/portable/GCC/RISC-V-RV32/portASM.S @@ -47,80 +47,83 @@ .align 8 xPortStartScheduler: - lw sp, pxCurrentTCB /* Load pxCurrentTCB. */ - lw sp, 0( sp ) /* Read sp from first TCB member. */ - lw x1, 0( sp ) - lw x5, 1 * WORD_SIZE( sp ) /* t0 */ - lw x6, 2 * WORD_SIZE( sp ) /* t1 */ - lw x7, 3 * WORD_SIZE( sp ) /* t2 */ - lw x8, 4 * WORD_SIZE( sp ) /* s0/fp */ - lw x9, 5 * WORD_SIZE( sp ) /* s1 */ - lw x10, 6 * WORD_SIZE( sp ) /* a0 */ - lw x11, 7 * WORD_SIZE( sp ) /* a1 */ - lw x12, 8 * WORD_SIZE( sp ) /* a2 */ - lw x13, 9 * WORD_SIZE( sp ) /* a3 */ - lw x14, 10 * WORD_SIZE( sp ) /* a4 */ - lw x15, 11 * WORD_SIZE( sp ) /* a5 */ - lw x16, 12 * WORD_SIZE( sp ) /* a6 */ - lw x17, 13 * WORD_SIZE( sp ) /* a7 */ - lw x18, 14 * WORD_SIZE( sp ) /* s2 */ - lw x19, 15 * WORD_SIZE( sp ) /* s3 */ - lw x20, 16 * WORD_SIZE( sp ) /* s4 */ - lw x21, 17 * WORD_SIZE( sp ) /* s5 */ - lw x22, 18 * WORD_SIZE( sp ) /* s6 */ - lw x23, 19 * WORD_SIZE( sp ) /* s7 */ - lw x24, 20 * WORD_SIZE( sp ) /* s8 */ - lw x25, 21 * WORD_SIZE( sp ) /* s9 */ - lw x26, 22 * WORD_SIZE( sp ) /* s10 */ - lw x27, 23 * WORD_SIZE( sp ) /* s11 */ - lw x28, 24 * WORD_SIZE( sp ) /* t3 */ - lw x29, 25 * WORD_SIZE( sp ) /* t4 */ - lw x30, 26 * WORD_SIZE( sp ) /* t5 */ - lw x31, 27 * WORD_SIZE( sp ) /* t6 */ - addi sp, sp, CONTEXT_SIZE - csrs mie, 8 /* Enable soft interrupt. */ - csrs mstatus, 8 /* Enable interrupts. */ - ret + lw sp, pxCurrentTCB /* Load pxCurrentTCB. */ + lw sp, 0( sp ) /* Read sp from first TCB member. */ + + lw x1, 0( sp ) /* Note for starting the scheduler the exception return address is used as the function return address. */ + lw x5, 2 * WORD_SIZE( sp ) /* t0 */ + lw x6, 3 * WORD_SIZE( sp ) /* t1 */ + lw x7, 4 * WORD_SIZE( sp ) /* t2 */ + lw x8, 5 * WORD_SIZE( sp ) /* s0/fp */ + lw x9, 6 * WORD_SIZE( sp ) /* s1 */ + lw x10, 7 * WORD_SIZE( sp ) /* a0 */ + lw x11, 8 * WORD_SIZE( sp ) /* a1 */ + lw x12, 9 * WORD_SIZE( sp ) /* a2 */ + lw x13, 10 * WORD_SIZE( sp ) /* a3 */ + lw x14, 11 * WORD_SIZE( sp ) /* a4 */ + lw x15, 12 * WORD_SIZE( sp ) /* a5 */ + lw x16, 13 * WORD_SIZE( sp ) /* a6 */ + lw x17, 14 * WORD_SIZE( sp ) /* a7 */ + lw x18, 15 * WORD_SIZE( sp ) /* s2 */ + lw x19, 16 * WORD_SIZE( sp ) /* s3 */ + lw x20, 17 * WORD_SIZE( sp ) /* s4 */ + lw x21, 18 * WORD_SIZE( sp ) /* s5 */ + lw x22, 19 * WORD_SIZE( sp ) /* s6 */ + lw x23, 20 * WORD_SIZE( sp ) /* s7 */ + lw x24, 21 * WORD_SIZE( sp ) /* s8 */ + lw x25, 22 * WORD_SIZE( sp ) /* s9 */ + lw x26, 23 * WORD_SIZE( sp ) /* s10 */ + lw x27, 24 * WORD_SIZE( sp ) /* s11 */ + lw x28, 25 * WORD_SIZE( sp ) /* t3 */ + lw x29, 26 * WORD_SIZE( sp ) /* t4 */ + lw x30, 27 * WORD_SIZE( sp ) /* t5 */ + lw x31, 28 * WORD_SIZE( sp ) /* t6 */ + addi sp, sp, CONTEXT_SIZE + csrs mstatus, 8 /* Enable machine interrupts. */ + csrs mie, 8 /* Enable soft interrupt. */ + ret /*-----------------------------------------------------------*/ .align 8 vPortTrapHandler: addi sp, sp, -CONTEXT_SIZE - sw x1, 0( sp ) - sw x5, 1 * WORD_SIZE( sp ) - sw x6, 2 * WORD_SIZE( sp ) - sw x7, 3 * WORD_SIZE( sp ) - sw x8, 4 * WORD_SIZE( sp ) - sw x9, 5 * WORD_SIZE( sp ) - sw x10, 6 * WORD_SIZE( sp ) - sw x11, 7 * WORD_SIZE( sp ) - sw x12, 8 * WORD_SIZE( sp ) - sw x13, 9 * WORD_SIZE( sp ) - sw x14, 10 * WORD_SIZE( sp ) - sw x15, 11 * WORD_SIZE( sp ) - sw x16, 12 * WORD_SIZE( sp ) - sw x17, 13 * WORD_SIZE( sp ) - sw x18, 14 * WORD_SIZE( sp ) - sw x19, 15 * WORD_SIZE( sp ) - sw x20, 16 * WORD_SIZE( sp ) - sw x21, 17 * WORD_SIZE( sp ) - sw x22, 18 * WORD_SIZE( sp ) - sw x23, 19 * WORD_SIZE( sp ) - sw x24, 20 * WORD_SIZE( sp ) - sw x25, 21 * WORD_SIZE( sp ) - sw x26, 22 * WORD_SIZE( sp ) - sw x27, 23 * WORD_SIZE( sp ) - sw x28, 24 * WORD_SIZE( sp ) - sw x29, 25 * WORD_SIZE( sp ) - sw x30, 26 * WORD_SIZE( sp ) - sw x31, 27 * WORD_SIZE( sp ) + sw x1, 1( sp ) + sw x5, 2 * WORD_SIZE( sp ) + sw x6, 3 * WORD_SIZE( sp ) + sw x7, 4 * WORD_SIZE( sp ) + sw x8, 5 * WORD_SIZE( sp ) + sw x9, 6 * WORD_SIZE( sp ) + sw x10, 7 * WORD_SIZE( sp ) + sw x11, 8 * WORD_SIZE( sp ) + sw x12, 9 * WORD_SIZE( sp ) + sw x13, 10 * WORD_SIZE( sp ) + sw x14, 11 * WORD_SIZE( sp ) + sw x15, 12 * WORD_SIZE( sp ) + sw x16, 13 * WORD_SIZE( sp ) + sw x17, 14 * WORD_SIZE( sp ) + sw x18, 15 * WORD_SIZE( sp ) + sw x19, 16 * WORD_SIZE( sp ) + sw x20, 17 * WORD_SIZE( sp ) + sw x21, 18 * WORD_SIZE( sp ) + sw x22, 19 * WORD_SIZE( sp ) + sw x23, 20 * WORD_SIZE( sp ) + sw x24, 21 * WORD_SIZE( sp ) + sw x25, 22 * WORD_SIZE( sp ) + sw x26, 23 * WORD_SIZE( sp ) + sw x27, 24 * WORD_SIZE( sp ) + sw x28, 25 * WORD_SIZE( sp ) + sw x29, 26 * WORD_SIZE( sp ) + sw x30, 27 * WORD_SIZE( sp ) + sw x31, 28 * WORD_SIZE( sp ) + + /* Save exception return address. */ + csrr t0, mepc + sw t0, 0( sp ) + lw t0, pxCurrentTCB /* Load pxCurrentTCB. */ sw sp, 0( t0 ) /* Write sp from first TCB member. */ - csrr t0, mepc - sw t0, 31 * WORD_SIZE( sp ) - csrr a0, mcause csrr a1, mepc mv a2, sp @@ -131,37 +134,43 @@ vPortTrapHandler: li t0, 0x00001800 /* MSTATUS MPP */ csrs mstatus, t0 - /* Cut and past restore code from xPortStartScheduler - can be made a macro - but that makes debugging harder. */ - lw sp, pxCurrentTCB /* Load pxCurrentTCB. */ - lw sp, 0( sp ) /* Read sp from first TCB member. */ - lw x1, 0( sp ) - lw x5, 1 * WORD_SIZE( sp ) /* t0 */ - lw x6, 2 * WORD_SIZE( sp ) /* t1 */ - lw x7, 3 * WORD_SIZE( sp ) /* t2 */ - lw x8, 4 * WORD_SIZE( sp ) /* s0/fp */ - lw x9, 5 * WORD_SIZE( sp ) /* s1 */ - lw x10, 6 * WORD_SIZE( sp ) /* a0 */ - lw x11, 7 * WORD_SIZE( sp ) /* a1 */ - lw x12, 8 * WORD_SIZE( sp ) /* a2 */ - lw x13, 9 * WORD_SIZE( sp ) /* a3 */ - lw x14, 10 * WORD_SIZE( sp ) /* a4 */ - lw x15, 11 * WORD_SIZE( sp ) /* a5 */ - lw x16, 12 * WORD_SIZE( sp ) /* a6 */ - lw x17, 13 * WORD_SIZE( sp ) /* a7 */ - lw x18, 14 * WORD_SIZE( sp ) /* s2 */ - lw x19, 15 * WORD_SIZE( sp ) /* s3 */ - lw x20, 16 * WORD_SIZE( sp ) /* s4 */ - lw x21, 17 * WORD_SIZE( sp ) /* s5 */ - lw x22, 18 * WORD_SIZE( sp ) /* s6 */ - lw x23, 19 * WORD_SIZE( sp ) /* s7 */ - lw x24, 20 * WORD_SIZE( sp ) /* s8 */ - lw x25, 21 * WORD_SIZE( sp ) /* s9 */ - lw x26, 22 * WORD_SIZE( sp ) /* s10 */ - lw x27, 23 * WORD_SIZE( sp ) /* s11 */ - lw x28, 24 * WORD_SIZE( sp ) /* t3 */ - lw x29, 25 * WORD_SIZE( sp ) /* t4 */ - lw x30, 26 * WORD_SIZE( sp ) /* t5 */ - lw x31, 27 * WORD_SIZE( sp ) /* t6 */ - addi sp, sp, CONTEXT_SIZE - mret + lw sp, pxCurrentTCB /* Load pxCurrentTCB. */ + lw sp, 0( sp ) /* Read sp from first TCB member. */ + + /* Load mret with the address of the first task. */ + lw t0, 0( sp ) + csrw mepc, t0 + + lw x1, 1( sp ) + lw x5, 2 * WORD_SIZE( sp ) /* t0 */ + lw x6, 3 * WORD_SIZE( sp ) /* t1 */ + lw x7, 4 * WORD_SIZE( sp ) /* t2 */ + lw x8, 5 * WORD_SIZE( sp ) /* s0/fp */ + lw x9, 6 * WORD_SIZE( sp ) /* s1 */ + lw x10, 7 * WORD_SIZE( sp ) /* a0 */ + lw x11, 8 * WORD_SIZE( sp ) /* a1 */ + lw x12, 9 * WORD_SIZE( sp ) /* a2 */ + lw x13, 10 * WORD_SIZE( sp ) /* a3 */ + lw x14, 11 * WORD_SIZE( sp ) /* a4 */ + lw x15, 12 * WORD_SIZE( sp ) /* a5 */ + lw x16, 13 * WORD_SIZE( sp ) /* a6 */ + lw x17, 14 * WORD_SIZE( sp ) /* a7 */ + lw x18, 15 * WORD_SIZE( sp ) /* s2 */ + lw x19, 16 * WORD_SIZE( sp ) /* s3 */ + lw x20, 17 * WORD_SIZE( sp ) /* s4 */ + lw x21, 18 * WORD_SIZE( sp ) /* s5 */ + lw x22, 19 * WORD_SIZE( sp ) /* s6 */ + lw x23, 20 * WORD_SIZE( sp ) /* s7 */ + lw x24, 21 * WORD_SIZE( sp ) /* s8 */ + lw x25, 22 * WORD_SIZE( sp ) /* s9 */ + lw x26, 23 * WORD_SIZE( sp ) /* s10 */ + lw x27, 24 * WORD_SIZE( sp ) /* s11 */ + lw x28, 25 * WORD_SIZE( sp ) /* t3 */ + lw x29, 26 * WORD_SIZE( sp ) /* t4 */ + lw x30, 27 * WORD_SIZE( sp ) /* t5 */ + lw x31, 28 * WORD_SIZE( sp ) /* t6 */ + addi sp, sp, CONTEXT_SIZE + + mret + + diff --git a/FreeRTOS/Source/portable/GCC/RISC-V-RV32/portmacro.h b/FreeRTOS/Source/portable/GCC/RISC-V-RV32/portmacro.h index 7132bf4ba..a256d5b0c 100644 --- a/FreeRTOS/Source/portable/GCC/RISC-V-RV32/portmacro.h +++ b/FreeRTOS/Source/portable/GCC/RISC-V-RV32/portmacro.h @@ -70,7 +70,7 @@ not need to be guarded with a critical section. */ /* Scheduler utilities. */ -#define portYIELD() { volatile uint32_t * const ulSoftInterrupt = ( uint32_t * ) 0x2000000; *ulSoftInterrupt = 1UL; } +#define portYIELD() { volatile uint32_t * const ulSoftInterrupt = ( uint32_t * ) configCTRL_BASE; *ulSoftInterrupt = 1UL; } #define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vPortYield() #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ -- 2.39.5