Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Real time embedded FreeRTOS mailing list 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT Training




Loading

Synchronizing task w/interrupt and semaphore

Posted by Dan Lewis on August 8, 2007
I've run into a problem that I can't resolve: As long as I don't call any FreeRTOS API's from within an interrupt routine, everything worksfine. But when I try to use xSemaphoreGiveFromISR/xSemaphoreTake to synchronize a task using an interrupt, I begin to have problems.

FYI: I'm using the Luminary Micro LM3S811 evaluation board, their driver library version 1427, FreeRTOS V4.3.1, and the free evaluation version (V4.42A) of IAR's Embedded Workbench.

I've simplified the application down to the minimal code that demonstrates the problem: The CPU is running at the default 6Mhz rate. A hardware timer is configured to interrupt 100 times per second. THe ISR merely clears the interrupt and calls xSemaphoreGiveFromISR. The task pends on the semaphore; when released, it increments an integer and sends it to the onboard display. Thus the application should display a continuously incrementing number on the onboard display. It does so for a while (up to 487) and then hangs. Where it hangs changes if I change the stack size or the interrupt rate, but it always hangs.

The code is attached. Any help would be most appreciated!

Dan

#include "hw_ints.h"
#include "hw_memmap.h"
#include "hw_types.h"
#include "timer.h"
#include "interrupt.h"
#include "sysctl.h"
#include "osram96x16x1.h"
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"

xSemaphoreHandle TimerSemaphore = NULL ;

void Timer0IntHandler(void)
{
TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT) ;
xSemaphoreGiveFromISR(TimerSemaphore, pdFALSE) ;
}

char *Convert(unsigned long int n, char *bfr)
{
if (n >= 10) bfr = Convert(n / 10, bfr) ;
*bfr++ = (n % 10) + '0' ;
*bfr = '\0' ;
return bfr ;
}

void TimerTask(void *pvParameters)
{
unsigned long int count = 0 ;
char bfr[30] ;

for (;;)
{
xSemaphoreTake(TimerSemaphore, portMAX_DELAY) ;
Convert(count++, bfr) ;
OSRAM96x16x1StringDraw(bfr, 0, 0) ;
}
}

#define PRIORITY ((tskIDLE_PRIORITY) + 1)

int main(void)
{
OSRAM96x16x1Init(true) ;

vSemaphoreCreateBinary(TimerSemaphore) ;

SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0) ;
// Configure timer 0 to generate periodic interrupts
TimerConfigure(TIMER0_BASE, TIMER_CFG_32_BIT_PER) ;
TimerLoadSet(TIMER0_BASE, TIMER_A, 60000) ; // interrupt 100 times/second
TimerEnable(TIMER0_BASE, TIMER_A);
TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT) ;
IntEnable(INT_TIMER0A);

xTaskCreate(TimerTask, "TimerTask", 128, NULL, PRIORITY, NULL) ;
vTaskStartScheduler();

// Should never arrive here ...
OSRAM96x16x1StringDraw("Failed!", 0, 1) ;
for (;;) ;
}


RE: Synchronizing task w/interrupt and semaphore

Posted by sotd on August 8, 2007
I cannot see anything wrong but am not familiar with the port. A couple of questions.

Could it simply be a stack problem. Try making bfr static to see if that helps. Also, some demos use FreeRTOS calls in the LCD initialization routines. This means you have to call them from a task after the scheduler has been started. COuld this be a problem?

You say everything works ok, other than this. Odd. The docs say you don't need any special syntax for ISRs with is unlike most port, so it should be easy.

Do any of the Cortex demos demonstrate this being done, where you could copy code from. I suspect the USRT demo will show a queue being used, which is basically the same thing.

RE: Synchronizing task w/interrupt and semaphore

Posted by Dan Lewis on August 8, 2007
Thanks for the suggestions. I made bfr static, but it made no difference at all.

The LCD initialization code is from Luminary Micro's driver lib, which has no FreeRTOS reference within it. But just for kicks, I then moved the call to vSemaphoreCreateBinary into the task, and moved the call to IntEnable just after it so that the interrupt routine would not access the semaphore before it had been created. However, other than changing the point where the application hangs (from a count of 487 to 490), there was no significant change.

The demo that comes with the LM3S811 port of FreeRTOS uses a similar interrupt routine (vGPIO_ISR) for a push button on the board and uses it to synchronize a task (vButtonHandlerTask). The only difference I can think of is that most users are not likely to push that button 500 times. :-)

Dan

RE: Synchronizing task w/interrupt and semaph

Posted by fkln on August 8, 2007
Hi,

I am also working with FreeRTOS and the chips from Luminary Micro.

Which compiler do you use ?

If you use gcc, I recommend to try the IAR compiler.
I have got a similar problem with nested interrupts, after I switch to IAR the problem was solved.

Klaus

RE: Synchronizing task w/interrupt and semaphore

Posted by Dan Lewis on August 8, 2007
Klaus,

As mentioned in my original post, I too am using IAR. And I just solved my problem: I upgraded to version 4.4.0 of FreeRTOS and the problem went away! :-)

Dan

RE: Synchronizing task w/interrupt and semaphore

Posted by Dan Lewis on August 9, 2007
Well, I spoke too soon. :-(

The simplified test case given in my original post works fine now with version 4.4.0 of FreeRTOS. However, the larger application from which it was extracted still runs for a while and then suddenly hangs. It contains a task that uses vTaskDelayUntil; if I replace it with the older vTaskDelay, then everything works great. Apparently there are still problems in vTaskDelayUntil.

Dan

RE: Synchronizing task w/interrupt and semaphore

Posted by Richard on August 9, 2007
While I can offer no guarantees, I would be very suprised if there was a problem with vTaskDelayUntil() considering the amount of testing it has undergone. Did you read the conclusion to this thread? http://sourceforge.net/forum/forum.php?thread_id=1764930&forum_id=382005

It was been raised a couple of times that there is a problem with the function, but in all cases it turns out that it does exactly what you tell it to do.

I should look somewhere else. I'm away from the office for a while at the moment, but if you zip up the smallest application you can write that exhibits the problem and send it to me then I can take a look when I get back. Use the r (dot) barry[ @ ] freertos.org address, not the sourceforge address, otherwise the attachment will get removed.

I won't be able to try it until probably middle of next week.

Regards.

RE: Synchronizing task w/interrupt and semaphore

Posted by Dan Lewis on August 10, 2007
Richard,

I think I may have found my problem. I made a naive assumption that Luminary Micro's driver library was reentrant. I have two tasks which each call their TimerMatchSet API. After protecting these calls with a semaphore, my application seems to run ok. So for now please assume that it was "user error". I'll continue to test the application; if I find otherwise, I'll let you know.

Thanks for your help!

Dan

RE: Synchronizing task w/interrupt and semaph

Posted by JC on August 10, 2007
Dude... A *real* programmer would have blamed the hardware, then claimed to have fixed it in software!

--jc


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




Copyright (C) 2004-2010 Richard Barry. Copyright (C) 2010-2016 Real Time Engineers Ltd.
Any and all data, files, source code, html content and documentation included in the FreeRTOSTM distribution or available on this site are the exclusive property of Real Time Engineers Ltd.. See the files license.txt (included in the distribution) and this copyright notice for more information. FreeRTOSTM and FreeRTOS.orgTM are trade marks of Real Time Engineers Ltd.

Latest News:

FreeRTOS V9.0.0 is now available for download.


Free TCP/IP and file system demos for the RTOS


Sponsored Links

⇓ Now With No Code Size Limit! ⇓
⇑ Free Download Without Registering ⇑


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Renesas Electronics Gold Alliance RTOS Partner.jpg

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Atmel RTOS partner supporting ARM Cortex-M3 and AVR32 microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Xilinx Microblaze and Zynq partner

Silicon Labs low power RTOS partner

Altera RTOS partner for Nios II and Cortex-A9 SoC

Freescale Alliance RTOS Member supporting ARM and ColdFire microcontrollers

Infineon ARM Cortex-M microcontrollers

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

Cypress RTOS partner supporting ARM Cortex-M3

Fujitsu RTOS partner supporting ARM Cortex-M3 and FM3

Microsemi (previously Actel) RTOS partner supporting ARM Cortex-M3

Atollic Partner

IAR Partner

Keil ARM Partner

Embedded Artists