Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem


Loss of Interrupts

Posted by dave---w on July 24, 2017


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

// call the C function to handle the interrupt
jal U2InterruptHandler

// restore the context of the next task to execute

.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?

Thanks for the new sets of eyes.


Loss of Interrupts

Posted by rtel on July 24, 2017

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.

Loss of Interrupts

Posted by dave---w on July 24, 2017

Here is the receive side...

~~~ void U2InterruptHandler( void)

{ U8 c; static BaseType_t YieldRequired;

// look for receive interrupt
	// look for more receive data
		c = U2RXREG;
		*RxBufEnd = c;
		if(++RxBufEnd == (RxBuffer + BUF_SIZE))
			RxBufEnd = RxBuffer;

		// for every FS, increment the semaphore
		if(c == FS)
			// increment the task semaphore
			xSemaphoreGiveFromISR(UartRxSemaphore, &YieldRequired);

			// clear overrun errors
			U2STAbits.OERR = FALSE;

	// clear the receive interrupt flag

... <transmit side>

} ~~~

I will search the archives. Thanks for the advice.


Loss of Interrupts

Posted by rtel on July 24, 2017

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.

Loss of Interrupts

Posted by dave---w on July 24, 2017

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


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?

Thanks again.


Loss of Interrupts

Posted by dave---w on July 28, 2017

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 portENDSWITCHINGISR(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.)



Loss of Interrupts

Posted by richard_damon on July 28, 2017

portENDSWITCHINGISR() 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.

Loss of Interrupts

Posted by dave---w on July 28, 2017

Hi Richard,

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 portENDSWITCHINGISR decides from the contents of YieldRequired whether or not to task switch.

But also, looking the the reference manual, I see a different function portYIELDFROMISR().

Basically, I'm just looking for confirmation I've implemented this right and that is not the reason for missing interrupts.



Loss of Interrupts

Posted by richard_damon on July 28, 2017

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.

Loss of Interrupts

Posted by dave---w on July 29, 2017

Thanks for the guidelines.


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]

Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

Meet us at Embedded World. Hall 3A-525.

Hear from Richard Barry at Embedded World. Feb 28, 16:00, Hall 4-428.

Video: Watch James Gosling & Richard Barry at re:Invent, Las Vegas 2017.

FreeRTOS kernel V10.0.1 is available for immediate download. Now MIT licensed.

FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS