Quality RTOS & Embedded Software

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


Loading

PIC32 _CHANGE_NOTICE_VECTOR freezes running processes

Posted by robertloejr on December 1, 2015

I'm working with the PIC32 USB Starter Kit II with a PIC32MX795F512L. The 18 sample software projects provided by FreeRTOS.org in the purchased manual used version 7.5.3.

I made a project that creates a CHANGENOTICEVECTOR interrupt that responds to an SW1 button press. In addition, I created another task that flashes an LED (25ms ON / 50ms OFF).

When I press SW1, I get a message from my task that responds to the interrupt, but I notice the LED flashing is interrupted. When I press and hold SW1, the LED does not flash at all, and I don't get my message until I release SW1.

I tried increasing the priority of my LED flashing task. I also switched from using assembly code for the interrupt to straight C. I looked for other configuration settings for the change notice. Nothing seems to help.

I also have a UART2 interrupt and related task that seems to operate properly without affecting the LED flash rate.

Any help would be appreciated.

Code:

~~~~

include
include
include "FreeRTOS.h"
include "task.h"
include "semphr.h"
include "basic_io.h"
pragma config FPLLODIV = DIV1, FPLLMUL = MUL20, FPLLIDIV = DIV_2
pragma config FWDTEN = OFF, FPBDIV = DIV_2, POSCMOD = XT, FNOSC = PRIPLL, CP = OFF
pragma config FSRSSEL = PRIORITY_7

static void vHandlerTask( void *pvParameters ); static void vHandlerTask2( void *pvParameters );

void vSetupEnvironment( void ); static void vTimerFunction( void *pvParameters );

xSemaphoreHandle xBinarySemaphore, xBinarySemaphore2;

define DESIRED_BAUDRATE (9600)
define SYSCLK (80000000L)
define MAXCOMMANDSIZE 256

char CommandString[MAXCOMMANDSIZE]; int CommandLoc = 0;

int main( void ) { vSetupEnvironment();

vSemaphoreCreateBinary( xBinarySemaphore );
vSemaphoreCreateBinary( xBinarySemaphore2 );

if( xBinarySemaphore != NULL && xBinarySemaphore2 != NULL) {
    xTaskCreate( vHandlerTask, ( signed char * ) "Handler", 240, NULL, 2, NULL );
    xTaskCreate( vHandlerTask2, ( signed char * ) "Handler 2", 240, NULL, 2, NULL );
	xTaskCreate( vTimerFunction, ( signed char * ) "LED Task", 240, NULL, 3, NULL );
    vTaskStartScheduler();
}

for( ;; );
return 0;

}

static void vHandlerTask( void *pvParameters ) { xSemaphoreTake( xBinarySemaphore, 0 );

for( ;; ) {
    xSemaphoreTake( xBinarySemaphore, portMAX_DELAY );
	putsUART2("Command string: ");
	putsUART2(CommandString);
	putsUART2("\n");
	CommandLoc = 0;
}

}

static void vHandlerTask2( void *pvParameters ) { xSemaphoreTake( xBinarySemaphore2, 0 );

for( ;; ) {
    xSemaphoreTake( xBinarySemaphore2, portMAX_DELAY );
	putsUART2("button event\n");
}

}

void _ISR(CHANGENOTICEVECTOR, ipl1) vButtonISRHandler(void) { long sHigherPriorityTaskWoken = pdFALSE;

mCNClearIntFlag();
xSemaphoreGiveFromISR( xBinarySemaphore2, &sHigherPriorityTaskWoken );
portEND_SWITCHING_ISR( sHigherPriorityTaskWoken );

}

void _ISR(UART2_VECTOR, ipl2) IntUart2Handler(void) { unsigned int ch; long sHigherPriorityTaskWoken = pdFALSE;

if(INTGetFlag(INT_SOURCE_UART_RX(UART2))) {
    INTClearFlag(INT_SOURCE_UART_RX(UART2));

	while (DataRdyUART2()) {
		ch = getcUART2();
		putcUART2(ch);
		if (ch == 10 || ch == 13) {
			if (CommandLoc > 0)
				xSemaphoreGiveFromISR( xBinarySemaphore, &sHigherPriorityTaskWoken );
		}
		else if (CommandLoc < MAXCOMMANDSIZE-1) {
			CommandString[CommandLoc++] = ch;
			CommandString[CommandLoc] = 0;
		}
		else {
			xSemaphoreGiveFromISR( xBinarySemaphore, &sHigherPriorityTaskWoken );
		}
	}
}

if ( INTGetFlag(INT_SOURCE_UART_TX(UART2)) ) {
        INTClearFlag(INT_SOURCE_UART_TX(UART2));
}

portEND_SWITCHING_ISR( sHigherPriorityTaskWoken );

}

void vSetupEnvironment( void ) { unsigned int dummy; int pbClk;

SYSTEMConfigPerformance( configCPU_CLOCK_HZ );
mOSCSetPBDIV( OSC_PB_DIV_2 );

mPORTDClearBits(BIT0 | BIT1 | BIT2); mPORTDSetPinsDigitalOut(BIT0 | BIT1 | BIT2 ); PORTSetPinsDigitalIn(IOPORTD, BIT6 | BIT_7);

mCNOpen((CN_ON | CN_FRZ_OFF), (CN15_ENABLE), 0);
dummy = mPORTDRead();
ConfigIntCN((CHANGE_INT_ON | CHANGE_INT_PRI_1));

pbClk=SYSTEMConfig( SYSCLK, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);

OpenUART2( UART_EN, UART_RX_ENABLE | UART_TX_ENABLE, pbClk/16/DESIRED_BAUDRATE-1);

INTEnable(INT_SOURCE_UART_RX(UART2), INT_ENABLED);
INTSetVectorPriority(INT_VECTOR_UART(UART2), INT_PRIORITY_LEVEL_2);
INTSetVectorSubPriority(INT_VECTOR_UART(UART2), INT_SUB_PRIORITY_LEVEL_0);

INTConfigureSystem(INT_SYSTEM_CONFIG_MULT_VECTOR);

INTEnableSystemMultiVectoredInt();

while( BusyUART2());
putsUART2( "Startup\r\n");

}

static void vTimerFunction( void *pvParameters ) { const int DLY1 = 25; const int DLY2 = 50; portTickType xLastWakeTime;

mPORTDClearBits(BIT_2);
xLastWakeTime = xTaskGetTickCount();

for( ;; ) {
	mPORTDSetBits(BIT_2);
	vTaskDelayUntil( &xLastWakeTime, DLY1 / portTICK_RATE_MS );

	mPORTDClearBits(BIT_2);
	vTaskDelayUntil( &xLastWakeTime, DLY2 / portTICK_RATE_MS );
}

}

~~~~


PIC32 _CHANGE_NOTICE_VECTOR freezes running processes

Posted by rtel on December 2, 2015

Is the button interrupt edge or level sensitive? If it is level sensitive then you may be continuously re-entering the interrupt while the button is being held down, preventing other code from running.

Regards.


PIC32 _CHANGE_NOTICE_VECTOR freezes running processes

Posted by robertloejr on December 3, 2015

Thanks for your response. I looked through the PIC32 manual, and unless I missed something, there is no way to set the CNx inputs to a rising or falling edge. The INT0 - INT4 external inputs do allow an edge setting. I will try INT0 and see if it solves the problem.


PIC32 _CHANGE_NOTICE_VECTOR freezes running processes

Posted by tlafleur on December 3, 2015

Not true, I do not have the data sheet here, but you can set edge or state on each pin for interrupt. Re read data sheet.

Attachments

alternate (1388 bytes)

PIC32 _CHANGE_NOTICE_VECTOR freezes running processes

Posted by tlafleur on December 3, 2015

"The CNENx registers contain the CN interrupt enable control bits for each of the input pins. Setting any of these bits enables a CN interrupt for the corresponding pins."

This will give you an interrupt when a pin changes state, you must in the interrupt service routine, clear the interrupt, check if it's a state you are looking for, set a flag or mutex, exit the routine... It will only interrupt on a pin state change, a 1 to a 0, or a 0 to a 1

Attachments

alternate (2047 bytes)

PIC32 _CHANGE_NOTICE_VECTOR freezes running processes

Posted by tlafleur on December 3, 2015

It interrupts on BOTH edge, so a small state machine can set a flag on edge you want.

Attachments

alternate (1345 bytes)

PIC32 _CHANGE_NOTICE_VECTOR freezes running processes

Posted by robertloejr on December 3, 2015

It doesn't seem to interrupt on both edges. I get an interrupt only when the button is released. I don't have a problem getting the change notice interrupt. The problem is: when the button is held down the other running processes halt.


PIC32 _CHANGE_NOTICE_VECTOR freezes running processes

Posted by robertloejr on December 3, 2015

INT0 / RD0 was tied to an LED on the board so I used INT1. There were no problems with the LED flashing when multiple interrupts were generated on INT1.

~~~~ void _ISR(EXTERNAL1VECTOR, ipl1) vExternalInterrupt1(void) { long sHigherPriorityTaskWoken = pdFALSE; mINT1ClearIntFlag();

xSemaphoreGiveFromISR( xBinarySemaphore2, &sHigherPriorityTaskWoken );
portEND_SWITCHING_ISR( sHigherPriorityTaskWoken );

}

//inside SetupEnvironment:

ConfigINT1(EXT_INT_PRI_1 | FALLING_EDGE_INT | EXT_INT_ENABLE);

~~~~


PIC32 _CHANGE_NOTICE_VECTOR freezes running processes

Posted by rtel on December 4, 2015

Run the code in the debugger, press and hold the button so the symptom shows itself, then while holding down the button pause the debugger....which code is running?


PIC32 _CHANGE_NOTICE_VECTOR freezes running processes

Posted by robertloejr on December 4, 2015

It turns out I was missing a call to mPORTDRead() in the interrupt handler. That is why I did not get an interrupt on both edges as stated by lafleur. With the following code I can press the button without interferring with the LED flashing.

~~~~ void _ISR(CHANGENOTICEVECTOR, ipl1) vButtonISRHandler(void) { long sHigherPriorityTaskWoken = pdFALSE; mPORTDRead(); mCNClearIntFlag();

xSemaphoreGiveFromISR( xBinarySemaphore2, &sHigherPriorityTaskWoken );
portEND_SWITCHING_ISR( sHigherPriorityTaskWoken );

} ~~~~


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


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

Latest News

NXP tweet showing LPC5500 (ARMv8-M Cortex-M33) running FreeRTOS.

Meet Richard Barry and learn about running FreeRTOS on RISC-V at FOSDEM 2019

Version 10.1.1 of the FreeRTOS kernel is available for immediate download. MIT licensed.

View a recording of the "OTA Update Security and Reliability" webinar, presented by TI and AWS.


Careers

FreeRTOS and other embedded software careers at AWS.



FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Espressif ESP32

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Renesas

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

Xilinx Microblaze and Zynq partner