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 )

 /*-----------------------------------------------------------*/