S32K314 RTD (MCAL) - High Priority ISR Deadlock Caused by OsIf Critical Sections S32K314 RTD (MCAL) - High Priority ISR Deadlock Caused by OsIf Critical Sections Hello, I am developing an application on the following platform: MCU: NXP S32K314 RTD 7.0.0 (AUTOSAR MCAL) FreeRTOS 7.0.0 S32 Design Studio 3.6.4 During development, I encountered a deadlock related to high-priority interrupts and would like to ask whether my understanding is correct and whether there is a recommended solution. Background FreeRTOS specifies that ISRs with a priority higher than configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY must not call FreeRTOS APIs. However, I found that many RTD MCAL APIs internally execute FreeRTOS critical section APIs through the following call chain: MCAL API
↓
SchM_Enter_xxx()
↓
OsIf_SuspendAllInterrupts()
↓
SuspendAllInterrupts()
↓
OsIf_Interrupts_SuspendAllInterrupts()
↓
taskENTER_CRITICAL_FROM_ISR() and MCAL API
↓
SchM_Exit_xxx()
↓
OsIf_ResumeAllInterrupts()
↓
ResumeAllInterrupts()
↓
OsIf_Interrupts_ResumeAllInterrupts()
↓
taskEXIT_CRITICAL_FROM_ISR() This behavior exists even in APIs that only perform simple peripheral register accesses, such as DIO and GPT. Problem When a MCAL API is called from a high-priority ISR (priority higher than configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY), the internal call to taskENTER_CRITICAL_FROM_ISR() causes the FreeRTOS interrupt masking state to become inconsistent. As a result, after taskEXIT_CRITICAL_FROM_ISR() returns, BASEPRI is not restored correctly, causing lower-priority interrupts such as SysTick and PendSV to remain masked. The scheduler eventually stops because xPortSysTickHandler() is no longer executed. I was able to reproduce this issue using APIs such as: Dio_FlipChannel() GPT (PIT) interrupt processing Other MCAL APIs that use SchM exclusive areas Current Workaround To avoid modifying RTD-generated source code directly, I used the GNU linker --wrap option to wrap the following functions: OsIf_Interrupts_SuspendAllInterrupts()
OsIf_Interrupts_ResumeAllInterrupts() The wrapper checks the current interrupt priority. Please refer to the attached WrapperExample.c. If the current ISR priority is higher than configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY, it skips the original function. Otherwise, it calls the original implementation. This workaround appears to resolve the deadlock while leaving the generated RTD source unchanged. Questions Is this behavior expected by design in the RTD MCAL? Is it recommended to call DIO, GPT, CAN, or other MCAL APIs from high-priority ISRs? Does NXP recommend implementing dedicated drivers (Complex Device Drivers) for high-priority real-time functions such as watchdog servicing or GPIO toggling? Is wrapping OsIf_Interrupts_SuspendAllInterrupts() and OsIf_Interrupts_ResumeAllInterrupts() using the GNU linker --wrap option an acceptable workaround? Is there an official or recommended solution for this problem that does not require modifying generated RTD source code? Any advice or recommendations would be greatly appreciated. Thank you. Re: S32K314 RTD (MCAL) - High Priority ISR Deadlock Caused by OsIf Critical Sections Hello @tobara,
The case is currently pending input from the RTD development team.
BR, Daniel Re: S32K314 RTD (MCAL) - High Priority ISR Deadlock Caused by OsIf Critical Sections Hi,
please see below punctual answers to your question:
Is this behavior expected by design in the RTD MCAL?Answer: yes, this happens because you are calling OS APIs from a CAT1 interrupt (aka interrupts with prio higher than MAX SYSCALL). The purse of interrupts higher than MAX_SYSCALL is to do work with minimal latency also unhindered by the RTOS.If you need to avoid latency introduced by RTOS then you should not call APIs that in the end use the RTOS.
Is it recommended to call DIO, GPT, CAN, or other MCAL APIs from high-priority ISRs?
Answer: no, not larger than MAX_SYSCAL, for the reason mentioned in first answer.
Does NXP recommend implementing dedicated drivers (Complex Device Drivers) for high-priority real-time functions such as watchdog servicing or GPIO toggling?
Answer: if you already can tolerate the latency introduced by the RTD SchM, OSIf APIs, RTOS then you can just use the existing drivers but just call them from the higher interrupt but lower than MAX_SYSCALL. You still get the priority boost but not the problems described in the ticket.
Is wrapping OsIf_Interrupts_SuspendAllInterrupts() and OsIf_Interrupts_ResumeAllInterrupts() using the GNU linker --wrap option an acceptable workaround?
Answer: No, a quick analysis points in the direction that this workaround protects in only one direction. It might avoid the deadlock but does not protect lower prio ISR that share registers / resources with higher prio ISR (> MAX_SYSCALL). This implementation can introduce race conditions on shared registers and global variables.
Is there an official or recommended solution for this problem that does not require modifying generated RTD source code?Answer (but it needs to be confirmed by the RTD team): do not call RTD / RTOS APIs from IRQ > MAX_SYSCALL. If you can tolerate the current RTD->OSIF->RTOS latencies then just use a higher prio IRQ but lower than MAX_SYSCALL.
All answers need to be confirmed by the RTD team, I'm answering from a RTOS point of view.
Re: S32K314 RTD (MCAL) - High Priority ISR Deadlock Caused by OsIf Critical Sections Thank you very much for your detailed explanation. I now understand the following design constraints of the NXP RTD/MCAL: RTD/MCAL APIs must not be called from high-priority ISRs (interrupts with a priority higher than configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY). Although using --wrap may prevent the deadlock, bypassing the RTD critical sections can introduce race conditions when resources or registers are shared between high- and low-priority contexts. I have a few additional questions. If an application requires processing in a high-priority ISR (AUTOSAR Category 1 ISR), what is the recommended software architecture? Should such functionality always be implemented as a Complex Device Driver (CDD) or a dedicated low-level driver? If a GPIO port or timer channel is exclusively owned by a single high-priority ISR and is never accessed from any other task or ISR, would the concerns about race conditions still apply to the --wrap workaround? Is it correct to understand that the current RTD/MCAL does not provide a supported way to use its APIs from high-priority ISRs, and therefore high real-time functions must be implemented using a CDD or a dedicated driver? From my experience with embedded software outside the automotive domain, hardware abstraction layers are often designed to be independent of the operating system. Therefore, I was surprised to find that simple GPIO and timer APIs internally invoke RTOS critical section APIs. As a reference, I have attached the GPT driver that I implemented to avoid this issue (CpuPit.h/c). I would appreciate any comments or suggestions from the RTD team. Thank you again for your support.
記事全体を表示