Sequence of code blocks

gerhardkreuzer wrote on Thursday, January 21, 2016:

Hi,
I have to go thtough a list of functions, but there is a rule. Start the next function after the previous function has done … and this takes time. Such a function (logically not programmatically) consists of some steps.

func1()
startTimer
func2
BLOCK until timer expires
func3
func4
startTimer
BLOCK until timer expires

Other tasks should run during a BLOCK phase
How can I do this efficiently within freeRTOS?

With best tegards

Gerhard

rtel wrote on Thursday, January 21, 2016:

The most efficient way would be to have the task use a direct to task notification when it needs to block, and have the timer send the notification to the task when it expires (unblocking the task). See the example code on the following page: http://www.freertos.org/RTOS_Task_Notification_As_Counting_Semaphore.html

Depending on your requirements, the timer could be either a one shot software timer, or a hardware (peripheral) timer. If it is a software timer then a callback will execute when the timer expires - and the callback function will send the notification to the task to unblock the task. If it is a hardware timer then an interrupt service routine will execute when it expires, and the service routine will send the notification to the task to unblock the task.

You will need to make sure the task does not already have a notification pending before it start the timer - otherwise it will not block when it attempts to wait for a notification, because one is already pending.

Regards.

gerhardkreuzer wrote on Thursday, January 21, 2016:

Thanks. Will look into that sample.
Unfortunately have an older version without notification and Atmel didn’t integrate the new version in her IDE …
Maybe you can tell me how to migrate within Atmel Studio 6

With best regards

Gerhard

rtel wrote on Thursday, January 21, 2016:

Just use a binary semaphore instead of the task notification - as per
your other post. It is less efficient, but functionally equivalent.

gerhardkreuzer wrote on Friday, January 22, 2016:

Thanks,
ok, this means, semaphores only working between different tasks. As I have a list of steps I cant do this:

step1();
step2();
step3(); ==> starting only when a recursive mutex taken in step1 and step 2 is given by timers used by step1 and step 2. And it isnt important which timer expires first.

Is it true I have to seperate step3(), running in a different task to wait for this semaphore?

With best regards

Gerhard

rtel wrote on Friday, January 22, 2016:

No, it can be the same task. In fact, with mutexes, it would be normal
for the same task to both take and then give back the mutex. Different
semaphores are used in different scenarios.

Note if you are using a recursive mutex you will have to use a software
timer rather than an interrupt. Other types of semaphore can be given
from an interrupt, but mutexes (recursive or not) cannot as they include
a priority inheritance mechanism (which works on task priorities, and
gets confused if its an interrupt using the mutex).

Regards.

gerhardkreuzer wrote on Friday, January 22, 2016:

What exactly is the terminus ‘owner of the semaphore’ ?
As both tasks have to know the semaphore, or have a pointer to it, the semaphore has to be declared somewhere outside. The system hardly can know which tasks owns the semaphore, right?
When I call a API function …Take… within a task loop, than the system knows somehow that this task currently owns the semaphore? There is no parameter to define that.
The owner can do whatever he want, take, give no blocking take place, right?
All other tasks, which didn’t own the semaphore were blocked during a take, right?

The ownership of a semaphore could be changing during system lifetime?

If another task takes the semaphore first he will be the owner until he gives the semaphore, right?

If two tasks want to use a shared resource, one tries first so it is the owner until he is done, afterwards the other task owns the semaphore probably until he is done, right?

But always needed, it only works between different tasks, right?

With best regards

Gerhard

gerhardkreuzer wrote on Friday, January 22, 2016:

Ah.
Ok, I tried to use a recursive mutex, and a software timer.
I called my steps, here the mutex is taken and the timer is started, which also restarts the timer if it was running.
In the timer callback I gave the mutex.
But the system halts indefinetly long on that line for what reason ever.

So I start reading again and found the ownership clause and now I think I am wrong.

Ok, any idea whats wrong with my idea?

stepX()
carry out functionallity.
If timer is running, just restart
if timer is not running, take the recursive mutex and start timer
step3() blocks until he can take the mutex.

All code running in one task.

I attached my code of one of this steps.

With best regards

Gerhard

rtel wrote on Friday, January 22, 2016:

Semaphore ownership doesn’t really have a meaning unless you are using a
semaphore type mutex, in which case the semaphore is intended to be used
to guard a resource. If you want to access the resource first you must
successfully ‘obtain’ the mutex, and as long as you have the mutex, no
other task can successfully obtain it - and as only the mutex owner can
legitimately access the resource, the resource is protected. Once you
have finished with the resource you give the mutex back - at which point
other tasks that want to access the same resource have an opportunity to
obtain the mutex.

In your case, you are not using the semaphore in this way, so I was
guessing the only reason you were using a recursive mutex was so you
could ‘take’ it multiple times, but from you latest post I’m wondering
if that is what is causing you the problem. With a recursive mutex you
must ‘give’ it back the same number of times as you have [recursively]
taken it before it becomes available again.

When you say “If the timer is running, just restart it. if the timer is
not running, take the recursive mutex”, it sounds you are going to take
the mutex the same number of times as the timer callback function is
going to give it - because you are only taking the mutex again if the
timer has actually expired. However, you may get into race conditions
here - for example, if the timer were to expire between your task
determining it had not expired and your task restarting the timer.

I don’t want to confuse things, as you seem to have gone down this route
quite some way, and I don’t fully understand your use case, but perhaps
an event group would be a more appropriate object to use than a mutex.

Lets say you have three timers, the timers are started at different
times, and at some point your task wants to wait until all three timers
have expired. That might not be the actual case, but perhaps close
enough to your actual case to use as an example.

You can assign different bits in the event group to three different timers:

#define TIMER_1 ( 0x01 << 0 )
#define TIMER_2 ( 0x01 << 1 )
#define TIMER_3 ( 0x01 << 2 )

Before you start any timers you ensure all the bits are clear.

The callback function for timer 1 then sets bit TIMER_1 in the event
group. The callback function for timer 2 sets bit TIMER_2 in the event
group. The callback function for timer 3 sets bit TIMER_3 in the event
group (the same timer callback function could be used for all the
timers, but lets keep it simple now, and assume these are three separate
callback functions for three separate timers).

Once your code has started all three timers, and gets to the point where
it needs to wait for all three to expire, it has to wait
for all three bits to get set in the event group
:

xEventGroupWaitBits( xEventGroup, // Handle of the event group
                     ( TIMER_1 | TIMER_2 | TIMER_3 ), // Bits to wait for
                     pdTRUE, // Clear the bits back to zero before returning
                     pdTRUE, // Wait for all three bits to be set
                     BlockTime ); // However long you want to wai

Is this close to what you want to achieve?

gerhardkreuzer wrote on Friday, January 22, 2016:

Hmm, somehow, but: Atmel uses freeRTOS 7.3.0, as I can see here, so there is no event group available, isn’t it?

How can I update, I use a ARM 4 based MCU, sam4n by Atmel.

I posted my code, maybe something is wrong and I just didn’t see it.

Race condition, ok, but I tried it more than once, so race conditions only appear sometimes, or I am wrong?

With best regards

Gerhard

rtel wrote on Friday, January 22, 2016:

I think event groups were added in version 8. In theory you
should be able to take the latest version of FreeRTOS and drop the
source files over the top of the ones you are using. I say that is the
‘theory’, so make sure you have a back up of your existing files first.

gerhardkreuzer wrote on Friday, January 22, 2016:

Ok, will give it a try.

I attached an altered code snippet, cause I still not understand how this recursive mutex can know whats wanted in the moment …

The InputMux_setPort function is the one we discuss …

gerhardkreuzer wrote on Friday, January 22, 2016:

… what does this mean for the idea to just copy the V8.x files over the V7.3 files?

Software timers and FreeRTOS-MPU
The software timer API is not yet included in the official distribution of FreeRTOS/source/include/mpu_wrappers.h.

With best regards

Gerhard

gerhardkreuzer wrote on Friday, January 22, 2016:

Hi,

ok, done, but not working out:

1.) Copied file per file from new version over original version supplied by Atmel. There is a folder /portable/gcc/sam and here I take the CM4F files. Unfortunately I get an error that a floating point option has to be set somewhere …
2…) Next I tried out the CM3 files, as the original uses the CM3, but again, I get lot of errors, telling me, that MCU_… is missing.
3.) I just reied the original files, and now I get lot of errors cause something is declared double …

Seems, that Atmel didn’t work with V8.2

With best regards

Gerhard

gerhardkreuzer wrote on Friday, January 22, 2016:

Ok, after switch to V8 didn’t worked out I start checking why it hangs in the timer callback and I get nice result, see screenshot.
The system told me that I cant give the mutex, cause I am not the holder, aha …

So, this pattern would not work out but why?

With best regards

Gerhard

gerhardkreuzer wrote on Friday, January 22, 2016:

Hi,
so is this an explaination for that behaviour?

In the manual I get this info:

Mutexes must always given back by the owner.

Ok. I take the mutex in the context of my shell task, which decodes command line input and calls the function under discussion. The software timer is run by another task, which is the timer service by freeRTOS. The timer callback is running in the context of this task and so for the mutex can’t be given by the callback function …
And that is exactly the situation I see here during debugging.

Ok, but how can I carry out the function I needed (using FreeRTOS 7.3, thanks to Atmel, grr).

It is somehow common when hardware programming is in the focus. I want to execute a code block kicking off some hardware action, like switching a relay… Than I want to continue down the code until I reach a point, where the hardware response must be finished. During executing more code, the hardware, here a relay takes his time to finish switching (bouncing effects …).

Which kind of synchronisation/blocking can I use to archive this?

Mutex isnt that good.

Ok, semaphore maybe, but what if I have two or more such situations. Preparing different pieces of hardware and after all has setteled I start some other code block.

???

With best regards

Gerhard

PS: Would be a nice sample in the new upcoming book, cause I think it is common enough and it isn’t a task to task sync, it is more than a gate function. Gate can only be passed, if some processes outside the system (relays …) entering a stable state.

edwards3 wrote on Friday, January 22, 2016:

Mutexes are used to for mutual exclusion, where the taker has to be the giver to relinquish a resource. Binary semaphores are used for synchronization, why not use one of those? Counting semaphores might be useful too.

gerhardkreuzer wrote on Friday, January 22, 2016:

Hi,
the problem is, that I have to call the function more than once, and couldnt know in advance how often. It could be between 0 and 4.
There were other functions also setting something in HW and after all that I have to wait until all is settled.
So I discovered the recursive mutex.
Counting semaphore do odd things. Counting events, ok, but I don’t know how often the functions were calles, so this is of little use.
Maybe the new Event Group will be a nice thing, but I am not able to use FreeRTOS v8, Atmel didnt provide any infos ábout migration and just copy the fils around fails …

With best regards

Gerhard