Interrupt problems, Ver: 9.0.0, Port: PIC32MX

We make new project with PIC32MX370F512L. FreeRTOS port is 9.0.0. We have interrupt issues. I attach sample project which demonstrates the problem: There is interrupt handler for TIMER2, also interrupt setting to the timer. When xSemaphoreCreateMutex() function is called, the interrupt does not work. It doesn’t matter if the scheduler is started or not. I checked already – timer2 is not used by the scheduler for any purpose. The priority level of the timer match the priority level of the handler. The interrupts are enabled. When i comment the function xSemaphoreCreateMutex(), the interrupts are working. The attached project includes the FreeRTOS config, configuration bits and all needed features for test even on simulator

Interrupt problems, Ver: 9.0.0, Port: PIC32MX

~~~ /******************************************************************************* * Filename: TEST_System.c * Microcontroller: PIC32MX370F512L * Hardware: – * Compiler: MPLAB XC32 VER 1.40 or higher * Company: SONECO LTD * Author: DIMITAR BELEV – email: DIMITAR.BELEV@SONECO.BG * Creation Date: 2016.06.18 * Description: This file contains the main() function of the FreeRTOS interrupts test project. * Modification History: 2016.06.30 – Initial revision *******************************************************************************/ //******************************** HEADER FILES ********************************

include <xc.h> // Compiler main file

include <plib.h> // Peripheral library functions

include “FreeRTOS.h” // FreeRTOS main file

include “semphr.h” // Needed FreeRTOS defines and typedefs

include “queue.h” //

include “semphr.h” //

//****************************************************************************** //********************** CONFIGURATION BITS SET IN CODE ************************ // Shadow Register Set Priority Select: #pragma config FSRSSEL = PRIORITY_1 // SRS Priority 1 // Peripheral Module Disable Configuration: #pragma config PMDL1WAY = OFF // Allow multiple reconfigurations // Peripheral Pin Select Configuration: #pragma config IOL1WAY = OFF // Allow multiple reconfigurations // PLL Input Divider: #pragma config FPLLIDIV = DIV_2 // 2x Divider // PLL Multiplier: #pragma config FPLLMUL = MUL_20 // 20x Multiplier // System PLL Output Clock Divider: #pragma config FPLLODIV = DIV_1 // PLL Divide by 1 // Oscillator Selection Bits: #pragma config FNOSC = PRIPLL // Primary Osc w/PLL (XT+,HS+,EC+PLL) // Secondary Oscillator Enable: #pragma config FSOSCEN = OFF // Disabled // Internal/External Switch Over: #pragma config IESO = OFF // Disabled // Primary Oscillator Configuration: #pragma config POSCMOD = HS // HS osc mode // CLKO Output Signal Active on the OSCO Pin: #pragma config OSCIOFNC = OFF // Disabled // Peripheral Clock Divisor: #pragma config FPBDIV = DIV1 // PbClk is Sys_Clk/1 // Clock Switching and Monitor Selection: #pragma config FCKSM = CSDCMD // Clock Switch Disable, FSCM Disabled #pragma config WDTPS = PS1048576 // 1:1048576 // Watchdog Timer Window Enable: #pragma config WINDIS = OFF // Watchdog Timer is in Non-Window Mode // Watchdog Timer Enable: #pragma config FWDTEN = OFF // WDT Disabled (SWDTEN Bit Controls) // Watchdog Timer Window Size: #pragma config FWDTWINSZ = WINSZ_50 // Window Size is 50% // Background Debugger Enable: #pragma config DEBUG = OFF // Debugger is Disabled // JTAG Enable: #pragma config JTAGEN = OFF // JTAG Disabled // ICE/ICD Comm Channel Select: #pragma config ICESEL = ICS_PGx1 // Communicate on PGEC1/PGED1 // Program Flash Write Protect: #pragma config PWP = PWP512K // First 512K // Boot Flash Write Protect bit: #pragma config BWP = ON // Protection Enabled // Code Protect: #pragma config CP = ON // Protection Enabled //****************************************************************************** //**************************** FUNCTION PROTOTYPES ***************************** //void __ISR(TIMER2_VECTOR, IPL4AUTO) TMR2InterruptHandler(void); //****************************************************************************** //****************************** GLOBAL VARIABLES ****************************** SemaphoreHandle_t xSemaphoreTestHandle; // Semaphore handle for the interrupts test //****************************************************************************** //***************************** EXTERNAL VARIABLES ***************************** //****************************************************************************** /******************************************************************************* * Function Name: void main(void) * Input Parameters: NONE * Returned Value: NONE * Precondition: NONE * Affected Global Objects: ALL * Side Effects NONE * Company: SONECO LTD * Author: DIMITAR BELEV – email: DIMITAR.BELEV@SONECO.BG * Creation Date: 2016.06.18 * Short Description: main function of the TDS3002 project. * Remark: NONE * Example: NONE // This function does not have caller *******************************************************************************/ void main(void) { // Enable the pre-fetch cache module to achieve 100MHz Tcy: CHECON = 0b00000000000000000000001100110010; INTCONbits.MVEC = 1;
// Initialize the used tick timer for the TDS3XXX protocol timeouts:
PR2 = 10937;
T2CON = 0b00000000000000001000000001100000;                                 // TMR2_ON, Continue operation in IDLE, Gate accumulation disabled, Prescale 1:64, 16bit mode, Fp clock

// Initialize the TIMER2 interrupts:
IFS0bits.T2IF = 0;                                                          // Clear the TIMER2 Interrupt Flag
IPC2bits.T2IP = 1;                                                          // Set the TIMER2 interrupt priority
IPC2bits.T2IS = 0;                                                          // Set the TIMER2 interrupt priority
IEC0bits.T2IE = 1;                                                          // Enable the TIMER2 interrupts

// Firmware modules initialization:
xSemaphoreTestHandle = xSemaphoreCreateMutex();                             // The RTOS tasks control objects - semaphores, queues...

//vTaskStartScheduler();
INTEnableSystemMultiVectoredInt();
while(1)
{
}
return;
} // End of main() /******************************************************************************* * Function Name: void __ISR(TIMER2VECTOR, IPL4AUTO) TMR2InterruptHandler(void) * Input Parameters: NONE * Returned Value: NONE * Precondition: The global interrupts must be disabled * Affected Global Objects: ALL * Side Effects NONE * Company: SONECO LTD * Author: DIMITAR BELEV – email: DIMITAR.BELEV@SONECO.BG * Creation Date: 2016.06.30 * Short Description: Interrupt service routine for TIMER2 interrupt handling * Remark: NONE * Example: NONE // This function does not have caller *******************************************************************************/ void __ISR(TIMER2VECTOR, IPL1SRS) TMR2InterruptHandler(void) { // Clear the TIMER2 Interrupt flag: IFS0bits.T2IF = 0; } // End of TMR2InterruptHandler() void vAssertCalled( const char * pcFile, unsigned long ulLine ) { volatile unsigned long ul = 0;
( void ) pcFile;
( void ) ulLine;

__asm volatile( "di" );
{
    /* Set ul to a non-zero value using the debugger to step out of this
    function. */
    while( ul == 0 )
    {
        portNOP();
    }
}
__asm volatile( "ei" );
} void vApplicationTickHook(void) { } // End of vApplicationTickHook() void vApplicationIdleHook(void) { } // End of vApplicationTickHook() // End of TEST_System.c ~~~

Interrupt problems, Ver: 9.0.0, Port: PIC32MX

In the attached project file is also the FreeRTOS configuration, the main related settings are: ~~~

define configUSE_PREEMPTION 1

define configUSEPORTOPTIMISEDTASKSELECTION 1

define configUSEIDLEHOOK 1

define configUSETICKHOOK 1

define configTICKRATEHZ ( ( TickType_t ) 1000 )

define configCPUCLOCKHZ ( 100000000UL )

define configPERIPHERALCLOCKHZ ( 100000000UL )

define configMAX_PRIORITIES ( 5UL )

define configMINIMALSTACKSIZE ( 300 )

define configISRSTACKSIZE ( 250 )

define configTOTALHEAPSIZE ( ( size_t ) 9120 )

define configMAXTASKNAME_LEN ( 15 )

define configUSETRACEFACILITY 0

define configUSE16BIT_TICKS 1

define configIDLESHOULDYIELD 1

define configUSE_MUTEXES 1

define configCHECKFORSTACK_OVERFLOW 0

define configQUEUEREGISTRYSIZE 0

define configUSERECURSIVEMUTEXES 1

define configUSEMALLOCFAILED_HOOK 0

define configUSEAPPLICATIONTASK_TAG 0

define configUSECOUNTINGSEMAPHORES 1

define configGENERATERUNTIME_STATS 0

define configSUPPORTDYNAMICALLOCATION 1

~~~

Interrupt problems, Ver: 9.0.0, Port: PIC32MX

In your main() function – the call to xSemaphoreCreateMutex() – or ANY FreeRTOS API function – will deliberately leave interrupts disabled. When the scheduler starts, interrupts will automatically be enabled again. This is done to prevent interrupts attempting to use an RTOS service or perform a context switch before the scheduler has been started.

Interrupt problems, Ver: 9.0.0, Port: PIC32MX

point 3 http://www.freertos.org/FAQHelp.html

Interrupt problems, Ver: 9.0.0, Port: PIC32MX

Hi, Thanks for the information, there are two points: If you check the main(function) – in the test case when the scheduler is not used – There is INTEnableSystemMultiVectoredInt() call /After the API usage/, which enables the interrupts manually even if they are disabled by the xSemaphoreCreateMutex() API call. Second point is, that if i allow the scheduler to start (even with no created tasks the Idle task will be executed all time), the interrupts does not start and the idle task just runs all time without interruption My be you mean, that the xSemaphoreCreateMutex() disables the interrupts in such a way, that only vTaskStartScheduler() can enable them and the standard peripheral library for the interrupts will not work until the scheduler is started? In this case i need to double check what happens in this case and will return feedback? Thank you for your time, if you need anything from our side, just let me know. Kind regards Dimitar

Interrupt problems, Ver: 9.0.0, Port: PIC32MX

If you check the main(function) – in the test case when the scheduler is not used – There is INTEnableSystemMultiVectoredInt() call /After the API usage/, which enables the interrupts manually even if they are disabled by the xSemaphoreCreateMutex() API call.
Hmm. The FreeRTOS code masks priority bits in the CP0STATUS register. I think INTEnableSystemMultiVectoredInt() operates on a different register, maybe using a global enable/disable bit, so calling INTEnableSystemMultiVectoredInt() will not unmask the interrupts that were masked by FreeRTOS. Try calling portENABLE_INTERRUPTS() instead.

Interrupt problems, Ver: 9.0.0, Port: PIC32MX

Hi, I made the test, the interrupts are now working, thanks for the suggestion. The next problem is, that when i start the scheduler, the MCU resets after 1-2sec after the scheduler is started. If i dnot’t start the scheduler, the MCU stays stable. The problem is even when no task is created, no api functions are called prior the vTaskStartScheduler(). As far as my debug tool says is: “Target halted due to Software Breakpoint in user code”. I provide test code: Empty main function, no interrupts enabled, no tasks creatated. In debug mode i place breakpoint inside the idle task tick hook and it breaks many time, but when i run the target, it resets. Due to this project is migration from PIC24E part, if we manage to stabilize the interrupts and general behavior here, we can port our application level without issues, thanks in advance: The FreeRTOS config and configuration bits remai unchanged. void main(void) { // Enable the pre-fetch cache module to achieve 100MHz Tcy: CHECON = 0b00000000000000000000001100110010;
vTaskStartScheduler();
while(1)
{
}
return;
} // End of main()

Interrupt problems, Ver: 9.0.0, Port: PIC32MX

Hi, I made the test, the interrupts are now working, thanks for the suggestion. The next problem is, that when i start the scheduler, the MCU resets after 1-2sec after the scheduler is started. If i dnot’t start the scheduler, the MCU stays stable. The problem is even when no task is created, no api functions are called prior the vTaskStartScheduler(). As far as my debug tool says is: “Target halted due to Software Breakpoint in user code”. I provide test code: Empty main function, no interrupts enabled, no tasks creatated. In debug mode i place breakpoint inside the idle task tick hook and it breaks many time, but when i run the target, it resets. Due to this project is migration from PIC24E part, if we manage to stabilize the interrupts and general behavior here, we can port our application level without issues, thanks in advance: The FreeRTOS config and configuration bits remai unchanged. void main(void) { // Enable the pre-fetch cache module to achieve 100MHz Tcy: CHECON = 0b00000000000000000000001100110010;
vTaskStartScheduler();
while(1)
{
}
return;
} // End of main()

Interrupt problems, Ver: 9.0.0, Port: PIC32MX

There is a PIC32MX demo in the FreeRTOS download that runs stable for many years. Copy the pragmas and init code from that.