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
to 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.
The archive is updated every week, so will not always contain the very latest posts.
Use these archive pages to search previous posts. Use the Live FreeRTOS Forum
link to reply to a post, or start a new support thread.

Need help with "button" interrupt task (xSemaphoreGiveFromISR)

I thought it's better to create a new topic for this case. I'm a FreeRTOS newbie, currently studying interrupt generation in FreeRTOS. So far I've managed to write and successfully run my basic non-RTOS example of using the USER button on my STM32 ARM Cortex board as an external interrupt using the libraries to configure it (EXTI line and NVIC). Now I want to make a next step and move to FreeRTOS environment, obviously using a semaphore mechanism (xSemaphoreGiveFromISR).

My goal is to create a simple FreeRTOS project with 3 tasks - 2 of them for flashing a single LED (one for blue and another for a green one) at different frequency while the 3rd task should be waken by the ISR (that processes GPIO interrupts originating from the push button) and should do some simple job, like turning both LEDs off when the button is pressed. So far I've managed to create and run the first two tasks (flashing both LEDS at different speed, using no semaphores) so now I need to add the third - "user button" task and obviously the binary semaphore for signal the task from interrupt and also to synchronise the task with interrupt. I'm just not sure how to do it correctly. I'm also not sure about the priority of the button interrupt task - should it be higher than the priority of my first two tasks or not?

Now, I don't expect you to write any code for me, but if someone can just point me in the right direction how to start to add this button interrupt task I would be very grateful. Could be just in few sentences, kind of step-by-step plan. Something like: first you need to add button initialization (GPIO, RCC), you also need to create a binary semaphore to synch. the task with interrupt, then create a button task, check your configMAXLIBRARYSYSCALLINTERRUPTPRIORITY settings etc. Hope I'm not asking too much.

Need help with "button" interrupt task (xSemaphoreGiveFromISR)

UPDATE: Before using a button for generating GPIO interrupt I decided to try another, easier way - using software generated interrupts. For that purpose I modified "EXAMPLE 12" (Using a Binary Semaphore to Synchronize a Task with an Interrupt) code from R.Barry's RTOS Practical Guide book. In short, it's a simple example with 2 tasks (vPeriodTask and vHandlerTask) and 1 interrupt handler. vPeriodTask is supposed to generate (SW) interrupt every 1500 ms while vHandlerTask is used for synchronizing the task with SW interrupt using binary semaphore and has higher priority. Interrupt handler waits for interrupt, then "gives" the semaphore to unlock the high priority task (vHandlerTask) and switch to it.

However, my code doesn't work as I expected. Judging by my testing with breakpoint, vInterruptHandler obviously never gets called so there is no switching to high priority task. What happens is the following:

1.) tasks and semaphore get created and schedular gets running
2.) vHandlerTask "takes" semaphore and prints "Handler task ->> Processing event" and turns on the LED. This is ok.
3.) Next, schedular switches to vPeriodicTask that waits for delay and then prints "About to generate SW interrupt...". Then it generates SW interrupt and at that point the program freezes. Generated SW interrupt should wake up interrupt handler (that should then switch to vHandlerTask once again) but it does not.

Need help with "button" interrupt task (xSemaphoreGiveFromISR)

If the interrupt is never being entered then I would agree - it does not sound like FreeRTOS is causing the problem. I would recommend getting the interrupt to work with a very simply loop in main(), before creating any tasks or starting the scheduler.

I presume the interrupt requires some hardware configuration in order for it to work configuration - and presumably that is done in the EXTI0Config(); function. Have you looked in that function to see what it does? I imagine it will as a minimum enable the interrupt. Is that the same function you were using before? Next the EXTIGenerateSWInterrupt() function - have a look in that to see what it is doing. I suspect it will just be writing to one of the processors Set Pending registers.

When you say the code freezes, what is it actually doing? If you stop on the debugger where are you? If you are in a default interrupt handler, rather than the EXTI0 handler, then maybe it is the wrong interrupt that is being raised in the 'generate' function, or that the handler for the interrupt is in the incorrect vector (did you install the handler in the vector table?).

Obviously this interrupt handler doesn't work by RTOS mechanism anymore but rather as simple polling action. As the result, I got blinking LEDS (1 at time) every 1500 ms, just like it's supposed to be according to my new interrupt handler. On my console window I could read the following events:

Therefore I can conclude that SW generated interrupt works just fine. As for the two tasks, the schedular starts with Handler task (higher priority) which takes semaphore for the first time and then switches to the Period task which then keeps running and never switches back to Handler task (because it has no more free semaphores to take). The interrupt being raised in the 'generate' function is obviously correct.

This is just an update. Now I'll be back to my original code trying to figure out what part of my "original" interrupt handler code is problematic and what exactly happens when the program runs.

Need help with "button" interrupt task (xSemaphoreGiveFromISR)

Hello again. Yes I'm using semihosting console but this doesn't seem to be issue, at least not in my case. Actually I just find the problem - it was the interrupt handler function name! As soon as I changed the name from void vInterruptHandler(void) to void EXTI01IRQHandler(void) it started to work as it should. Now the text sequence in console during program run is the following:

Which is just how it should be. It was silly from me that I didn't think of this issue before... What confused me was different handler interrupt name in that example I mentioned - but that was obviously because of of using different Cortex family I guess. Thanks for your answers anyway. Now I can finally move on my original idea - to use user button to generate interrupt.

Need help with "button" interrupt task (xSemaphoreGiveFromISR)

The name has to match the name in the interrupt vector table. If you call the function a different name then you will have to edit the vector table to so the names match. You will probably find the name in the vector table is EXTI01IRQHandler, but the provided implementation of EXTI01IRQHandler is declared weak, so it is replaced by your definition in the application code.

Need help with "button" interrupt task (xSemaphoreGiveFromISR)

Yes, you are totally right. Anyway just to let you know, I've also managed to modify my code to use user button for generating interrupts (instead of SW generated interrupts from periodic task), which was my original goal. Thanks again for your help and useful info, everyone.