PIC32 UART Interrupt always in general handle

guifou wrote on Sunday, June 10, 2012:

Hi!

I’m trying to port my project into Freertos, but the uart interrupt don’t work…
My configuration:
PIC32MX675F512H
MPLAB X
FreeRTOS 7.1.1

I have to make a wrapper for the interrupt so i make a file named “Interrupts_isr.S” containing this:

#include <p32xxxx.h>
#include <sys/asm.h>
#include "../FreeRTOS/ISR_Support.h"
/******************************************************************/
            .extern vU3InterruptHandler
             .global vU3InterruptWrapper
 	.set		noreorder
	.set 		noat
 	.ent		vU3InterruptWrapper
vU3InterruptWrapper:
	portSAVE_CONTEXT
	jal 		vU3InterruptHandler
	nop
	portRESTORE_CONTEXT
	.end vU3InterruptWrapper

then a file containing the handler “Interrupts.c” :

#include "Interrupts.h"
#include <stdio.h>
#include <plib.h>
extern void __attribute__( (interrupt(ipl1), vector(_UART_3_VECTOR))) vU3InterruptWrapper( void );
//this handler toggles a led when arriving into it so i can know if my interrupt  works
void vU3InterruptHandler (void)
{
  for( ;; )
        {
            long int i;
            for(i=0; i<100000 ; i++);
        mPORTEToggleBits(BIT_2);
        }
}

and i’m déclaring the interrupt like this:

    void init_UART_FIFO_TX()
{
    U3STAbits.UTXISEL1 =  1;   //interrupt when buffer is empty
   U3STAbits.UTXISEL0 =  0;   //
  UARTEnable(UART3, UART_ENABLE_FLAGS(UART_PERIPHERAL | UART_TX));
  INTSetVectorPriority(INT_VECTOR_UART(UART3), INT_PRIORITY_LEVEL_7);
  INTSetVectorSubPriority(INT_VECTOR_UART(UART3), INT_SUB_PRIORITY_LEVEL_0);
  INTEnable(INT_SOURCE_UART_TX(UART3), INT_DISABLED);
  INTEnableInterrupts();
}

at the begining of my main i have put also

INTEnableSystemMultiVectoredInt();

THE PROBLEM:
the interrupt is occurring OK but is not redirecting into MY handler but into the _general_exception_handler() that is by default.
It seems that my new wrapper hasn’t overwritten the _general_exception_handler for the UART3 vector!

Thanks for all your help!!!!

rtel wrote on Sunday, June 10, 2012:

Have a look at the official demo in the FreeRTOS download http://www.freertos.org/port_PIC32_MIPS_MK4.html.  It contains an example UART interrupt for the PIC32MX360.  Although this won’t work on the PIC32MX795 because that parts interrupt implementation is different - although the changes required will be minimal (search the forum archive to find other posts on this).  I’m not sure of the PIC32MX695, but suspect it will be more like the 7965 than the 360.

Regards.

guifou wrote on Monday, June 11, 2012:

Hi,

I have looked at the example but i don’t understand why the my handler hasn’t overwritten the default on of freertos? Where in freertos do you define that all the interrupts are by default redirected in the “_general_exception_handler()”?

Thanks!

rtel wrote on Tuesday, June 12, 2012:

Sorry - I don’t understand your last post. 

Have you read the “Interrupt service routines” section of the following page:
http://www.freertos.org/port_PIC32_MIPS_MK4.html.

Have you set the interrupt controller into multi vectored mode by calling INTEnableSystemMultiVectoredInt()?

Regards.

guifou wrote on Tuesday, June 12, 2012:

Ah sorry!

i have read it! but always the problem…
I had already put INTEnableSystemMultiVectoredInt() at the beginning of my main.

My exception always goes there! thats what i explained. It’s at the end of the main of the project and it’s also in the demoç

void vApplicationGeneralExceptionHandler( unsigned portLONG ulCause, unsigned portLONG ulStatus )
{
	/* This overrides the definition provided by the kernel.  Other exceptions 
	should be handled here. */
	for( ;; );
}
[\code]
why is my exception always going there and not in my wrapper as defined in my first post??
What are the conditions for an interrupt to go in this function? not wrapped but activated?
thanks!

guifou wrote on Tuesday, June 12, 2012:

Ah sorry!

i have read it! but always the problem…
I had already put INTEnableSystemMultiVectoredInt() at the beginning of my main.

My exception always goes there! thats what i explained. It’s at the end of the main of the project and it’s also in the demoç

void vApplicationGeneralExceptionHandler( unsigned portLONG ulCause, unsigned portLONG ulStatus )
{
	/* This overrides the definition provided by the kernel.  Other exceptions 
	should be handled here. */
	for( ;; );
}

why is my exception always going there and not in my wrapper as defined in my first post??
What are the conditions for an interrupt to go in this function? not wrapped but activated?
thanks!

davedoors wrote on Tuesday, June 12, 2012:

Where is vApplicationGeneralExceptionHandler() defined? I just searched the entire source tree and cannot find it.

I would think that entering a general exception would be the result of a CPU fault, like trying to execute an invalid instruction, or a misaligned memory access.

guifou wrote on Tuesday, June 12, 2012:

Hi!

It’s the last function of the main.c! who has implemented this function, it’s microchip or FreeRTOS?
Is it possible in MPLAB X to view the compiled assembly code so i can see whats really in my vector interrupt ?

rtel wrote on Tuesday, June 12, 2012:

Which version of FreeRTOS are you using?  The last function in main.c is indeed the general exception handler, but using the Microchip function name as follows:

void _general_exception_handler( unsigned long ulCause, unsigned long ulStatus )
{
	/* This overrides the definition provided by the kernel.  Other exceptions 
	should be handled here. */
	for( ;; );
}

See the MPLAB CX32 users guide for information on the handler, and the MIPS M4K documentation for information on what the exception is.

10.5.2 General Exception
A general exception is any non-interrupt exception which occurs during program
execution outside of bootstrap code (StatusBEV=0). General exceptions are vectored
to offset 0x180 from EBase.
At this location, the 32-bit toolchain places a branch instruction targeting a function
named _general_exception_context(). The provided implementation of this
function saves context, calls an application handler function, restores context and
performs a return from the exception instruction. The context saved is the hi and lo
registers and all General Purpose Registers except s0-s8, which are defined to be
preserved by all called functions and so are not necessary to actively save here again.
The values of the Cause and Status registers are passed to the application handler
function (_general_exception_handler()). If the user application provides an
implementation of _general_exception_context(), that implementation will be
used instead.
void _general_exception_handler (unsigned cause, unsigned status);
A weak default implementation of _general_exception_handler() is provided in
the standard library which merely goes into an infinite loop. If the user application
provides an implementation of _general_exception_handler(), that
implementation will be used instead.

Regards.