1

What is the difference between INTDisableInterrupts() and INTEnableSystemMultiVectoredInt() and asm volatile ("di")

newb7777
  • 517
  • 5
  • 22

1 Answers1

3

In Pic32, there are "normal" interrupts and "Vectored" interrupts. If you aren't familliar with Pic32, "vectored" means that each interrupt has it's own interrupt handler function. You can have a function for UART interrupt and another function for RS232 (UART),... You do not have to put everything in a 'high priority' and a 'low priority' interrupt anymore.

So : INTDisableInterrupts() will simply disable the interrupts. This will call "di".

"di" : simply disables the interrupts, in assmebler.

INTEnableSystemMultiVectoredInt() will let tell your PIC32 to use a different function for all your interrupts. If you did not provide interrupt handler functions for each of your interrupts, then it will seem as if they are disabled. Your interrupts are NOT disabled however, and if you write an handler for an Vectored interrupt, your pic will use it.

UPDATE:

@newb7777

To answer your question : If you have only one interrupt ( not vectored ), then you have one big function that must check all the "Interrupt Flag register" to know what caused the interrupt and process the right code.

If you have 'vectored interrupts', then the PIC behaves like most processors ( they almost all have vectored interrupts ). When something happened that would generate an interrupt then a register changes value. For instance one that would be called "UART_1_Rx_Received". Before executing an instruction, the processor sees that this flag is on and if the 'Interrupt enable register' and the 'global interrupt enable register' are both ON, then the interrupt function will be called. Note that all interrupts also have a priority. If a high-priority interrupt is running then it will never be interrupted by an interrupt with <= priority. If a low priority interrupt is running then a higher priority interrupt could interrupt it.

However, you should not lose interrupts because if a byte comes from the UART that would generate a low-priority interrupt and a higher-priority interrupt is running, then the flag will still be set. When the higher priority interrupt ends, then the lower priority will be executed.

Why do we disable interrupts then ? The main reasons to disable interrupts are: - the interrupt changes the value of a variable. if the code loops :

for(i=0;i==BufferSize;i++)

and your interrupt changes the value of BufferSize while this loop executes, then the loop could execute forever (if BufferSize changes from 100 to 2 while I has the value 99 then I will not get back to 2 for a long time...). You may want to disable interrupt before doing the loop in that case. Another reason could be that you want to execute something where timing is important. another reason is that sometimes, MCU needs you to execute a few instructions in a specific order to unlock something that would be dangerous to execute by error so you don't want an interrupt in the middle of the process. If you have a circular buffer that received bytes from an interrupt and you pool that buffer from the code then you want to make sure to disable interrupts before removing a variable from the buffer to make sure the variables don't change while you read them.

There are many reasons to disable interrupts, just keep in mind that you can also create a "volatile" variable for global variables that are used in and outside of interrupts.

One last thing to answer your question : if you get an interrupt for every byte that comes in your UART at 115,200 baud, and you have an interrupt function that takes a long time to execute, then it is possible to miss a byte or two. In that case if you are lucky there is a hardware buffer that allows you to get them but it is possible also that there isn't and you would lose byte in your communication port. Interrupts must always be as short as possible. When possible, set a flag in the interrupt and do the processing in your main loop outside of the interrupt. When you have many interrupt levels, always use high priority for interrupts that could trigger often and low priority if an interrupt processes for a long time.

  • So you have to write a handler for each of the vectored interrupt. What happens when another vectored interrupts fires at the time while one is presently being handled. Do you miss the second interrupt? I guess this is why you want to disable interrupt when you are servicing an interrupt. Please shed some light in this. – newb7777 May 08 '18 at 20:31