RISC-V tasks now context switching to each other using taskYIELD() - not fully tested yet.
diff --git a/FreeRTOS/Source/portable/GCC/RISC-V-RV32/port.c b/FreeRTOS/Source/portable/GCC/RISC-V-RV32/port.c
index 5e66d08..24611a9 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 @@
/* 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 @@
// pxTopOfStack--;
// *pxTopOfStack = ( StackType_t ) 2; /* Stack pointer. */
// pxTopOfStack--;
+ *pxTopOfStack = ( StackType_t ) prvTaskExitError;
+ pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) pxCode;
return pxTopOfStack;
@@ -163,8 +165,8 @@
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 @@
void Software_IRQHandler( void )
{
+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 d86757e..5efe94f 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 @@
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 7132bf4..a256d5b 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 @@
/* 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 )
/*-----------------------------------------------------------*/