Skip to content

Commit

Permalink
rework OSEK interrupt nesting handling
Browse files Browse the repository at this point in the history
  • Loading branch information
Chalandi committed Oct 4, 2024
1 parent 171688b commit 3372f51
Show file tree
Hide file tree
Showing 11 changed files with 154 additions and 40 deletions.
4 changes: 2 additions & 2 deletions Code/Appli/OsGenCfg.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ OS_CONFIG_BEGIN
OS_INTERRUPT_CAT2_DEF(Undefined, 0, NOT_NESTED) /* Reserved */
OS_INTERRUPT_CAT2_DEF(Undefined, 0, NOT_NESTED) /* Reserved */
OS_INTERRUPT_CAT1_DEF(OsDispatchHandler, 4, NESTED) /* OsDispatchHandler */
OS_INTERRUPT_CAT2_DEF(SysTickTimer, 4, NESTED) /* OsCat2IsrWrapper */
OS_INTERRUPT_CAT2_DEF(SysTickTimer, 4, NOT_NESTED) /* OsCat2IsrWrapper */
OS_INTERRUPT_CAT2_DEF(Undefined, 0, NOT_NESTED) /* TIMER0_IRQ_0_IRQn */
OS_INTERRUPT_CAT2_DEF(Undefined, 0, NOT_NESTED) /* TIMER0_IRQ_1_IRQn */
OS_INTERRUPT_CAT2_DEF(Undefined, 0, NOT_NESTED) /* TIMER0_IRQ_2_IRQn */
Expand Down Expand Up @@ -139,7 +139,7 @@ OS_CONFIG_BEGIN
//=============================================================================
// Interrupt Mask Configuration
//=============================================================================
#define OS_INT_CAT1_LOWEST_PRIO_LEVEL 8UL
#define OS_INT_CAT1_LOWEST_PRIO_LEVEL 7UL


OS_CONFIG_END
4 changes: 4 additions & 0 deletions Code/OSEK/HwPlatform/ARM/OsAsm.s
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ OsDispatchHandler:
.extern OsRunCat2Isr
.extern OsGetSavedStackPointer
.extern OsIntCallDispatch
.extern OsIncNestingDepthLevel
.extern OsDecNestingDepthLevel

OsCat2IsrWrapper:

Expand All @@ -76,12 +78,14 @@ OsCat2IsrWrapper:
tst lr, #0x10
it eq
vpusheq {S16-S31}
bl.w OsIncNestingDepthLevel
mov r0,r13
bl.w OsStoreStackPointer
bl.w OsRunCat2Isr
bl.w OsGetSavedStackPointer
bl.w OsIntCallDispatch
mov r13,r0
bl.w OsDecNestingDepthLevel
pop {r4 - r11, lr}
tst lr, #0x10
it eq
Expand Down
49 changes: 41 additions & 8 deletions Code/OSEK/HwPlatform/ARM/OsHwPltfm.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
#include"OsInternal.h"
#include"OsTcb.h"

#define USE_OS_PRIO
uint32 osRemapOsPriorityValue(uint32 level, uint32 IntPrioBit);

//------------------------------------------------------------------------------------------------------------------
/// \brief OsIsInterruptContext
///
Expand Down Expand Up @@ -96,12 +99,12 @@ void osInitInterrupts(void)
if((InterruptIndex == 4U) || (InterruptIndex == 5U) || (InterruptIndex == 6U) || (InterruptIndex == 11U) || (InterruptIndex == 14U) || (InterruptIndex == 15U))
{
/* set the system handler priority level */
SCB_SHPRx[InterruptIndex - 4U] = ((uint8)IsrLookupTable[InterruptIndex].Prio << (8U - IntPrioBit));
SCB_SHPRx[InterruptIndex - 4U] = ((uint8)osRemapOsPriorityValue(IsrLookupTable[InterruptIndex].Prio, IntPrioBit) << (8U - IntPrioBit));
}
else if(InterruptIndex > 15U)
{
/* set the NVIC interrupt priority level */
NVIC_IPRx[InterruptIndex - 16U] = ((uint8)IsrLookupTable[InterruptIndex].Prio << (8U - IntPrioBit));
NVIC_IPRx[InterruptIndex - 16U] = ((uint8)osRemapOsPriorityValue(IsrLookupTable[InterruptIndex].Prio, IntPrioBit) << (8U - IntPrioBit));

/* enable the NVIC interrupt */
NVIC_ISERx[(InterruptIndex - 16U) / 32U] = (1UL << ((InterruptIndex - 16U) % 32U));
Expand All @@ -126,6 +129,9 @@ void osInitInterrupts(void)
void osSetInterruptPriorityMask(uint32 level)
{
uint32 IntPrioBit = OsHwGetInterruptPrioBits();

level = osRemapOsPriorityValue(level, IntPrioBit);

OsSetSysBasepriReg((level << (8U - IntPrioBit)));
}

Expand All @@ -142,19 +148,46 @@ uint32 osGetInterruptPriorityMask(void)
{
uint32 level = 0;
uint32 IntPrioBit = OsHwGetInterruptPrioBits();

OsGetSysBasepriReg((uint32*)&level);
return((level >> (8U - IntPrioBit)));
}
level >>= (8U - IntPrioBit);

uint32 osGetHwIntNestingLevel(void)
{
return 1;
return(osRemapOsPriorityValue(level, IntPrioBit));
}

void osDisableHwIntNesting(void)
//------------------------------------------------------------------------------------------------------------------
/// \brief
///
/// \descr
///
/// \param void
///
/// \return void
//------------------------------------------------------------------------------------------------------------------
uint32 osRemapOsPriorityValue(uint32 level, uint32 IntPrioBit)
{
#ifdef USE_OS_PRIO
/* note: remap the level prio: ARM is using lower value for highest prio
contrary to the OS which uses lower value for lower prio */
if(level > ((1ul << IntPrioBit) -1))
{
level = (1ul << IntPrioBit) - 1;
}

level = ((1ul << IntPrioBit) - 1) - level;
#endif
return(level);
}

//------------------------------------------------------------------------------------------------------------------
/// \brief
///
/// \descr
///
/// \param void
///
/// \return void
//------------------------------------------------------------------------------------------------------------------
void osSaveAndDisableIntState(void)
{
}
Expand Down
15 changes: 8 additions & 7 deletions Code/OSEK/HwPlatform/ARM/OsHwPltfm.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,21 @@
#define SCB_ICSR 0xE000ED04UL
#define SET_PENDSV() (*(volatile uint32*)(SCB_ICSR)) |= 1UL<<28
#define CLEAR_PENDSV() (*(volatile uint32*)(SCB_ICSR)) &= ~(1UL<<28)
#define osDispatch() SET_PENDSV(); __asm("DSB"); __asm("NOP")

#define ENABLE_INTERRUPTS() __asm("CPSIE I")
#define DISABLE_INTERRUPTS() __asm("CPSID I")

#define GET_ICSR_VECTACTIVE() ((*(volatile uint32*)(SCB_ICSR)) & (uint32)0x1FUL)

#define NVIC_ISERx ((volatile uint32 *)(0xE000E100UL))
#define NVIC_IPRx ((volatile uint8 *) (0xE000E400UL))
#define SCB_SHPRx ((volatile uint8 *) (0xE000ED18UL))
#define NVIC_ISPRx ((volatile uint8 *) (0xE000E200UL))


#define osDispatch() SET_PENDSV(); __asm("DSB"); __asm("NOP")

#define ENABLE_INTERRUPTS() __asm("CPSIE I")
#define DISABLE_INTERRUPTS() __asm("CPSID I")

#define OS_INTERRUPT_NESTING_DEPTH_LEVEL 8

//=========================================================================================
// SYSTICK
//=========================================================================================
Expand All @@ -50,8 +53,6 @@ void osRestoreSavedIntState(void);
void osSaveAndDisableIntState(void);
void OsCatchAllCpuExceptions(void);
void OsIsr_SysTickTimerFunc(void);
uint32 osGetHwIntNestingLevel(void);
void osDisableHwIntNesting(void);
boolean OsIsInterruptContext(void);
void osInitInterrupts(void);
//void osMaskNestedIntPrio(void);
Expand Down
2 changes: 1 addition & 1 deletion Code/OSEK/HwPlatform/RISC-V/OsHwPltfm.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ boolean OsIsInterruptContext(void)
///
/// \return uint32 current nesting level
//------------------------------------------------------------------------------------------------------------------
uint32 osGetHwIntNestingLevel(void)
uint32 osGetIntNestingLevel(void)
{
return 1;
}
Expand Down
13 changes: 2 additions & 11 deletions Code/OSEK/HwPlatform/RISC-V/OsHwPltfm.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,7 @@
#define ENABLE_INTERRUPTS() riscv_set_csr(RVCSR_MSTATUS_OFFSET, RVCSR_MSTATUS_MIE_BITS)
#define DISABLE_INTERRUPTS() riscv_clear_csr(RVCSR_MSTATUS_OFFSET, RVCSR_MSTATUS_MIE_BITS)

#define osSetINTSYSCR(value) //__asm volatile ("csrw 0x804, %0" : : "r" (value) :)
#define osMaskClearINTSYSCR(value) //__asm volatile ("csrrc zero, 0x804, %0" : : "r" (value) :)
#define osMaskSetINTSYSCR(value) //__asm volatile ("csrrs zero, 0x804, %0" : : "r" (value) :)

#define osDisableHwIntNesting() //osMaskSetINTSYSCR(0x20)

//=========================================================================================
// SYSTICK
//=========================================================================================

#define OS_INTERRUPT_NESTING_DEPTH_LEVEL 8

//=========================================================================================
// Externs
Expand All @@ -63,6 +54,6 @@ void osRestoreSavedIntState(void);
void osSaveAndDisableIntState(void);
void OsCatchAllCpuExceptions(void);
void OsIsr_SysTickTimerFunc(void);
uint32 osGetHwIntNestingLevel(void);
uint32 osGetIntNestingLevel(void);

#endif
83 changes: 78 additions & 5 deletions Code/OSEK/OsCat2Int.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
//------------------------------------------------------------------------------------------------------------------
/// \brief OsRunCat2Isr
///
/// \descr This function is the entry point of all category 2 interrupts (PLIC).
/// \descr This function is the entry point of all category 2 interrupts
///
/// \param void
///
Expand All @@ -40,13 +40,86 @@

if(IsrLookupTable[IntId].type == NOT_NESTED)
{
/* disable the nesting of the current interrupt priority level (Cat1 interrupts will kept unmasked) */
/* disable the nesting of the current interrupt priority level but keep it enabled for category 1 interrupts */
osSetInterruptPriorityMask(OS_INT_CAT1_LOWEST_PRIO_LEVEL);
}

/* enable global interrupt flag */
ENABLE_INTERRUPTS();
/* enable interrupt nesting before calling the ISR */
osEnableIntNesting();

/* call the interrupt service routine */
/* call the appropriate interrupt service routine */
IsrLookupTable[IntId].IsrFunc();
}

//------------------------------------------------------------------------------------------------------------------
/// \brief
///
/// \descr
///
/// \param void
///
/// \return void
//------------------------------------------------------------------------------------------------------------------
void OsIncNestingDepthLevel(void)
{
OCB_Cfg.OsInterruptNestingDepth++;

if(OCB_Cfg.OsInterruptNestingDepth >= OS_INTERRUPT_NESTING_DEPTH_LEVEL)
OsKernelError(E_OS_KERNEL_PANIC);
}

//------------------------------------------------------------------------------------------------------------------
/// \brief
///
/// \descr
///
/// \param void
///
/// \return void
//------------------------------------------------------------------------------------------------------------------
void OsDecNestingDepthLevel(void)
{
OCB_Cfg.OsInterruptNestingDepth--;
}

//------------------------------------------------------------------------------------------------------------------
/// \brief
///
/// \descr
///
/// \param void
///
/// \return void
//------------------------------------------------------------------------------------------------------------------
__attribute__((weak)) uint32 osGetIntNestingLevel(void)
{
return OCB_Cfg.OsInterruptNestingDepth;
}

//------------------------------------------------------------------------------------------------------------------
/// \brief
///
/// \descr
///
/// \param void
///
/// \return void
//------------------------------------------------------------------------------------------------------------------
void osDisableIntNesting(void)
{
DISABLE_INTERRUPTS();
}

//------------------------------------------------------------------------------------------------------------------
/// \brief
///
/// \descr
///
/// \param void
///
/// \return void
//------------------------------------------------------------------------------------------------------------------
void osEnableIntNesting(void)
{
ENABLE_INTERRUPTS();
}
14 changes: 10 additions & 4 deletions Code/OSEK/OsCore.c
Original file line number Diff line number Diff line change
Expand Up @@ -282,11 +282,14 @@ ISR(SysTickTimer)
void OsStoreStackPointer(uint32 StackPtrValue)
{
/* get the interrupt nesting level */
const uint32 OsInterruptNestingDepth = osGetHwIntNestingLevel();
const uint32 OsInterruptNestingDepth = osGetIntNestingLevel();

/* save the interrupt nesting level stack pointer */
OCB_Cfg.OsIntNestSavedStackPointer[OsInterruptNestingDepth - 1u] = StackPtrValue;

/* save the interrupt nesting level priority */
OCB_Cfg.OsIntNestSavedPrioLevel[OsInterruptNestingDepth - 1u] = osGetInterruptPriorityMask();

/* store the preempted task context only in nested level 1,
the other nesting interrupts will use the current stack */
if(OsInterruptNestingDepth == 1u)
Expand Down Expand Up @@ -319,7 +322,7 @@ void OsStoreStackPointer(uint32 StackPtrValue)
uint32 OsGetSavedStackPointer(void)
{
/* get the interrupt nesting level */
const uint32 OsInterruptNestingDepth = osGetHwIntNestingLevel();
const uint32 OsInterruptNestingDepth = osGetIntNestingLevel();

if(OsInterruptNestingDepth == 1u)
{
Expand Down Expand Up @@ -350,12 +353,15 @@ uint32 OsGetSavedStackPointer(void)
uint32 OsIntCallDispatch(uint32 StackPtr)
{
/* get the interrupt nesting level */
const uint32 OsInterruptNestingDepth = osGetHwIntNestingLevel();
const uint32 OsInterruptNestingDepth = osGetIntNestingLevel();

/* restore the interrupt nesting priority level */
osSetInterruptPriorityMask(OCB_Cfg.OsIntNestSavedPrioLevel[OsInterruptNestingDepth - 1u]);

if(OsInterruptNestingDepth == 1u)
{
/* Disable the Hw nesting */
osDisableHwIntNesting();
osDisableIntNesting();

/* Reset the flag */
OCB_Cfg.OsCat2InterruptLevel = 0;
Expand Down
2 changes: 1 addition & 1 deletion Code/OSEK/OsGenMac.h
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@
#define OS_FE_INTERRUPT_END

#define OS_MULTICORE_END
#define OS_CONFIG_END 0,0,OS_INVALID_TASK,0,0,0,0,0,0,0,0,{0}};
#define OS_CONFIG_END 0,0,OS_INVALID_TASK,0,0,0,0,0,0,0,0,{0},{0}};

#elif defined(OS_GEN_LINKER_SCRIPT)

Expand Down
5 changes: 5 additions & 0 deletions Code/OSEK/OsInternal.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,10 @@ void OsSetIntVectTableAddress(uint32* address);

OsStatusType osSchedule(void);
uint32 osGetActiveInterruptVectorId(void);
void OsIncNestingDepthLevel(void);
void OsDecNestingDepthLevel(void);
uint32 osGetIntNestingLevel(void);
void osDisableIntNesting(void);
void osEnableIntNesting(void);

#endif
3 changes: 2 additions & 1 deletion Code/OSEK/OsTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,8 @@ typedef struct
uint32 OsInterruptNestingDepth;
uint32 OsInterruptNestingSavedLevel;
uint32 OsInterruptSavedLevel;
uint32 OsIntNestSavedStackPointer[8];
uint32 OsIntNestSavedStackPointer[OS_INTERRUPT_NESTING_DEPTH_LEVEL];
uint32 OsIntNestSavedPrioLevel[OS_INTERRUPT_NESTING_DEPTH_LEVEL];
}Ocb_t;

typedef struct
Expand Down

0 comments on commit 3372f51

Please sign in to comment.