I’m stuck trying to figure out why I’m losing bytes with a UART ISR. I send and receive packets of data and rarely I’m missing a byte on the receive side. (CRC causes the message to fail.) This happens on 2 different Microchip PICs, PIC32MX460F512L and PIC32MX470F512L. I’ve gone through the PIC documenation inside and out and haven’t found any problems there. So just to be sure, I want to ask about FreeRTOS (v8.1.2).
I’ve inserted the following code into port_asm.s:
.extern U2InterruptWrapper
////////////////////////////////////////////////////////////////////////////////
//
// UART interrupt service routine
//
////////////////////////////////////////////////////////////////////////////////
.set nomips16
.set noreorder
.ent U2InterruptWrapper
// interrupt entry point
U2InterruptWrapper:
// save the current task context
portSAVE_CONTEXT
// call the C function to handle the interrupt
jal U2InterruptHandler
nop
// restore the context of the next task to execute
portRESTORE_CONTEXT
.end U2InterruptWrapper
My priority is 3, which I believe is the highest priority in the system. My PICs have 8 byte FIFOs and I’m using 115,200 BAUD which is about 83 usec per byte. With a 12.5 nsec clock time in the PIC, there should be plenty of time to read all the bytes from the FIFO.
Is there something I’m missing that might cause this to lose bytes?
Can’t tell from the code you posted. Please show the U2InterruptHandler
code too.
I remember there was some discussion on the PIC32 UART interrupts some
years back. As I recall (?) it resulted from a change in the way
interrupts were handled between different PIC32 part numbers. You mind
find something in the forum on this.
Double check where the interrupt is being cleared - I think on some
devices it needs to be first in the ISR, and on others last. Perhaps
look at the drivers provided by Microchip for the device you are using
as a reference.
Yes, thanks. Been there, done that. I conform to the Microchip usage.
BTW, I forgot the end of the ISR function I posted above. After the transmit side at the end of the function is:
// context switch if necessary
portEND_SWITCHING_ISR(YieldRequired);
I never fully understood what this is doing. I just followed the FreeRTOS examples. The only place this is used is on the RX side when passing the (counting) semaphore from the ISR to the task. Does this make sense?
I’m still having no luck tracking this down. I looked at the ISR vector table and everything appears to be normal with one thing I don’t understand. The CS0 interrupt vector is set to vPortYieldISR. I have no idea what that is, and I mentioned above that I didn’t know what the portEND_SWITCHING_ISR(YiedlRequired); code does. I would guess these 2 are related, but I don’t know.
Is this a required part of the ISR processing? (See post above.)
portEND_SWITCHING_ISR() performs or schedules a task switch if needed (based on the YieldRequired parameter). If an ISR does not use this at the end, then if it woke up a task tthat is now the highest priority, it won’t start to execute until something else cause a task switch (like possibly the time tick).
One some processors, this is performed by software triggering a lowest priority interrupt which forces the scheduler to run.
Sorry for being dense… I’m guessing that when I do the GiveFromISR that the YieldRequired variable is loaded inside that routine. Then before I exit the ISR, the portEND_SWITCHING_ISR decides from the contents of YieldRequired whether or not to task switch.
But also, looking the the reference manual, I see a different function portYIELD_FROM_ISR().
Basically, I’m just looking for confirmation I’ve implemented this right and that is not the reason for missing interrupts.
The various ‘FromISR’ rooutines will set the value of the flag true if they wake up a higher priority task, and thus need to signal you to trigger a scheduler activation.
As to the way you use the variable, from what I have seen, different ports define the mechanism in different ways. (I suspect in part based on how old they are), and some have slightly different rules for how to use these functions.