riscv: add generic way to detect if inside interrupt context

This commit is contained in:
brendan 2026-08-27 11:16:48 +08:00
parent 8be86d4a24
commit 50013cf591
4 changed files with 33 additions and 2 deletions

View file

@ -97,6 +97,12 @@ volatile uint64_t * pullMachineTimerCompareRegister = NULL;
size_t xCriticalNesting = ( size_t ) 0xaaaaaaaa;
size_t * pxCriticalNesting = &xCriticalNesting;
/*
* Counts the interrupt nesting depth.
*/
size_t xInterruptNesting = 0;
size_t * pxInterruptNesting = &xInterruptNesting;
/* Used to catch tasks that attempt to return from their implementing function. */
size_t xTaskReturnAddress = ( size_t ) portTASK_RETURN_ADDRESS;
@ -205,3 +211,9 @@ void vPortEndScheduler( void )
}
}
/*-----------------------------------------------------------*/
BaseType_t xPortIsInsideInterrupt( void )
{
return ( xInterruptNesting == 0 ) ? pdFALSE : pdTRUE;
}
/*-----------------------------------------------------------*/

View file

@ -162,6 +162,7 @@ definitions. */
* where the global and thread pointers are currently assumed to be constant so
* are not saved:
*
* xInterruptNesting
* xCriticalNesting
* x31
* x30
@ -198,6 +199,8 @@ definitions. */
* pxCode
*/
pxPortInitialiseStack:
addi a0, a0, -portWORD_SIZE /* Space for interrupt nesting count. */
addi a0, a0, -portWORD_SIZE /* Space for critical nesting count. */
store_x x0, 0(a0) /* Critical nesting count starts at 0 for every task. */

View file

@ -57,11 +57,13 @@
* specific version of freertos_risc_v_chip_specific_extensions.h. See the
* notes at the top of portASM.S file. */
#ifdef __riscv_32e
#define portCONTEXT_SIZE ( 15 * portWORD_SIZE )
#define portCONTEXT_SIZE ( 16 * portWORD_SIZE )
#define portCRITICAL_NESTING_OFFSET 14
#define portINTERRUPT_NESTING_OFFSET 15
#else
#define portCONTEXT_SIZE ( 31 * portWORD_SIZE )
#define portCONTEXT_SIZE ( 32 * portWORD_SIZE )
#define portCRITICAL_NESTING_OFFSET 30
#define portINTERRUPT_NESTING_OFFSET 31
#endif
#if ( configENABLE_FPU == 1 )
@ -122,6 +124,8 @@
.extern xISRStackTop
.extern xCriticalNesting
.extern pxCriticalNesting
.extern xInterruptNesting
.extern pxInterruptNesting
/*-----------------------------------------------------------*/
.macro portcontexSAVE_FPU_CONTEXT
@ -306,6 +310,12 @@ store_x x15, 13 * portWORD_SIZE( sp )
load_x t0, xCriticalNesting /* Load the value of xCriticalNesting into t0. */
store_x t0, portCRITICAL_NESTING_OFFSET * portWORD_SIZE( sp ) /* Store the critical nesting value to the stack. */
load_x t0, xInterruptNesting /* Load the value of xInterruptNesting into t0. */
store_x t0, portINTERRUPT_NESTING_OFFSET * portWORD_SIZE( sp ) /* Store the interrupt nesting value to the stack. */
addi t0, t0, 1
load_x t1, pxInterruptNesting /* Load the address of xInterruptNesting into t1. */
store_x t0, 0( t1 ) /* Increment xInterruptNesting by 1 */
#if( configENABLE_FPU == 1 )
csrr t0, mstatus
srl t1, t0, MSTATUS_FS_OFFSET
@ -425,6 +435,10 @@ csrw mstatus, t3
6:
#endif /* ifdef portasmSTORE_FPU_CONTEXT */
load_x t0, portINTERRUPT_NESTING_OFFSET * portWORD_SIZE( sp ) /* Obtain saved xInterruptNesting value from task's stack. */
load_x t1, pxInterruptNesting /* Load the address of xInterruptNesting into t1. */
store_x t0, 0 ( t1 ) /* Restore the interrupt nesting value. */
load_x t0, portCRITICAL_NESTING_OFFSET * portWORD_SIZE( sp ) /* Obtain xCriticalNesting value for this task from task's stack. */
load_x t1, pxCriticalNesting /* Load the address of xCriticalNesting into t1. */
store_x t0, 0 ( t1 ) /* Restore the critical nesting value for this task. */

View file

@ -106,6 +106,8 @@ extern void vTaskSwitchContext( void );
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
BaseType_t xPortIsInsideInterrupt( void );
/*-----------------------------------------------------------*/
/* Critical section management. */