|
NOTE:This is a read only archive of threads posted to the FreeRTOS support forum. Use these archive pages to search previous posts. New forum support threads can be started at the FreeRTOS forums.
FreeRTOS Support Archive
The FreeRTOS support forum can be used for active support both from Amazon Web Services and the community. In return for using our software for free, we request you play fair and do your bit to help others! Sign up for an account and receive notifications of new support topics then help where you can.
This is a read only archive of threads posted to the FreeRTOS support forum. Use these archive pages to search previous posts. New forum support threads can be started at the FreeRTOS forums.
[FreeRTOS Home]
[Live FreeRTOS Forum]
[FAQ]
[Archive Top]
[November 2012 Threads]
LPC2148 FIQ Handler problemPosted by capablazab on November 8, 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
LPC2148 FIQ Handler problemPosted by richardbarry on November 8, 2012 A couple of comments:
1) Do you have a stack setup for FIQ mode? Most of the demos provided don’t. The stacks are normally configured in assembly code from the C start up code, before main() is called.
2) If you are using FIQ then you will have to ensure your portDISABLE_INTERRUPTS() and portENABLE_INTERRUPTS() functions disable/enable both IRQ and FIQ.
3) You are likely to get problems using FreeRTOS API functions from an FIQ handler because FIQ can pre-empt IRQ, and the code does not take that into account (none of the demos use FIQ). You might be ok if you disable the FIQ interrupt before using any FreeRTOS functions from an IRQ handler, but then that might defeat the object of using FIQ in the first place.
Regards.
LPC2148 FIQ Handler problemPosted by capablazab on November 9, 2012 Richard,
Thank you for your fast response.
As you suggested I made a few changes:
I increased the FIQ stack size to 400 bytes in startup.s:
/* Stack Sizes */
.set UND_STACK_SIZE, 0x00000004
.set ABT_STACK_SIZE, 0x00000004
.set FIQ_STACK_SIZE, 0x00000800
.set IRQ_STACK_SIZE, 0X00000400
.set SVC_STACK_SIZE, 0x00000400
in main (just to be sure), i added:
int main( void )
{
** portENABLE_INTERRUPTS();**
…
Also, in portmacro.h the codes seems to be correctly handling the activation/deactivation of FIQ and IRQ:
#define portDISABLE_INTERRUPTS()
__asm volatile (
“STMDB SP!, {R0} nt” /* Push R0. */
“MRS R0, CPSR nt” /* Get CPSR. */
**”ORR R0, R0, #0xC0 nt” /* Disable IRQ, FIQ. */ **
“MSR CPSR, R0 nt” /* Write back modified value. */
“LDMIA SP!, {R0} ” ) /* Pop R0. */
#define portENABLE_INTERRUPTS()
__asm volatile (
“STMDB SP!, {R0} nt” /* Push R0. */
“MRS R0, CPSR nt” /* Get CPSR. */
**”BIC R0, R0, #0xC0 nt” /* Enable IRQ, FIQ. */ **
“MSR CPSR, R0 nt” /* Write back modified value. */
“LDMIA SP!, {R0}
Also I added to the ISRHandler:
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);
portDISABLE_INTERRUPTS();
IO1SET |= LED;
// When finishing the routine, this task will return to blocked state
// waiting for another semaphore which will be given again by the FIQ.
//xSemaphoreGive(xBinarySemaphore);
** portENABLE_INTERRUPTS();**
}
}
As you said on number 3:
_You are likely to get problems using FreeRTOS API functions from an FIQ handler because FIQ can pre-empt IRQ, and the code does not take that into account (none of the demos use FIQ). _
If I understand, you mean, the FIQ can preempt the IRQ? But I only have a FIQ. there are not other interrupts.
You might be ok if you disable the FIQ interrupt before using any FreeRTOS functions from an IRQ handler, but then that might defeat the object of using FIQ in the first place.
I think this too is applicable when having FIQ and IRQ interrupts? Or am I wrong?
I can add now, that, with this code if I remove the call to xSemaphoreGiveFromISR(xBinarySemaphore, &xHigherPriorityTaskWoken); in the FIQ routine, the LED returns to blink, so that seems to be the trouble.
I’m using the FIQ because its the fastest one only, but if you tell me that the IRQ will work, then I could give it a try. (Or any other workaround :D)
Thank you for your support!!
Carlos
LPC2148 FIQ Handler problemPosted by capablazab on November 9, 2012 Sorry,
This doesnt work either.
void vISRHandlerTask(void)
{
IO1DIR |= (LED); // Initializes P1.16 as output.
for(;;)
{
portDISABLE_INTERRUPTS();
// This task will be blocked until the FIQ gives it the semaphore.
xSemaphoreTake(xBinarySemaphore, portMAX_DELAY);
IO1SET |= LED;
// When finishing the routine, this task will return to blocked state
// waiting for another semaphore which will be given again by the FIQ.
//xSemaphoreGive(xBinarySemaphore);
portENABLE_INTERRUPTS();
}
}
Carlos
LPC2148 FIQ Handler problemPosted by *anonymous on November 16, 2012 No one?
Any help please?
I just need to interrupt the MCU with an external interrupt, and then do some processing with a task, periodically…
LPC2148 FIQ Handler problemPosted by travfrog on November 16, 2012 Hi Carlos,
I don’t know anything about this specific MCU so I did a quick read of the user manual. From your code above, I do not see where you are configuring the EXT interrupt mode and polarity. These registers apparently default to 0 which means level sensitive active low.
I suspect when you change the state of the external pin to low, the interrupt fires as expected. You clear the interrupt flag but at this point the input is still low so as soon as the interrupt exits, it will fire again. You end up doing nothing more than servicing the interrupt. I’ve done this sort of thing.
You could make the input edge triggered (falling or rising).
Hope this helps
travfrog
LPC2148 FIQ Handler problemPosted by *anonymous on November 17, 2012 Dear all,
The problem is solved!
travfrog thank you too for your help: The EXT is set to level sensitive by default as you said, so I was triggering the interrupt by moving a wire from VCC/GND. Now I’ve set it to edge sensitive so I can trigger it with a PWM.
Here’s what I dit to make the **FIQ[/b work (thanks to mikaeleiman from lpc2000 yahoo group)
main.c:
void FIQ_Handler (void) __attribute__ ((interrupt(”FIQ”))) __attribute((naked));
void FIQ_Handler (void)
{
portSAVE_CONTEXT();
actualFIQHandler();
EXTINT = 0x2;
portRESTORE_CONTEXT();
}
actualFIQHandler.c
void actualFIQHandler(void) __attribute__((noinline));
void actualFIQHandler(void)
{
static signed portBASE_TYPE xHigherPriorityTaskWoken;
xSemaphoreGiveFromISR(xBinarySemaphore, &xHigherPriorityTaskWoken);
if ( xHigherPriorityTaskWoken )
{
// switch context to newly awoken task
portYIELD_FROM_ISR();
}
}
and finally ISRHandler.c
void vISRHandlerTask(void)
{
IO1DIR |= (LED); // Initializes P1.16 as output.
int flag=0;
for(;;)
{
portDISABLE_INTERRUPTS();
// This task will be blocked until the FIQ gives it the semaphore.
xSemaphoreTake(xBinarySemaphore, portMAX_DELAY);
if(flag==1)
{
IO1SET |= LED;
flag=0;
}
else
{
IO1CLR |= LED;
flag=1;
}
// When finishing the routine, this task will return to blocked state
// waiting for another semaphore which will be given again by the FIQ.
portENABLE_INTERRUPTS();
}
}
I defined the interrupt as edge sensitive, and its working okay now.
Thank you for your support!
Carlos**
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.
|
|