Quality RTOS & Embedded Software

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




Loading

Using Semaphores with HW interrupts and tasks

Posted by rog57 on January 4, 2013
Hi,

After creating tasks and launching the scheduler, I am unable to get a normal (regular) function to execute after the timer-counter interrupt is complete. The function is to do interrupt post-processing on the data.
Right now, I'm using a static global var which is set on completion, and I have a task that checks every 50ms and if the flag is set, it will call the function. It doesn't execute though, which seems is likely in this mode.
After reading the FreeRTOS guide, I'm thinking a semaphore is the right thing to use. However, I have been unable to find an example of using a semaphore with a HW interrupt in the task and scheduler based mode.

Can someone point me in the right direction?
Also, is it possible to run a regular function in the task environment as I am trying without it "timing" out in a task mode?

Thank you in advance.

RE: Using Semaphores with HW interrupts and tasks

Posted by Richard on January 4, 2013
“I am unable to get a normal (regular) function to execute after the timer-counter interrupt is complete”


Is this a timer-counter interrupt you have configured yourself? Or the tick interrupt.

By regular function, do you mean just a C function that you want to be triggered by an interrupt?

“The function is to do interrupt post-processing on the data. ”


Ok, so it should execute after each interrupt.

“Right now, I'm using a static global var which is set on completion,”


Do you mean on completion of the interrupt?

“and I have a task that checks every 50ms and if the flag is set,”


So you have something like this?

for( ;; )
{
if( flag is set )
{
Do something;
clear flag;
}
else
{
vTaskDelay( 50 / portTICK_RATE_MS )
}
}


“It doesn't execute though, which seems is likely in this mode. ”


What doesn't execute? The interrupt, or the "Do something" function in the above example?

Does the flag get set?
Does the interrupt execute?

“After reading the FreeRTOS guide, I'm thinking a semaphore is the right thing to use.”


Yes I would agree. That would be much more efficient. It does't explain why the way you are doing it now is not working though.

Is the guide you have the FreeRTOS tutorial "Using the FreeRTOS Real Time Kernel"? If so, which edition do you have, I can highlight the bit that shows how to use the semaphore for this.

Which FreeRTOS port are you using?

“Also, is it possible to run a regular function in the task environment as I am trying without it "timing" out in a task mode?”


I'm not sure I understand your question there. Tasks are just C functions, and they call lots of other regular C functions (the FreeRTOS API functions themselves are regular functions).

Regards.

RE: Using Semaphores with HW interrupts and tasks

Posted by rog57 on January 4, 2013
My responses start with ">"

"I am unable to get a normal (regular) function to execute after the timer-counter interrupt is complete"
Is this a timer-counter interrupt you have configured yourself?
>Yes. I have configured timer_counter 0 to do rising edge captures

Or the tick interrupt. By regular function, do you mean just a C function that you want to be triggered by an interrupt?
>Correct. A function I need to process data immediately following the interrupt's completion

So you have something like this?
>Yes, the code is pretty much as you as you have pasted. Flag is static global.

What doesn't execute? The interrupt, or the "Do something" function in the above example?
>The function will not run. I'm not sure why it's exiting, but it does so within a few milliseconds of entering the function. However, if I wrap the function with this:
portENTER_CRITICAL();
{
myFunction();
}

it runs to completion. This is what I meant by the statement. So I'm not 100% sure what is happening.

Does the flag get set? Does the interrupt execute?
>Yes to both...as above

I am using the LPC17xx port (Cortex-M3) so the documents I have a for this device (using an LPC1768)

I'm not sure I understand your question there.
>What I meant by timing out, is what is happening without the "portENTER_CRITICAL" wrapped around it. It just appears to kind of time out and exit early. I'm not 100% sure that even though I execute my task check every 50ms, does that mean a function called within that task will execute to completion?

If you could point out the page from the manual on how to apply the semaphore that would be great. I see a queue would work too but not required here. I will use it on the ADC however.

Thanks so much for your detailed response.



RE: Using Semaphores with HW interrupts and tasks

Posted by Richard on January 5, 2013
There are two things that need sorting out then:

1) Working out why the "do something" does not run to its end, and
2) Changing the method that triggers the "so something" function from the simple delay loop to using a semaphore from the interrupt.

Lets concentrate on (1) first because changing the way the function is triggered is not going to make any difference to the behaviour when the function is called.

Any function called from a task will run to completion. It might be that the task running the function is swapped in and out while it is running, but when a task is swapped back in it just continues running from the point at which it was swapped out so all the code [within the task itself] is run sequentially.

Can you give more information about the function itself.

Does it have more than one return point?
Can you step through the function in the debugger to see what it is doing?
Does it make any use of FreeRTOS API functions?
Why would placing it in a critical section make any difference?

Regards.

RE: Using Semaphores with HW interrupts and tasks

Posted by rog57 on January 8, 2013
Richard,
Responses to your questions here: ">"

Does it have more than one return point?
>No - just one at the end, no other exit.

Can you step through the function in the debugger to see what it is doing?
> Yes. The debugger just seems to "stop" when it hits any code inside a loop (see example below)

Does it make any use of FreeRTOS API functions?
>Not in the function that's called. See below

Why would placing it in a critical section make any difference?
> I am completely at a loss to explain this.

It's important to note that this issue has nothing to do with using sprintf or the CMSIS _DBG_ call. If I comment out all sprintf and DBG calls in my code it will still not run. The only thing that will make it run ( the real function or the "test" function below, is wrapping the call with portENTER_CRITICAL()

I have created a simple function to call from the task handler that might exemplify what is going on. There is a simple 2D array and function. If I run it as is, (#if 1) it will print out this much of the string:

myArray[0][0]

And that's it. If I set the preprocessor directive to #if 0, and un-comment the line that starts with "sprintf" above, it prints the line no problem. So it seems like it can print or process something simple, but as soon as a test condition or loop is incurred, it won't run.

int myArray[6][3] = { {12,23,33}, {21,44,32},{18,15,76},{89,65,11},{41,19,98},{75,47,53} };

int dataReceiveProcess2(void)
{
char msgBuf[150];

//sprintf(msgBuf, "myArray[%i][%i]= %i", 2,0, myArray[2][0]); _DBG_(msgBuf);

#if 1
for(int i = 0; i < 7; i++)
{
sprintf(msgBuf, "myArray[%i][%i]= %i", i,0, myArray[0]);
_DBG_(msgBuf);
}
#endif

return 0;
}

Here's the call from main:
static void prvReadCOMBufferTaskFunction( void *pvParameters )
{
portTickType xLastCheckTime;
// Initialize xLast***Times prior to the first call to vTaskDelayUntil()
xLastCheckTime = xTaskGetTickCount();

for(;;)
{
vTaskDelayUntil( &xLastCheckTime, check_COM_SIGNAL_RATE );
// Check the flag to see if it's set
if(TRUE == completeFlag)
{
//a small interval for interrupt to complete
vTaskDelay( 50 / portTICK_RATE_MS );
//portENTER_CRITICAL();
//{
dataReceiveProcess2();
completeFlag = FALSE;
//}
}
}
}



RE: Using Semaphores with HW interrupts and tasks

Posted by rog57 on January 8, 2013
Richard,

Sorry, the rest of the message is below - sent before completion.

Any help or thoughts on what might be happening would be appreciated. I'm using an LPC1768 controller, compiling on IAR EWARM 6.5, with a JTAG debugger.

Regards

RE: Using Semaphores with HW interrupts and tasks

Posted by Richard on January 9, 2013
That is very strange. I presume you have stack overflow checking on? Does it make a difference if you make the 150 byte buffer static, rather than having it on the stack?

If that does not make a different is it possible for you to send me the project? If so, please cut it down to its bare minimum, so it just has the code that demonstrates the problem and nothing else. Package it up including the IAR project files, check what you package up builds without any modification, and send it to the address from the "Contact" page on the FreeRTOS.org website.

Regards.

RE: Using Semaphores with HW interrupts and tasks

Posted by rog57 on January 9, 2013
I will try making it static to see if that changes anything. And I will also try removing functions and code to see if I can get to a point where it will run. Barring that, I will send the project files to you.

Appreciate your help very much.

Kind regards

RE: Using Semaphores with HW interrupts and tasks

Posted by rog57 on January 10, 2013

I thought it might be reasonable to try and discover what's going on before using up more of your time.
After reading further in the manual regarding stack size, I kept increasing the "configMINIMAL_STACK_SIZE" until the function could run without the PORT_CRITICAL wrapped around the call. That number ended up being 200 (4 byte) words.

Then, I applied the "uxTaskGetStackHighWaterMark" function just before the function was called. I also passed in the task handle to the called C function and ran the call there. before it's called, the number was 168. In the function, it is 43. So instead of leaving the "configMINIMAL_STACK_SIZE" at 200, I switched it back to the default of 80, and instead did a local define of 200 bytes for this function that's apparently a "stack hog. "

My questions are now:
For this device (LPC1768), with 64K SRAM, is using this amount of stack space for a single function excessive?
What are the implications of this in terms of (net) available stack size to the running program?
Am I further ahead to create, then delete, a task for this function each time it's required?
What elements in the called function causes the requirement for the stack size to increase?

Thanks a bunch for taking the time to answer my queries.

RE: Using Semaphores with HW interrupts and tasks

Posted by MEdwards on January 10, 2013
Any variables you allocate inside the function will be placed on the stack, unless they are declared static. Declaring them static has the disadvantage that it makes the function non reentrant.

Does you function have something like a large buffer declared as an array variable in it?

RE: Using Semaphores with HW interrupts and tasks

Posted by rog57 on January 11, 2013
By declaring the debug print buffer as static, outside the scope of the function, I have been able to get the stack size for the function to 160 words. This is a 20% margin better, but still double the MIN size. This function will only ever be called by one task, and as there are no static variables, it is fully re-entrant.

I'm still curious about this:

For this device (LPC1768), with 64K SRAM, is using this amount of stack space for a single function excessive?
What are the implications of this in terms of (net) available stack size to the running program?
Am I further ahead to create, then delete, a task for this function each time it's required?
What elements in the called function causes the requirement for the stack size to increase? (in the case of the function in question, it only declares 2 variables; 1 counter of unsigned int and an array of 50 unsigned 32 bit ints, so I cannot imagine why it wants to consume more/higher stack space)

Kind regards.


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




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

Latest News

FreeRTOS kernel V10 is available for immediate download. Now MIT licensed.


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

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