/* BEGIN_FILE_HDR ******************************************************************************** * NOTICE * This software is the property of HiRain Technologies. Any information * contained in this doc should not be reproduced, or used, or disclosed * without the written authorization from HiRain Technologies. ******************************************************************************** * File Name: Os_Intc.c ******************************************************************************** * Project/Product: AUTOSAR OS PROJECT * Title: Os_Intc.c * Author: Hirain ******************************************************************************** * Description: Intc Module of OS * ******************************************************************************** * Limitations : None * ******************************************************************************** * ******************************************************************************** * Revision History: * Reference to Core C File ******************************************************************************** * END_FILE_HDR*/ #include "Os_Internal.h" /*PRQA S 303,305,306 EOF*/ /* * MISRA-C:2004 11.3(303):Cast between a pointer to volatile object and an integral type. * MISRA-C:2004 11.3(305):Cast a pointer to an integral type. * MISRA-C:2004 11.3(306):Cast between a pointer to function and an integral type. * To address a flash must cast an integral type to a pointer. * To address a System Register must cast an integral type to a pointer and volatile is a type specifier to make sure the instruction can not be omitted due to compiler optimizations. */ /*PRQA S 0604 EOF*/ /* This operation is allowed in C99,The declaration of the variable can be placed in executable statements. */ /*PRQA S 0776 EOF*/ /* name definition has no effect. */ /*PRQA S 3442 EOF*/ /* They are essential operators to access registers. */ /*PRQA S 3383 EOF*/ /* The comparative operation or arithmetic expression of non-negative variables does not cause overflow. */ /*PRQA S 3430 EOF*/ /* The value passed is a single value, which also allows the parentheses to be defined in the macro definition, which does not cause the error of the operation. */ /*PRQA S 4603 EOF*/ /* not include . */ /*PRQA S 4544 EOF*/ /* The comparative operation or arithmetic expression of non-negative variables does not cause overflow. */ /*PRQA S 0488,3004 EOF*/ /* This address parameter can be done in this way . */ /*PRQA S 1338 EOF*/ /* The return value of the function and the definition of CoreID are CoreIdType. */ /*PRQA S 1840 EOF*/ /* This approach can be assigned to convert. */ /*PRQA S 4131,4543,4571 EOF*/ /* This left shift directive is executable. */ /*PRQA S 3218 EOF*/ /* Defines global variables to prevent data from being tampered. */ /*PRQA S 3229 EOF*/ /* Under the definition of macros. */ /*PRQA S 3203 EOF*/ /* Pcx is used to get MSP value. */ /*PRQA S 4643 EOF*/ /* not include . */ /*PRQA S 2016 EOF*/ /* The 'default' clause in this 'switch' statement contains no executable code can not make mistakes. */ /*PRQA S 3384 EOF*/ /* Unsigned integer arithmetic in C can never overflow, because the standard defines safe wraparound behaviour . */ /*PRQA S 0673 EOF*/ /* A pointer has been initialized with an expression which can points to a more heavily qualified type. */ /*PRQA S 0428,3200,3209 EOF*/ /* This function has been declared with a "non-void" return type and the value returned from this function call can be nonexistent . */ #define OS_START_SEC_VAR_NOINIT_UNSPECIFIED #include "Os_MemMap.h" /***************************************************************************** * variables define ******************************************************************************/ VAR(Os_AddrType, OS_VAR) OsIntc_FirstISRCSA[OS_ISR_NUMBER]; #if((OS_TIMING_PROTECTION_SUPPORT == OS_ON)||(OS_MEM_PROTECTION_SUPPORT == OS_ON)||(OS_APPLICATION_NUMBER > 0)) #define OS_ISR_RETURN_ISR (0xfffffff1) #define OS_ISR_RETURN_TASK (0xfffffffd) #define OS_SHIFT_ONE_BYTE ((Os_uint32)1) #define OS_SHIFT_ONE_WORD ((Os_uint32)4) #define OS_SHIFT_THREE_WORD ((Os_uint32)12) #define OS_SHIFT_SIX_WORD ((Os_uint32)24) #define OS_SHIFT_SEVEN_WORD ((Os_uint32)28) #define OS_SHIFT_EIGHT_WORD ((Os_uint32)32) #define OS_SHIFT_TEN_WORD ((Os_uint32)40) #define OS_SHIFT_TWELVE_WORD ((Os_uint32)48) #define OS_SHIFT_TWENTYTWO_WORD ((Os_uint32)88) VAR(Os_JmpBuf, OS_VAR) OsIntc_Envbuf[OS_PL_LOWEST_INT_PRIO + (Os_uint32)1]; #if(OS_ON == OS_ISR_NEST_SUPPORT) #define OS_ISR_NEST_OPTIMIZATION_JUDGE (0xfffffff1) STATIC VAR(Os_App_KillIsr, OS_VAR) OsIntc_KilldISRId[OS_ISR_NUMBER]; STATIC VAR(Os_AddrType, OS_VAR) OsIntc_KilldISRIdPtr[OS_USED_CORE_NUMBER]; #endif/*(OS_ON == OS_ISR_NEST_SUPPORT)*/ #endif/*#if((OS_TIMING_PROTECTION_SUPPORT == OS_ON)||(OS_MEM_PROTECTION_SUPPORT == OS_ON)||(OS_APPLICATION_NUMBER > 0))*/ #if(OS_ON == OS_ISR_NEST_SUPPORT) STATIC VAR(Os_AddrType, OS_VAR) OsIntc_KilldISRIdPtrCal[OS_USED_CORE_NUMBER]; #endif/*#if(OS_ON == OS_ISR_NEST_SUPPORT)*/ #if(OS_TIMING_PROTECTION_SUPPORT == OS_OFF) STATIC VAR(Os_boolean, OS_VAR) OsIntc_GlobalIntState_Backup[OS_USED_CORE_NUMBER];/* global interrupt state */ #endif STATIC VAR(Os_PrioType, OS_VAR) OsIntc_IntPri_Backup[OS_USED_CORE_NUMBER];/* interrupt priority state */ #define OS_STOP_SEC_VAR_NOINIT_UNSPECIFIED #include "Os_MemMap.h" /***************************************************************************** * MACRO ******************************************************************************/ #define OS_START_SEC_CODE #include "Os_MemMap.h" /***************************************************************************** * OS internal code ******************************************************************************/ #if((OS_TIMING_PROTECTION_SUPPORT == OS_ON)||(OS_MEM_PROTECTION_SUPPORT == OS_ON)||(OS_APPLICATION_NUMBER > 0)) STATIC FUNC(void, OS_CODE) OsIntc_SVC_Schedule(void); #endif/*#if((OS_TIMING_PROTECTION_SUPPORT == OS_ON)||(OS_MEM_PROTECTION_SUPPORT == OS_ON)||(OS_APPLICATION_NUMBER > 0))*/ #if(OS_ON == OS_ISR_NEST_SUPPORT) STATIC FUNC(void, OS_CODE) OsIntc_BubbleSort ( Os_App_KillIsr *arr, Os_uint32 size ); STATIC FUNC(void, OS_CODE) OsIntc_ExitISRCSA(void); #endif/*#if(OS_ON == OS_ISR_NEST_SUPPORT)*/ /* BEGIN_FUNCTION_HDR *********************************************************************************************** * Function Name: OsIntc_BubbleSort * * Description: None * * Inputs: arr, size * * Outputs: None * * Limitations: None *********************************************************************************************** END_FUNCTION_HDR*/ #if(OS_ON == OS_ISR_NEST_SUPPORT) STATIC FUNC(void, OS_CODE) OsIntc_BubbleSort ( Os_App_KillIsr *arr, Os_uint32 size ) { Os_uint32 i,j; Os_App_KillIsr tmp; for(i = (Os_uint32)0; i < (size - (Os_uint32)1); i++) { for(j = (Os_uint32)0; j < (size - i - (Os_uint32)1); j++) { if(arr[j].NestLayer > arr[j+(Os_uint32)1].NestLayer) { tmp = arr[j]; arr[j] = arr[j+(Os_uint32)1]; arr[j+(Os_uint32)1] = tmp; } } } } #endif /* BEGIN_FUNCTION_HDR *********************************************************************************************** * Function Name: OsIntc_Init * * Description: Do necessary init for intc * * Inputs: CoreID * * Outputs: None * * Limitations: input CoreID is logical id, If needed , CoreID need to change to phy core id *********************************************************************************************** END_FUNCTION_HDR*/ FUNC(void, OS_CODE) OsIntc_Init ( CoreIdType CoreID ) { (void)CoreID; ISRType isrIdx; Os_uint16 VectorNumber; Os_uint8 PriNumber; OS_SCB->SHCSR |= ((Os_uint32)OS_SCB_SHCSR_USGFAULTENA_MSK | (Os_uint32)OS_SCB_SHCSR_BUSFAULTENA_MSK | (Os_uint32)OS_SCB_SHCSR_MEMFAULTENA_MSK); OsCpu_SetBASEPRI((Os_uint32)0); OS_PL_NVIC_SHPR3_REG |= ((Os_uint32)OS_PL_LOWEST_INT_PRIO << ((Os_uint32)OS_PL_PRIO_REG_BITS - (Os_uint32)OS_PL_PRIO_BITS)) << (Os_uint32)OS_PL_PENDSV_PRIO_SHIFT; /*Set ISR Priority*/ for(isrIdx = (ISRType)0; isrIdx < OS_ISR_NUMBER; isrIdx++) { OS_PL_DSYNC(); OS_PL_ISYNC(); if(Os_ISRCfg[isrIdx].vectorIndex > 15) { VectorNumber = Os_ISRCfg[isrIdx].vectorIndex - (Os_uint16)16; PriNumber = (Os_uint8)((OS_PL_LOWEST_INT_PRIO - Os_ISRCfg[isrIdx].Prio) << (OS_PL_PRIO_REG_BITS - OS_PL_PRIO_BITS)); OS_WRITE_ISR_PRI(VectorNumber,PriNumber); } OS_PL_DSYNC(); OS_PL_ISYNC(); } } /* BEGIN_FUNCTION_HDR *********************************************************************************************** * Function Name: OsIntc_GetIntPriority * * Description: Get interrupt priority of current core * * Inputs: CoreID * * Outputs: OS_INLINE_FUNC(Os_PrioType) OsIntc_GetIntPriority * * Limitations: input CoreID is logical id, If needed , CoreID need to change to phy core id *********************************************************************************************** END_FUNCTION_HDR*/ FUNC(Os_PrioType, OS_CODE) OsIntc_GetIntPriority ( CoreIdType CoreID ) { (void)CoreID; Os_PrioType readbackPri; readbackPri = (Os_PrioType)OsCpu_GetBASEPRI(); if(readbackPri != (Os_PrioType)0) { readbackPri = (Os_PrioType)OS_PL_LOWEST_INT_PRIO - (Os_PrioType)(readbackPri >> (Os_PrioType)(OS_PL_PRIO_REG_BITS - OS_PL_PRIO_BITS)); } return readbackPri; } /* BEGIN_FUNCTION_HDR *********************************************************************************************** * Function Name: OsIntc_ReplaceIntPriority * * Description: Set interrupt priority of current core * * Inputs: CoreID, priority * * Outputs: * * Limitations: 1.input CoreID is logical id, If needed , CoreID need to change to phy core id *********************************************************************************************** END_FUNCTION_HDR*/ FUNC(void, OS_CODE) OsIntc_ReplaceIntPriority ( CoreIdType CoreID, Os_PrioType priority ) { Os_uint32 val; Os_PrioType readbackPri; Os_uint8 cnt = (Os_uint8)0; if(priority != (Os_uint16)0) { val = OS_PL_LOWEST_INT_PRIO - priority; } else { val = (Os_uint32)0; } val = val << (OS_PL_PRIO_REG_BITS - OS_PL_PRIO_BITS); do { OsCpu_SetBASEPRI(val); readbackPri = (Os_PrioType)OsCpu_GetBASEPRI(); cnt++; }while((readbackPri != val) && (cnt < OS_PL_REG_RETRY_TIMES)); if(cnt >= OS_PL_REG_RETRY_TIMES) { OsHook_FataErrReport(CoreID, E_OS_PL_SYSFATA_ACCESS_REG_ERR, OSServiceId_OsIntc_ReplaceIntPriority, OS_IE_NOMORE_INFO, OS_IE_NO_ERRPAR, OS_IE_NO_ERRPAR, OS_IE_NO_ERRPAR); } if(Os_CurrentContext[CoreID] != OS_CONTEXT_C2ISR) { if(val != (Os_uint32)0) { OS_PL_NVIC_SHPR3_REG &= (~OS_NVIC_PENDSV_PRI); OS_PL_NVIC_SHPR3_REG |= (val-1) << OS_PL_PENDSV_PRIO_SHIFT; } else { OS_PL_NVIC_SHPR3_REG |= (OS_PL_LOWEST_INT_PRIO << (OS_PL_PRIO_REG_BITS - OS_PL_PRIO_BITS)) << OS_PL_PENDSV_PRIO_SHIFT; } } } /* BEGIN_FUNCTION_HDR *********************************************************************************************** * Function Name: OsIntc_GetGlobalIntState * * Description: Get global interrupt state * * Inputs: CoreID * * Outputs: Os_boolean * * Limitations: input CoreID is logical id, If needed , CoreID need to change to phy core id *********************************************************************************************** END_FUNCTION_HDR*/ FUNC(Os_boolean, OS_CODE) OsIntc_GetGlobalIntState ( CoreIdType CoreID ) { Os_uint32 val; Os_boolean state = OS_FALSE; (void)CoreID; val = (Os_uint32)OsCpu_GetPRIMASK(); if((Os_uint32)0 == (Os_uint32)(val & OS_PL_ICR_IE_MASK)) { state = OS_TRUE; } return state; } /* BEGIN_FUNCTION_HDR *********************************************************************************************** * Function Name: OsIntc_SetGlobalIntState * * Description: Set global interrupt state * * Inputs: CoreID, gIntState * * Outputs: None * * Limitations: input CoreID is logical id, If needed , CoreID need to change to phy core id *********************************************************************************************** END_FUNCTION_HDR*/ FUNC(void, OS_CODE) OsIntc_SetGlobalIntState ( CoreIdType CoreID, Os_boolean gIntState ) { (void)CoreID; if(gIntState == OS_TRUE) { OS_PL_EnableInterrupts(); } else { /* code */ OS_PL_DisableInterrupts(); } } /* BEGIN_FUNCTION_HDR *********************************************************************************************** * Function Name: OsIntc_DisableAllInterrupts * * Description: save current state and disable all interrupts * * Inputs: CoreID * * Outputs: None * * Limitations: input CoreID is logical id, If needed , CoreID need to change to phy core id *********************************************************************************************** END_FUNCTION_HDR*/ FUNC(void, OS_CODE) OsIntc_DisableAllInterrupts ( CoreIdType CoreID ) { #if((OS_TIMING_PROTECTION_SUPPORT == OS_ON) || (OS_MEM_PROTECTION_SUPPORT == OS_ON)) VAR(Os_PrioType, OS_VAR) IntPri_Backup; IntPri_Backup = OsIntc_GetIntPriority(CoreID); OsIntc_ReplaceIntPriority(CoreID, OS_PL_LOWEST_INT_PRIO - (Os_uint32)1); OsIntc_IntPri_Backup[CoreID] = IntPri_Backup; #else VAR(Os_boolean, OS_VAR) IntState_Backup; /*when use intc for time protection so need to consider tp here*/ IntState_Backup = OsIntc_GetGlobalIntState(CoreID); OS_PL_DisableInterrupts(); OsIntc_GlobalIntState_Backup[CoreID] = IntState_Backup; #endif } /* BEGIN_FUNCTION_HDR *********************************************************************************************** * Function Name: OsIntc_ResumeAllInterrupts * * Description: resume saved global int state * * Inputs: CoreID * * Outputs: None * * Limitations: input CoreID is logical id, If needed , CoreID need to change to phy core id *********************************************************************************************** END_FUNCTION_HDR*/ FUNC(void, OS_CODE) OsIntc_ResumeAllInterrupts ( CoreIdType CoreID ) { #if((OS_TIMING_PROTECTION_SUPPORT == OS_ON) || (OS_MEM_PROTECTION_SUPPORT == OS_ON)) OsIntc_ReplaceIntPriority(CoreID, OsIntc_IntPri_Backup[CoreID]); #else OsIntc_SetGlobalIntState(CoreID, OsIntc_GlobalIntState_Backup[CoreID]); #endif } /* BEGIN_FUNCTION_HDR *********************************************************************************************** * Function Name: OsIntc_SuspendOsInterrupts * * Description: save current C2 state and disable C2 interrupts * * Inputs: CoreID * * Outputs: None * * Limitations: input CoreID is logical id, If needed , CoreID need to change to phy core id *********************************************************************************************** END_FUNCTION_HDR*/ FUNC(void, OS_CODE) OsIntc_SuspendOsInterrupts ( CoreIdType CoreID ) { OsIntc_IntPri_Backup[CoreID] = OsIntc_GetIntPriority(CoreID); OsIntc_ReplaceIntPriority(CoreID, Os_CoreCfg[CoreID].topC2IsrPri); } /* BEGIN_FUNCTION_HDR *********************************************************************************************** * Function Name: OsIntc_ResumeOsInterrupts * * Description: resume saved C2 state * * Inputs: CoreID * * Outputs: None * * Limitations: input CoreID is logical id, If needed , CoreID need to change to phy core id *********************************************************************************************** END_FUNCTION_HDR*/ FUNC(void, OS_CODE) OsIntc_ResumeOsInterrupts ( CoreIdType CoreID ) { OsIntc_ReplaceIntPriority(CoreID, OsIntc_IntPri_Backup[CoreID]); } /***************************************************************************** * OS ISR in out process function ******************************************************************************/ /* BEGIN_FUNCTION_HDR *********************************************************************************************** * Function Name: OsIntc_OutISR2 * * Description: Leaving a Category 2 interrupt * * Inputs: None * * Outputs: None * * Limitations: Called in generated ISR, after user isr hook *********************************************************************************************** END_FUNCTION_HDR*/ FUNC(void, OS_CODE) OsIntc_OutISR2 ( void ) { Os_boolean tempReSchFlag = OS_FALSE; Os_AddrType tempRetAddr = (Os_AddrType)0; CoreIdType CoreID; Os_uint32 val = (Os_uint32)0; CoreID = OsCpu_GetCoreID(); OsIntc_DisableGlobalInterrupt(CoreID);/* User ISR may enable interrupt nest, so we must disable it here*/ OsMpu_SetKernel(CoreID);/* switch mpu from user isr to kernel*/ tempReSchFlag = OsIsr_OutISR2(CoreID); /* outIsr2 is jump from the end of ISR, so no need to consider CDC and release CSA*/ if((tempReSchFlag == OS_TRUE)) { if(((OS_SCB->SHCSR)&OS_SCB_SHCSR_PENDSVACT_MSK) != (Os_uint32)0) { Os_CurrentContext[CoreID] = OS_CONTEXT_TASK; return; } OS_SCB->ICSR |= OS_SCB_ICSR_PENDSVSET_MSK; } else/*return to saved context*/ { if(Os_IntNestDepth[CoreID] != OS_INVALID_ISR) { #if(OS_ON == OS_ISR_NEST_SUPPORT) tempRetAddr = Os_ISRCBTable[Os_CoreCfg[CoreID].nestIsrIdPtr[Os_IntNestDepth[CoreID]]].OsIsrCtxPtr; OsMpu_ClearRegion(); OsMpu_SetISR(CoreID, Os_CoreCfg[CoreID].nestIsrIdPtr[Os_IntNestDepth[CoreID]]); #else /*fata err*/ #endif } else { tempRetAddr = Os_TaskCBTable[Os_CurrentTaskId[CoreID]].OsTaskCtxPtr; /*switch to task mpu set as mpu not saved in CSA*/ OsMpu_ClearRegion(); OsMpu_SetTask(CoreID, Os_CurrentTaskId[CoreID]); } val = (Os_uint32)OsCpu_GetPSP(); if(tempRetAddr != (Os_AddrType)val) { /*error*/ OsHook_FataErrReport(CoreID, E_OS_PL_SYSFATA_CSA_ERR, OSServiceId_OsIntc_OutISR2, OS_IE_NOMORE_INFO, OS_IE_NO_ERRPAR, OS_IE_NO_ERRPAR, OS_IE_NO_ERRPAR); } } } /* BEGIN_FUNCTION_HDR *********************************************************************************************** * Function Name: OsIntc_InISR1 * * Description: Entering a Category 1 interrupt * * Inputs: CoreID,ISRID * * Outputs: None * * Limitations: Called in generated ISR, interrupt must be disabled before call this API, Ctx must be saved *********************************************************************************************** END_FUNCTION_HDR*/ FUNC (void, OS_CODE) OsIntc_InISR1 ( CoreIdType CoreID, ISRType ISRID ) { /* up and low context has been saved before this function*/ /* interrupt has been disabled, interrupt priority has been set to current ISR*/ /* MPU has been set to set0, which is kernel set*/ OsIsr_InISR1(CoreID); #if(OS_ON == OS_ISR_NEST_SUPPORT) if(Os_ISRCfg[ISRID].enNest == OS_TRUE) { OsIntc_EnableGlobalInterrupt(CoreID); } #endif } /* BEGIN_FUNCTION_HDR *********************************************************************************************** * Function Name: OsIntc_OutISR1 * * Description: Leaving a Category 1 interrupt * * Inputs: None * * Outputs: None * * Limitations: None *********************************************************************************************** END_FUNCTION_HDR*/ FUNC(void, OS_CODE) OsIntc_OutISR1 ( void ) { CoreIdType CoreID; CoreID = OsCpu_GetCoreID(); OsIntc_DisableGlobalInterrupt(CoreID); OsIsr_OutISR1(CoreID); OsIntc_EnableGlobalInterrupt(CoreID); } /* BEGIN_FUNCTION_HDR *********************************************************************************************** * Function Name: OsIntc_CheckISREnabled * * Description: Check the ISR * * Inputs: CoreID,ISRID * * Outputs: None * * Limitations: None *********************************************************************************************** END_FUNCTION_HDR*/ FUNC(Os_boolean, OS_CODE) OsIntc_CheckISREnabled(CoreIdType CoreID, ISRType ISRID) { (void) CoreID; OS_PL_DSYNC(); OS_PL_ISYNC(); Os_uint32 CheckISRFlag; /*PRQA S 4571 ++*/ /* *The number of interrupts in vector table does not require the type of int to represent and left shift is to calculate the register value used. */ Os_uint8 vectorNumber = Os_ISRCfg[ISRID].vectorIndex - (Os_uint16)16; CheckISRFlag = OS_REG_BIT_READ32(OS_NVIC_BASEADDR + (Os_uint32)OS_NVIC_ISER_OFFSET(vectorNumber)); CheckISRFlag = (CheckISRFlag & ((Os_uint32)1 << ((vectorNumber)% (Os_uint32)32))); if(CheckISRFlag == 0) { return OS_FALSE; } else { return OS_TRUE; } /*PRQA S 4571 --*/ OS_PL_DSYNC(); OS_PL_ISYNC(); } #if((OS_TIMING_PROTECTION_SUPPORT == OS_ON)||(OS_MEM_PROTECTION_SUPPORT == OS_ON)||(OS_APPLICATION_NUMBER > 0)) /* BEGIN_FUNCTION_HDR ******************************************************************************** * Function Name: OsIntc_Setjmp * * Description: Set jump point * * Inputs: jmp_buf * * Outputs: None * * Limitations: Called in generated ISR ******************************************************************************** END_FUNCTION_HDR*/ /*PRQA S 3008 ++*/ /* *Assembly without impact. */ FUNC(Os_sint32, OS_CODE) OsIntc_Setjmp /*PRQA S 3008 --*/ ( Os_uint32 * jmp_buf/*jmp_buf is used for R0 not ununsed parameter*/ ) { #if defined(OS_QAC) #else OS_ASM_KEYWORD ( "STR R13,[R0] \n" "ADD R0,R0,#4 \n" "STMIA R0,{R1-R12,R14} \n" ); #endif/*(OS_QAC)*/ return 0; } /* BEGIN_FUNCTION_HDR ******************************************************************************** * Function Name: OsIntc_Longjmp * * Description: Return jump point * * Inputs: None * * Outputs: None * * Limitations: Called in Hook ******************************************************************************** END_FUNCTION_HDR*/ /*PRQA S 3008 ++*/ /* *Assembly without impact. */ FUNC(Os_sint32, OS_CODE) OsIntc_Longjmp /*PRQA S 3008 --*/ ( Os_uint32 * jmp_buf/*jmp_buf is used for R0 not ununsed parameter*/ ) { #if defined(OS_QAC) #else OS_ASM_KEYWORD ( "LDR R13,[R0] \n" "ADD R0,R0,#4 \n" "LDMIA R0,{R1-R12,R14} \n" ); #endif/*(OS_QAC)*/ return 1; } /* BEGIN_FUNCTION_HDR ******************************************************************************** * Function Name: OsIntc_SVC_Schedule * * Description: PendSV Schedule in intc * * Inputs: None * * Outputs: None * * Limitations: Called in OsIntc_KillISRSchedule ******************************************************************************** END_FUNCTION_HDR*/ STATIC FUNC(void, OS_CODE) OsIntc_SVC_Schedule(void) { #if defined(OS_QAC) #else OS_ASM_KEYWORD( "cpsid i \n" "ldr r1, =OsCpu_TaskSwitch \n" "blx r1 \n" "isb \n" "LDR r3, = OsCpu_FirstTaskCSA \n" "ldr r0,[r3] \n" /*Load psp from OsCpu_FirstTaskCSA[CoreID] */ /*control*/ "ldr r1,[r0],#4 \n" "msr control,r1 \n" "ldmia r0!, {r4-r11, r14} \n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */ " \n" "tst r14, #0x10 \n" /* Is the task using the FPU context? If so, pop the high vfp registers too. */ "it eq \n" "vldmiaeq r0!, {s16-s31} \n" " \n" "msr psp, r0 \n" /* Set process stack. */ "cpsie i \n" "bx r14 \n" " \n" ); #endif/*(OS_QAC)*/ } /* BEGIN_FUNCTION_HDR ******************************************************************************** * Function Name: OsIntc_KillISRSchedule * * Description: After running C2ISR is killed, call this function to schedule * * Inputs: None * * Outputs: None * * Limitations: Called in generated ISR, after user isr hook ******************************************************************************** END_FUNCTION_HDR*/ FUNC(void, OS_CODE) OsIntc_KillISRSchedule ( CoreIdType volatile CoreID, ISRType volatile ISRID, Os_boolean volatile needSchedule ) { Os_uint32 volatile OS_INIT_XPSRVectorIndex; Os_uint32 volatile pcxptr; Os_uint32 volatile JumpFun; /* free CSA of current runnning ISR*/ if(needSchedule == OS_TRUE) { if(Os_CurrentTaskId[CoreID] == OS_INVALID_TASK_ID) { OsKernel_CheckTaskSwitch(CoreID); } if(Os_TaskCBTable[Os_CurrentTaskId[CoreID]].OsTaskState == OS_TASK_READY) { if(OsCpu_TpFlag == OS_TRUE) { OsCpu_TpFlag = OS_FALSE; } if(OsCpu_MPUFlag == OS_TRUE) { OsCpu_MPUFlag = OS_FALSE; } OS_INIT_XPSRVectorIndex = OS_INIT_XPSR | (Os_uint32)(Os_ISRCfg[ISRID].vectorIndex); JumpFun =(Os_uint32)&OsIntc_Longjmp; /*switch to task mpu set as mpu not saved in CSA*/ OsCpu_SetPendSV(); OsMpu_ClearRegion(); OsMpu_SetTask(CoreID, Os_CurrentTaskId[CoreID]); pcxptr = OsCpu_GetMSP(); /*PRQA S 0428 ++*/ /* *Need to return to this function when return. */ (*(Os_uint32*)(pcxptr + OS_SHIFT_SEVEN_WORD)) = (Os_uint32)JumpFun; /*PRQA S 0428 ++*/ (*(Os_uint32*)(pcxptr + OS_SHIFT_EIGHT_WORD)) = OS_INIT_XPSRVectorIndex; (*(Os_uint32*)(pcxptr + OS_SHIFT_ONE_WORD)) = (Os_uint32)&OsIntc_Envbuf[Os_ISRCfg[ISRID].Prio]; (*(Os_uint32*)pcxptr) = OS_ISR_RETURN_TASK; #if defined(OS_QAC) #else OS_ASM_KEYWORD( "cpsie i \n" "POP {PC} \n" ); #endif/*(OS_QAC)*/ } if((OsCpu_MPUFlag == OS_TRUE) || (OsCpu_TpFlag == OS_TRUE))/*Os_TaskCBTable[Os_CurrentTaskId[CoreID]].OsTaskState == OS_TASK_SUSPENDED ||Os_CurrentTaskId[CoreID] == 0xff*/ { if(OsCpu_TpFlag == OS_TRUE) { OsCpu_TpFlag = OS_FALSE; } if(OsCpu_MPUFlag == OS_TRUE) { OsCpu_MPUFlag = OS_FALSE; } /*switch to task mpu set as mpu not saved in CSA*/ OsMpu_ClearRegion(); OsMpu_SetTask(CoreID, Os_CurrentTaskId[CoreID]); OS_INIT_XPSRVectorIndex = OS_INIT_XPSR | (Os_uint32)(Os_ISRCfg[ISRID].vectorIndex); pcxptr = OsCpu_GetMSP(); (*(Os_uint32*)(pcxptr + OS_SHIFT_ONE_WORD)) = (Os_uint32)&OsIntc_Envbuf[Os_ISRCfg[ISRID].Prio]; (*(Os_uint32*)(pcxptr + OS_SHIFT_SIX_WORD)) = OS_ISR_RETURN_TASK; (*(Os_uint32*)(pcxptr + OS_SHIFT_SEVEN_WORD)) = (Os_uint32)&OsIntc_SVC_Schedule; (*(Os_uint32*)(pcxptr + OS_SHIFT_EIGHT_WORD)) = OS_INIT_XPSRVectorIndex; (*(Os_uint32*)pcxptr) = OS_ISR_RETURN_ISR; #if defined(OS_QAC) #else OS_ASM_KEYWORD( "cpsie i \n" "POP {PC} \n" ); #endif/*(OS_QAC)*/ } else { if(OsCpu_TpFlag == OS_TRUE) { OsCpu_TpFlag = OS_FALSE; } if(OsCpu_MPUFlag == OS_TRUE) { OsCpu_MPUFlag = OS_FALSE; } OsMpu_ClearRegion(); OsMpu_SetTask(CoreID, Os_CurrentTaskId[CoreID]); OsCpu_SVC_Schedule(); } } else/*return to saved context*/ { if(Os_IntNestDepth[CoreID] != OS_INVALID_ISR) { #if((OS_ON == OS_ISR_NEST_SUPPORT) && (OS_ON == OS_MEM_PROTECTION_SUPPORT)) /*switch to task mpu set as mpu not saved in CSA*/ OsMpu_ClearRegion(); OsMpu_SetISR(CoreID, Os_CoreCfg[CoreID].nestIsrIdPtr[Os_IntNestDepth[CoreID]]); #else /*fata err*/ #endif if(OsCpu_TpFlag == OS_TRUE) { OsCpu_TpFlag = OS_FALSE; } if(OsCpu_MPUFlag == OS_TRUE) { OsCpu_MPUFlag = OS_FALSE; } OS_INIT_XPSRVectorIndex = OS_INIT_XPSR | (Os_uint32)(Os_ISRCfg[ISRID].vectorIndex); JumpFun =(Os_uint32)&OsIntc_Longjmp; /*switch to task mpu set as mpu not saved in CSA*/ pcxptr = OsCpu_GetMSP(); /*PRQA S 0428 ++*/ /* *Need to return to this function when return. */ (*(Os_uint32*)(pcxptr + OS_SHIFT_SEVEN_WORD)) = JumpFun; /*PRQA S 0428 ++*/ (*(Os_uint32*)(pcxptr + OS_SHIFT_EIGHT_WORD)) = OS_INIT_XPSRVectorIndex; (*(Os_uint32*)(pcxptr + OS_SHIFT_ONE_WORD)) = (Os_uint32)&OsIntc_Envbuf[Os_ISRCfg[ISRID].Prio]; (*(Os_uint32*)pcxptr) = OS_ISR_RETURN_ISR; #if defined(OS_QAC) #else OS_ASM_KEYWORD( "cpsie i \n" "POP {PC} \n" ); #endif/*(OS_QAC)*/ } else { OS_INIT_XPSRVectorIndex = OS_INIT_XPSR | (Os_uint32)(Os_ISRCfg[ISRID].vectorIndex); JumpFun =(Os_uint32)&OsIntc_Longjmp; /*switch to task mpu set as mpu not saved in CSA*/ OsMpu_ClearRegion(); OsMpu_SetTask(CoreID, Os_CurrentTaskId[CoreID]); pcxptr = OsCpu_GetMSP(); /*PRQA S 0428 ++*/ /* *Need to return to this function when return. */ (*(Os_uint32*)(pcxptr + OS_SHIFT_SEVEN_WORD)) = JumpFun; /*PRQA S 0428 ++*/ (*(Os_uint32*)(pcxptr + OS_SHIFT_EIGHT_WORD)) = OS_INIT_XPSRVectorIndex; (*(Os_uint32*)(pcxptr + OS_SHIFT_ONE_WORD)) = (Os_uint32)&OsIntc_Envbuf[Os_ISRCfg[ISRID].Prio]; if((OsCpu_MPUFlag == OS_TRUE) || (OsCpu_TpFlag == OS_TRUE)) { if(OsCpu_TpFlag == OS_TRUE) { OsCpu_TpFlag = OS_FALSE; } if(OsCpu_MPUFlag == OS_TRUE) { OsCpu_MPUFlag = OS_FALSE; } (*(Os_uint32*)pcxptr) = OS_ISR_RETURN_ISR; } else { (*(Os_uint32*)pcxptr) = OS_ISR_RETURN_TASK; } #if defined(OS_QAC) #else OS_ASM_KEYWORD( "cpsie i \n" "POP {PC} \n" ); #endif/*(OS_QAC)*/ } } } #if(OS_ON == OS_ISR_NEST_SUPPORT) /* BEGIN_FUNCTION_HDR ******************************************************************************** * Function Name: OsIntc_ExitISRCSA * * Description: free ISR CSA, only used in terminate App * * Inputs: None * * Outputs: None * * Limitations: None ******************************************************************************** END_FUNCTION_HDR*/ STATIC FUNC(void, OS_CODE) OsIntc_ExitISRCSA ( void ) { CoreIdType CoreID; ISRType ISRID = OS_INVALID_ISR; CoreID = OsCpu_GetCoreID(); OsIntc_BubbleSort(OsIntc_KilldISRId, (Os_uint32)OS_ISR_NUMBER); OsIntc_KilldISRIdPtr[CoreID]--; ISRID = (ISRType)OsIntc_KilldISRId[OsIntc_KilldISRIdPtrCal[CoreID]].KillIsrId; OsIntc_KilldISRIdPtrCal[CoreID]--; OsIntc_Longjmp(OsIntc_Envbuf[Os_ISRCfg[ISRID].Prio]); } #endif/*#if(OS_ON == OS_ISR_NEST_SUPPORT)*/ /* BEGIN_FUNCTION_HDR *********************************************************************************************** * Function Name: OsIntc_FreeISRCSA * * Description: free ISR CSA, only used in terminate App * * Inputs: CoreID,ISRID * * Outputs: None * * Limitations: None *********************************************************************************************** END_FUNCTION_HDR*/ FUNC(void, OS_CODE) OsIntc_FreeISRCSA ( CoreIdType CoreID, ISRType ISRID ) { /*PRQA S 4643 ++*/ /* Do not include . */ ISRType isrIdx; /*PRQA S 4643 --*/ ISRType tmpIsrId; #if(OS_ON == OS_ISR_NEST_SUPPORT) Os_uint32 mpupcxi_temp1 = (Os_uint32)0; Os_uint32 mpupcxi_temp2 = (Os_uint32)0; #endif /*PRQA S 3432 ++*/ /* P2VAR and other macros in the Compiler conforms to AUTOSAR standard. There's no need to revise. */ P2VAR(ISRType, AUTOMATIC, OS_VAR) nestPtr; /*PRQA S 3432 --*/ #if(OS_ON == OS_ISR_NEST_SUPPORT) OsIntc_KilldISRIdPtrCal[CoreID] = (Os_uint32)(OS_ISR_NUMBER - OS_SHIFT_ONE_BYTE); #endif nestPtr = Os_CoreCfg[CoreID].nestIsrIdPtr; /* loop and remove all ISR belongs to this app, at same time re-sort the queue*/ for(isrIdx = (ISRType)0; isrIdx < Os_IntNestDepth[CoreID]; isrIdx++) { tmpIsrId = nestPtr[isrIdx]; if(ISRID == tmpIsrId) { #if(OS_ON == OS_ISR_NEST_SUPPORT) OsIntc_KilldISRId[OsIntc_KilldISRIdPtr[CoreID]].NestLayer = isrIdx; OsIntc_KilldISRId[OsIntc_KilldISRIdPtr[CoreID]].KillIsrId = ISRID; mpupcxi_temp1 = (Os_uint32)OsIntc_FirstISRCSA[nestPtr[isrIdx + OS_SHIFT_ONE_BYTE]]; mpupcxi_temp2 = mpupcxi_temp1 + OS_SHIFT_ONE_WORD; if((*(Os_uint32*)mpupcxi_temp2) == OS_ISR_NEST_OPTIMIZATION_JUDGE) { mpupcxi_temp1 +=OS_SHIFT_EIGHT_WORD;/*medium opti 8 * 4*/ } else { mpupcxi_temp1 += OS_SHIFT_TWELVE_WORD;/*low opti 12 * 4*/ } (*(Os_uint32*)mpupcxi_temp1) = (Os_uint32)&OsIntc_ExitISRCSA; OsIntc_KilldISRIdPtr[CoreID] ++;/*avoide change local vars*/ #endif break; } } } /* BEGIN_FUNCTION_HDR *********************************************************************************************** * Function Name: OsIntc_ClearPendingISR * * Description: Clear the Pending ISR * * Inputs: CoreID,ISRID * * Outputs: None * * Limitations: None *********************************************************************************************** END_FUNCTION_HDR*/ FUNC(void, OS_CODE) OsIntc_ClearPendingISR(CoreIdType CoreID, ISRType ISRID) { (void) CoreID; /* clear pending interrupt */ OS_REG_WRITE32((OS_NVIC_BASEADDR + OS_NVIC_ICPRO_OFFSET(Os_ISRCfg[ISRID].vectorIndex - 16)), 1 << ((Os_ISRCfg[ISRID].vectorIndex - 16) % 32) ); } /* BEGIN_FUNCTION_HDR *********************************************************************************************** * Function Name: OsIntc_DisableISR * * Description: Disable the ISR * * Inputs: CoreID,ISRID * * Outputs: None * * Limitations: None *********************************************************************************************** END_FUNCTION_HDR*/ FUNC(void, OS_CODE) OsIntc_DisableISR(CoreIdType CoreID, ISRType ISRID) { (void) CoreID; /* disable interrupt */ OS_REG_WRITE32((OS_NVIC_BASEADDR + OS_NVIC_ICER_OFFSET(Os_ISRCfg[ISRID].vectorIndex - 16)), 1 << ((Os_ISRCfg[ISRID].vectorIndex - 16) % 32) ); } /* BEGIN_FUNCTION_HDR *********************************************************************************************** * Function Name: OsIntc_EnableISR * * Description: Disable the ISR * * Inputs: CoreID,ISRID * * Outputs: None * * Limitations: None *********************************************************************************************** END_FUNCTION_HDR*/ FUNC(void, OS_CODE) OsIntc_EnableISR(CoreIdType CoreID, ISRType ISRID) { (void) CoreID; /* enable interrupt */ OS_REG_WRITE32((OS_NVIC_BASEADDR + OS_NVIC_ISER_OFFSET(Os_ISRCfg[ISRID].vectorIndex - 16)), 1 << ((Os_ISRCfg[ISRID].vectorIndex - 16) % 32) ); } #endif #define OS_STOP_SEC_CODE #include "Os_MemMap.h"