|
|
View previous topic :: View next topic |
Author |
Message |
YulL
Joined: 29 Sep 2004 Posts: 39 Location: Paris (France)
|
Interruption into an interrupt |
Posted: Wed Nov 17, 2004 4:35 am |
|
|
Hello,
Could you tell me if it is possible that an interrupt generated by the serial port of my PIC16LF873A should be in a function that is about the interrupt? For example into :
#int_rda
void serial_isr()
{ ... }
Best regards |
|
|
Ttelmah Guest
|
Re: Interruption into an interrupt |
Posted: Wed Nov 17, 2004 5:01 am |
|
|
YulL wrote: | Hello,
Could you tell me if it is possible that an interrupt generated by the serial port of my PIC16LF873A should be in a function that is about the interrupt? For example into :
#int_rda
void serial_isr()
{ ... }
Best regards |
No.
The sequence is:
In 'main body' code.
Interrupts enabled.
Event occurs, triggering interrupt.
Global interrupt enable flag is disabled by the hardware, and the interrupt 'dispatcher' is called.
Interrupt dispatcher saves the system registers.
Interrupt dispatcher scans the interrupt flags to detect which interrupt occured, and calls the corresponding subroutine.
Subroutine returns, and the 'interrupt flag' for this interrupt is cleared.
Interrupt dispatcher restores the system registers.
System returns from the dispatcher, and in the same instruction, re-enables the global interrupt flag.
So once the system starts to respond to an interrupt, the global interrupt flag is cleared, preventing an interrupt from inside an interrupt.
In the case of the default CCS code, since the specific interrupt flag for the event that is being 'serviced', is cleared at the end of the routine, if there has been a second trigger during the service routine, this will be 'lost'. You can improve this behaviour, by adding the keyword 'noclear' to the interrupt handler declaration, _and clearing the interrupt flag yourself, at the start of the handler_. If this is done, a second interrupt in the duration of the handler, will leave the interrupt flag set, and when the code returns to the main routine, the very next instruction, the interrupt handler will be called a second time.
It is also important to understand that there is no 'timestamp' associated with the different interrupt flags. So if (for instance), you have a timer interrupt that triggers in the interval between the serial interrupt firing, and the global dispatcher checking the flags, and the timer flag is checked before the serial flag, then it is the timer interrupt that will be serviced, and the serial interrupt will have to wait till this is complete, and the code returns to the main routine, when the interrupt handler will be called again. The #priority statement controls the order that the flags are checked. Potentially, if an interrupt is called very frequently, and the code is fairly long, this can result in lower priority interrupts never being reached.
This is why it is _vital_, that the user does not touch the global interrupt enable, inside an interrupt event. Doing this, could allow the code to interrupt back into 'itself', and destroy the contents of the system registers, leading to chaos...
The 'exception' to all the above, is with the 18 series chips (doesn't therefore apply to you), where there is a second 'high priority' interrupt that can interrupt a lower priority event. This has a lot of 'caveats'. It is your responsibility to save the required registers into another location in this handler (the system only saves the very 'core' registers automatically), and on many of the chips, there is a fault in the hardware, making using this interrupt for 'asynchronous' events (triggers that are not governed by the processors master clock), very dangerous. Suppport for this type of interrupt, is very poorly covered in the current compilers.
Best Wishes |
|
|
YulL
Joined: 29 Sep 2004 Posts: 39 Location: Paris (France)
|
|
Posted: Wed Nov 17, 2004 6:26 am |
|
|
Thanks for your quick answer! You wrote a book
I've learned a lot with the reading of your post...
But it is not so complicated...
I used :
#int_rda
void serial_isr()
{ disable_interrupts(INT_RDA);
...
enable_interrupts(INT_RDA);
}
and I'm going to try :
#int_rda
void serial_isr()
{...}
Am I alright?... |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Wed Nov 17, 2004 6:57 am |
|
|
Yes, no need to disable/enable ints inside of the handler. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|