I have an MC9S12XEP100 application with the following interrupts:
I'm seeing occasional "spurious interrupts" when a large amount of CAN0 data is being received, and all 3 ECT ISRs are enabled. (Even if the ECT ISR content is just resetting their respective ECT_TFLG1).
If I disable the XGATE ECT2ISR (with the same amount of CAN0 traffic), no spurious interrupts occur. I based my XGATE implementation on the example "Freescale\CWS12v5.1\(CodeWarrior_Examples)\HCS12X\S12XE_XGATE_setup" which uses the ROUTE_INTERRUPT macro to assign the ECT2ISR, TIM3ISR and TIM4ISR to the XGATE.
What could be causing XGATE spurious interrupts? What additional troubleshooting can I do?
Thank you
已解决! 转到解答。
Hi,
A spurious interrupt in S12 devices occurs when an interrupt request becomes inactive after the interrupt has been recognized but before the vector request is processed. This can happen if the specific interrupt is disabled after it is signaled but before the interrupt source is acknowledged.
In simpler terms, it's like your phone ringing (an interrupt), but when you pick it up, there's no one on the other end (the interrupt source is no longer active). This mechanism ensures that the CPU can handle unknown or unexpected interrupts in a predictable manner.
The root cause for spurious interrupt is that the source of interrupt is unknown, where an interrupt request becomes inactive after the interrupt has been recognized, but prior to the vector request. This kind of scenario is mostly happened with asynchronous operation.
For example, in pump application, when the pump is switched off, it will disable the communication timer's interrupt. If exactly at the time (which happens very rarely, likely in the first cycle in the exception processing flow of S12Z CPU), the corresponding timer's interrupt is triggered. S12Z enters the exception processing flow. But the interrupt request becomes inactive and spurious interrupt will be entered. To avoid such scenario, it's better to wait for another extra one period timer interrupt. After that interrupt, disable this interrupt could be implemented immediately.
General advice to avoid spurious interrupts in S12 devices, you can follow these best practices:
- Correct interrupt flag clearing.
Let FLAGS register is set to 0b10101010 and we want to clear only bit 1. Then…
… incorrect approach FLAGS=FLAGS | 0b00000010; // the operation is read modify write so all flags are cleared
… correct approach FLAGS= 0b00000010;
For edge-sensitive interrupts, incorrect handling can lead to missed or spurious interrupts. For example, if the interrupt flag is cleared before the interrupt condition is fully resolved, the system might miss subsequent interrupts.
- Proper Interrupt Configuration: Ensure that all interrupts are correctly configured and enabled only when necessary. Avoid enabling interrupts that are not required for your application.
- Interrupt Masking: Use interrupt masking to prevent interrupts from being recognized when they are not needed. This can help avoid spurious interrupts caused by transient conditions.
- Debouncing External Signals: If your interrupts are triggered by external signals, make sure to debounce these signals to avoid noise or glitches that can cause spurious interrupts.
- Interrupt Priority Management: Properly manage the priority of interrupts to ensure that higher priority interrupts are handled first. This can help in reducing the chances of spurious interrupts.
- Software Checks: Implement software checks to verify the validity of the interrupt source before processing the interrupt. This can help in identifying and ignoring spurious interrupts.
Best regards,
Ladislav
Hi,
A spurious interrupt in S12 devices occurs when an interrupt request becomes inactive after the interrupt has been recognized but before the vector request is processed. This can happen if the specific interrupt is disabled after it is signaled but before the interrupt source is acknowledged.
In simpler terms, it's like your phone ringing (an interrupt), but when you pick it up, there's no one on the other end (the interrupt source is no longer active). This mechanism ensures that the CPU can handle unknown or unexpected interrupts in a predictable manner.
The root cause for spurious interrupt is that the source of interrupt is unknown, where an interrupt request becomes inactive after the interrupt has been recognized, but prior to the vector request. This kind of scenario is mostly happened with asynchronous operation.
For example, in pump application, when the pump is switched off, it will disable the communication timer's interrupt. If exactly at the time (which happens very rarely, likely in the first cycle in the exception processing flow of S12Z CPU), the corresponding timer's interrupt is triggered. S12Z enters the exception processing flow. But the interrupt request becomes inactive and spurious interrupt will be entered. To avoid such scenario, it's better to wait for another extra one period timer interrupt. After that interrupt, disable this interrupt could be implemented immediately.
General advice to avoid spurious interrupts in S12 devices, you can follow these best practices:
- Correct interrupt flag clearing.
Let FLAGS register is set to 0b10101010 and we want to clear only bit 1. Then…
… incorrect approach FLAGS=FLAGS | 0b00000010; // the operation is read modify write so all flags are cleared
… correct approach FLAGS= 0b00000010;
For edge-sensitive interrupts, incorrect handling can lead to missed or spurious interrupts. For example, if the interrupt flag is cleared before the interrupt condition is fully resolved, the system might miss subsequent interrupts.
- Proper Interrupt Configuration: Ensure that all interrupts are correctly configured and enabled only when necessary. Avoid enabling interrupts that are not required for your application.
- Interrupt Masking: Use interrupt masking to prevent interrupts from being recognized when they are not needed. This can help avoid spurious interrupts caused by transient conditions.
- Debouncing External Signals: If your interrupts are triggered by external signals, make sure to debounce these signals to avoid noise or glitches that can cause spurious interrupts.
- Interrupt Priority Management: Properly manage the priority of interrupts to ensure that higher priority interrupts are handled first. This can help in reducing the chances of spurious interrupts.
- Software Checks: Implement software checks to verify the validity of the interrupt source before processing the interrupt. This can help in identifying and ignoring spurious interrupts.
Best regards,
Ladislav
The problem ended up being that both the main processor's ECT3ISR and the XGATE's ECT2ISR were being triggered by the same 1 PPS signal. And inside the XGATE ECT2ISR I was clearing its interrupt flag via:
ECT_TFLG1_C2F = 1U
Which I think was erroneously also clearing the main processor's ECT3 flag before the main processor had time to execute its ISR, thereby causing a spurious interrupt.
I updated the XGATE interrupt to instead clear it via:
ECT_TFLG1 = 4U
And now everything is working fine.
Thank you for your help.