capablazab wrote on Thursday, November 08, 2012:
Hello,
I’m using FreeRTOS with an LPC2148. I ported the code from the LPC 2106 example. (It works fine)
The FIQ interrupt is working fine too, but I need it to launch a function from the ISR, to toggle a pin of the MCU.
I have 2 tasks: one that blinks an GREEN LED (just to be sure the system is running), and an ISRHandler which is synchronized with a semaphore. In this case, the ISRHandler turns ON an RED LED. The code I’m using is very similar to the one proposed in the documentation.
I’m sure the FIQ interrupt is working fine: With the GREEN LED blinking, if I dont use the ISRHandler, I can turn ON the RED LED in the interrupt when a pin is LOW, and then turn it OFF when the pin returns to HIGH, and the GREEN LED returns to blink. So, the interrupt ends and the blinker task returns to run.
BUT, If I enable the ISRHandler task (with xTaskCreate()), the ISRHandler preempts the blinker task after the FIQ interrupt, and apparently doesnt block when the pin is HIGH again, so the GREEN LED doenst blink anymore.
I hope my explanation isn’t too confusing.
This is the code I’m using: (Ill do a brief summary)
main.h
xSemaphoreHandle xBinarySemaphore;
main.c
int main( void )
{
// Setup the hardware for use with the Olimex demo board.
prvSetupHardware();
// Create Binary Semaphore
vSemaphoreCreateBinary(xBinarySemaphore);
// SETUP FIQ
PINSEL0 = 0x20000000; // sets p0.14 as EINT1
VICIntSelect |= 0x00008000;
VICIntEnable = 0x00008000;
xTaskCreate( vISRHandlerTask, ( signed char * ) “ISRHandler”, 1000, NULL, 3, NULL );
xTaskCreate( vBlinkTask, (signed char * ) “blinker”, configMINIMAL_STACK_SIZE, NULL, 1, NULL);
vTaskStartScheduler();
// Should never reach here!
return 0;
}
void FIQ_Handler (void)
{
// Remove FIQ flag
EXTINT = 0x2;
**static portBASE_TYPE xHigherPriorityTaskWoken;
xHigherPriorityTaskWoken = pdFALSE;
xSemaphoreGiveFromISR(xBinarySemaphore, &xHigherPriorityTaskWoken);
if(xHigherPriorityTaskWoken == pdTRUE)
portYIELD_FROM_ISR();**
}
ISRHandler.c
#include “main.h”
#define LED (1 << 20)
void vISRHandlerTask(void)
{
IO1DIR |= (LED); // Initializes P1.16 as output.
for(;
{
// This task will be blocked until the FIQ gives it the semaphore.
** xSemaphoreTake(xBinarySemaphore, portMAX_DELAY);**
IO1SET |= LED; // turns ON pin 1.16
// When finishing the routine, this task will return to blocked state
// waiting for another semaphore which will be given again by the FIQ.
/// I tried with giving the semaphore, but the MCU starts with the RED LED ON and doesnt do anything.
////xSemaphoreGive(xBinarySemaphore);
}
}
Blinker.c
#define LED (1 << 19)
void vBlinkTask(void)
{
pwmInit();
pwmFrequency(500);
pwmDutyCycle(90);
IO1DIR |= LED;
for(;
{
IO1CLR |= LED; // just blinks an LED every 100 ticks
vTaskDelay(50);
IO1SET |= LED;
vTaskDelay(50);
}
}
I’d greatly appreciate any help.
Regards,
Carlos