We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hello Forum, I wanna disable interrupts on my 80C167. As far as I understood the User Manual, writes to the PSW (containing the IEN bit and the Interrupt-Level) will take place about two cycles later, which leads to the following effect: If during this very two cycles an Interrupt Request occurs, this interrupt will be accepted and executed, while the PSW-changes took place. This means, during the execution of the interrupt service routine, all other interrupts are disabled, even the higher prioritized, which leads to problems, in particular if it takes a long time to execute. This is what I mean by "realtime unsafe". If I use
#pragma DISABLE
I never thought of the possibility that an interrupt service routine can be executed with the IEN flag cleared. The manual clearly says it's possible. Section 'Interrupt and Trap Functions -> Interrupt System Structure -> Interrupt Control Registers -> Interrupt Enable Bit IEN': 'When IEN is cleared, no new interrupt requests are accepted by the CPU. Requests that already have entered the pipeline at that time will process, however.' It seems that for realtime safety one has to use ATOMIC with PSW-modifying code (or modify xxIC registers, which indeed can be boring). Thanks for the warning! Mike.
After countless 'learning experiences' I have made it a policy to never globally disable interrupts. It always seems to bite me when I do. The technique I use in the '167 is to change the priority level instead:
_bfld_(PSW, 0xF000, 0xD000); _nop_();
_bfld_(PSW, 0xF000, 0xF000); _nop_();
_atomic_(0); IEN = 0; _nop_(); _endatomic_();
Hello, as far as I remember, it doesn't matter whether I change IEN or ILVL: I want to change a few variables uninterruptile, therefore I change the ILVL. In the meantime, the longest running low-prioritized interrupt will be accepted and executed with ILVL=0xF, thus blocking all other interrupts. Ciao - thanks for any more hints - Peter
Hello Mike, the statement you referred to says only that you have to add NOPs or other interruptileable stuff after changing PSW and before you are "IRQ-Safe". We have to keep two different things apard: - Machine commands after PSW-change take place before being "IRQ-Safe". - Interrupt Accepatance in this gap leads to unwanted higher-level-interrupt-blocking. The Keil #pragma DISABLE code keeps in mind the first point (by adding two NOPs), but in my opinion doesn't handle the second point. But there is another thing that maybe could happen. Please see my answer to my answer to Scott's posting. Thanks - Peter
Hello, I got an assumption: Maybe the following happens (just an idea, I'm not sure about that): After accepting an interrupt of, say, an priority of 2, while changing the ILVL to 15, the ILVL of 15 will be immediately overwritten by the ILVL of 2, hence this will be realtime safe. By ending the interrupt routine, the ILVL of 15 will be restored, and my to-be-atomic-code will be executed. (BTW: This is the method that Keil's #pragma DISABLE is using.) All things went just fine, opposed to the situation the IEN flag is used. If there is somebody who _knows_ and doesn't just assume about that, please answer. AFAIR there was a hint somewhere in Siemens' or Keil's documentation dealing with exact the method to choose to be realtime safe. But I can't remember where this was and haven't found it yet. Maybe somebody can help my mind to remember... Thanks - Peter
The Infineon '166 users manual says when the PSW is the target of an operation it is changed during the 'Execute' state but this change is ignored by the interrupt processing hardware for at least another state (therefore the NOP). This means the PSW that gets pushed on the stack is the new one (0xFxxx) and the low priority interrupt replaces it with it's priority (0x2xxx), leaving higher priorities open until the RETI. Best luck
I have read this thread very carefully and what I gather is that this would be a solution to the problem. Is that true? Would using the atomic instruction prevent an interrupt from being serviced immediately after the bfld instruction?
_atomic_(0); _bfld_(PSW, 0xF000, 0xD000); _nop_(); _endatomic_(); _atomic_(0); _bfld_(PSW, 0xF000, 0xF000); _nop_(); _endatomic_();
Hi Walt, as far as I understood the contents of this thread (in those days), it is realtime-safe to use #DISABLE. Don't use IEN. Setting the acceptance level high, on the other hand, is safe due to the overwriting-and-restoring-mechanism on entering end exiting of lower level interrupt routines. Ciao - Peter
Hi Peter, I will investigate #DISABLE. Thanks, Walt