Semaphores in DSP/BIOS

.
r
r

k.

=A0

upt.

PS: I "solved" this problem, albeit inelegantly (since it only works for the scenario in which the semaphore is used only once), by performing a SEM_post() immediately after the SEM_pend() in each task that was pending.

--Randy

Reply to
Randy Yates
Loading thread data ...

Thanks to everyone for your responses, but judging by the complexity of your responses, I think you misunderstood my question.

The main point is this: isn't there a "type" of semaphore usually provided in other OSes which allows multiple tasks to pend on a "single" post?

--Randy

Reply to
Randy Yates

Hi don,

You've hit it on the head. This is exactly the kind of answer I was looking for. In fact I did implement your second (?) solution (although I came up with it before reading it here).

The last suggestion is also quite good - alas there are some toolchain/ build issues associated with creating tasks dynamically, hence the scenario I proposed.

Thanks for showing me I'm not completely out of it!

--Randy

Reply to
Randy Yates

er

,
s

g?

for

ask.

rrupt.

f

ies

Again, bingo! You've hit it on the head - that's exactly my scenario too. I have an Init() task that needs to run before everything else starts up.

--Randy

Reply to
Randy Yates

Record)',

formatting link
*A New World Record*, ELO

Some semaphore implementations let you post "N" instances in one call. I.e., pick a very large N :>

One advantage of this is T1 can then examine the semaphore's

*value* and see if every other task has "successfully pended" on it (if T1 knows how many tasks there are). So, if T1 needs to do something *after* all of the other tasks have passed this "checkpoint", it can do so without requiring another mechanism through which the tasks signal their progress *back* to it. I prefer a sticky flag.
Reply to
D Yuniskis

Yes. It's called a 'binary semaphore'. Sometimes it's called an 'event' or a 'flag'. A complete RTOS should have both: many have just one or the other, along with some weasle-word justification for the practice that boils down to "we never need to use the other kind of semaphore and we're lazy, so you don't need to use it either".

--
Tim Wescott
Control system and signal processing consulting
www.wescottdesign.com
Reply to
Tim Wescott

Is this an RTOS that's integrated into your C environment and comes up "invisibly", or does it need to be called explicitly? If I'm using an RTOS that needs to be started from main() I'll often do all of my initialization there, then kick off the RTOS.

--
Tim Wescott
Control system and signal processing consulting
www.wescottdesign.com
Reply to
Tim Wescott

Okay

Gack! No.

I like to view your motor-control example as follows:

(1) ADC interrupt causes an ISR task to be performed at a certain priority (P1) (2) Conditionally this task might add a lower-priority (P2) task to the scheduler's queue for that priority (3) When the ISR task returns, the scheduler does one of two things:

a) If there is already a P2 task running, it does nothing. The remaining P2 tasks will eventually be run b) If not, it checks the queue for P2, and if non-empty starts the first task in it

Now, whether a given RTOS behaves like this, I am unsure. It is how I wrote schedulers a number of times. It would seem to address Randy's problem of not all of T2, T3... ever running, and it avoids doing a blunt-instrument lowering of priority in an ISR. (Which among other difficulties makes the IRS re-entrant!)

(Except, now Randy has clarified he was only asking about types of semaphores, not schedulers...)

Yes. I tend to see (or tended to see, before Randy clarified) his issue as he was bypassing the scheduling paradigm to run one task, and so others at that priority were never started.

Steve

Reply to
Steve Pope

Events/flags are different. A semaphore (strictly speaking) is only examined by pending on it. And only modified by posting.

An event/flag is something that can freely be examined without "taking it". (i.e., when you "take" a binary semaphore, the next guy -- pending -- has to wait for someone to *post* it).

I vary in how I implement these. Sometimes they are "sticky". Like a bit that gets explicitly "set" (asserted) by "someone", "examined" by others (await-ed) or "reset" (released), etc.

I.e., the flag has *state*... "memory".

Usually, I let events be transitory in nature. Like an "edge" instead of a "level". I.e., if you are waiting for an event

*when* it happens, then you "see" it (along with everyoneelse who is waiting). But, if you start waiting for it just *after* it has occurred, you *don't* see it (i.e., you wait for the *next* one to come along).

These concepts can be encapsulated in other manifestations. E.g., you can use mailboxes/ports and RPC/IPC to allow events to be distributed (multiprocessor systems) transparently. If, for example, you have the ability to broadcast messages to lists of ports/queues then anything waiting *in* one of those queues (for an anticipated message!) can be "woken up" by sending N copies of a message to that queue. Since the OS presumably already knows how to handle ports being located on different processors, the OS gives you this

*distributed* ability "for free".

Yup. Usually because they want to trim the size of their kernel or make it easier to handle certain circumstances. These things usually don't take much "extra" to implement so it's annoying when someone "arbitrarily" decides to offer one type of mechanism but not other, similar, ones.

Like someone saying "we only use NAND gates; you can *make* anything you want using (an infinite number of) them!" :-/

Reply to
D Yuniskis

s.

er

,
s

l the days go by... =A0 =A0

ho am I?"

)',

formatting link
*ANew World Record*, ELO

For 2/4-phase handshake protocols, look up resources on asynchronous hardware. So yes this is actually logic stuff. This approach is more suited to scenarios when you'r hard-coding things like what I do all the time i.e. no RTOS kernel for maximum performance. And hooking them up with boolean expressions lets you determine priority exactly like logic. Still, I'm pretty sure you can apply same concept even on top of an RTOS. I just happen to like a unified approach in thinking about things which is rightfully grounded in the medium you happen to be working on i.e. digital logic.

-Momo

Reply to
Manny

Bah, a 'complete RTOS' ?! What is this? Why is having semaphore a measure for the completeness of an RTOS ?

--
42Bastian
Do not email to bastian42@yahoo.com, it's a spam-only account :-)
Use @monlynx.de instead !
Reply to
42Bastian Schick

Because I said so, before you weighed in.

--
Tim Wescott
Control system and signal processing consulting
www.wescottdesign.com
Reply to
Tim Wescott

ROTFL!

+1 Tim! ;-)
Reply to
D Yuniskis

Then it is ok. I go back to my corner and be ashamed :-)

--
42Bastian
Do not email to bastian42@yahoo.com, it's a spam-only account :-)
Use @monlynx.de instead !
Reply to
42Bastian Schick

Good. I'll pat myself on the back.

Note that I don't think that one necessarily _needs_ a "complete" RTOS (whatever that is), but if there were one out there it would certainly have both flavors of semaphores.

--
Tim Wescott
Control system and signal processing consulting
www.wescottdesign.com
Reply to
Tim Wescott

Oh, so you want to know what's REALLY going on? ... :)

Yes, I had my initialization initially in main() also. The problem is that one of the things that needs initializing uses the SPI bus, and the processor is so damned fast (2 ns instruction cycle) some type of delay is required between SPI bus transactions.

So instead of attempting to write a delay routine, whose accuracy in this day and age is going to be subject to things like compiler optimization flags, code cache hits, etc., I thought it would be much more elegant to utilize the OS's TSK_sleep() function (which is based on hardware timer ticks).

So, even though my Init() task was running at the highest priority, the TSK_sleep() calls block and allow lower-priority tasks to run. Hence my need for a "gating" semaphore.

--
Randy Yates                      % "My Shangri-la has gone away, fading like 
Digital Signal Labs              %  the Beatles on 'Hey Jude'" 
mailto://yates@ieee.org          %  
http://www.digitalsignallabs.com % 'Shangri-La', *A New World Record*, ELO
Reply to
Randy Yates

Ha! I hear ya' Tim.

Well, it turns out DSP/BIOS _does_ have a "binary semaphore." The problem is, it's not the type of binary semaphore I need.

From the DSP/BIOS API Reference Manual for SEM_pendBinary():

SEM_pendBinary and SEM_postBinary are for use with binary semaphores. These are semaphores that can have only two states: available and unavailable. They can be used to share a single resource between tasks. They can also be used for a basic signaling mechanism, where the semaphore can be posted multiple times and a subsequent call to SEM_pendBinary clears the count and returns. Binary semaphores do not keep track of the count; they simply track whether the semaphore has been posted or not.

[...]

If the semaphore count is non-zero (available), SEM_pendBinary sets the count to zero (unavailable) and returns TRUE.

If the semaphore count is zero (unavailable), SEM_pendBinary suspends execution of this task until SEM_post is called or the timeout expires.

So what I need is not something that can handle multiple posts and one pend, but rather something that can handle multiple pends and one post!

--
Randy Yates                      % "And all you had to say
Digital Signal Labs              %  was that you were 
mailto://yates@ieee.org          %  gonna stay."
http://www.digitalsignallabs.com % Getting To The Point', *Balance of Power*, ELO
Reply to
Randy Yates

Hi Folks,

I just realized what would probably be the best solution given the semaphores available in DSP/BIOS. Initialize the semaphore to a 1. Then SEM_pend() on the semaphore at the beginning of the Init() task (this assumes the Init() task runs first at startup), and SEM_post() on the semaphore at the end of the Init() task. As before, all other tasks SEM_pend() on the semaphore, then as soon as the pend is released, post to the same semaphore.

This way, if any other tasks run between Init() begin and Init() end, they will block since the pend at the beginning of Init() will have taken the semaphore. And at the end of Init, the pend will allow the first pending task to unblock, it's pend allows the next pending task to unblock, etc., until task N is unblocked and when it posts the semaphore will be left at a 1, ready for the next "resource block" (if any).

--
Randy Yates                      % "How's life on earth? 
Digital Signal Labs              %  ... What is it worth?" 
mailto://yates@ieee.org          % 'Mission (A World Record)', 
http://www.digitalsignallabs.com % *A New World Record*, ELO
Reply to
Randy Yates

Hi Randy,

I've read the posts you've wrote about DspBios over the past few weeks. Seems like you're currently starting to use it..

If so: You should take a look at the software interrupts. For me they are the swiss army knife of process synchronization. DspBios on it's own already offers a lot, but there are things that you can't directly do with it.

One practical example that I once had to deal with: I was gluing together different third party libraries. One was writing it's result to a mailbox, the other one was posting a semaphore.

How do you write a consumer task that starts processing results as soon as one of the conditions occur? DspBios does not has as pre-canned solution.

My first solution was built upon tasks. I had one helper-task waiting for the mailbox, another helper-task waiting one on the semaphore and both threads signaled a event to a third thread, my consumer.

Sounds like a straight forward design, but it didn't worked as expected. My helper threads worked inside the task environment, so it happened that for example my first helper thread read the data from the mailbox and unblocked my consumer-thread, but the consumer thread never started because there was something higher priority running inside one of the third party libraries.

Software interrupts solved the problem for me. They life outside the scheduler, so a software interrupt preempts any task. This lets you post multiple semaphores without getting interrupted, it lets you check mailboxes, semaphores and each other blocking DspBios primitive. You can also post semaphores and unblock tasks inside software interrupts.

They are much leaner than tasks. You can raise them with conditions (counting or masking). Also they don't block hardware interrupts in any way..

As said: For non trivial scheduling problems a swiss army knife. And easy to use..

Cheers and and have fun,

Nils

Reply to
Nils

again a few mistakes:

--
Randy Yates                      % "How's life on earth? 
Digital Signal Labs              %  ... What is it worth?" 
mailto://yates@ieee.org          % 'Mission (A World Record)', 
http://www.digitalsignallabs.com % *A New World Record*, ELO
Reply to
Randy Yates

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.