Page 1 of 1

OS_xxx calls from subroutines?

PostPosted: Thu Jun 27, 2002 5:35 am
by aek
Hi Jeff.

You are on-target. "OS_"-prefixed services (e.g. OS_WaitSem())may only be called from tasks, and not from subroutines. "OS"-prefixed services (e.g. OSSignalSem()) can be called from anywhere. Allowing context switches only from the task level is one of the major reasons why Salvo is able to get by with such small RAM requirements -- you can run it on a 256-byte 8051 quite easily.

Encapsulation as you describe (e.g. printf() blocking when a buffer is full) is perhaps the most common problem that crops up due to this limitation. There are a couple of ways one can circumvent this. None are as simple as the conventional stack-based RTOS approach, but then none carry the RAM penalty of independent stacks for each task.

Ways around it include i) to have some sort of two-way handshaking (e.g. using binSems) between the sending task and the process (usually another dedicated task) that handles the buffer, or ii) use counting semaphores to manage the filling of the buffer (in your example). This latter example requires that the printf() be called from a dedicated "printf task", which is fed string data (e.g. via messages) from another task.

One thing to note is that adding additional events (e.g. binSems) or tasks to solve a problem like this is very efficient, RAM-wise.

I have been wanting to write an AppNote to address precisely this issue. Anyone else care to add their thoughts / experiences / solutions?

Regards,

------------------

[This message has been edited by aek (edited June 27, 2002).]


Re: OS_xxx calls from subroutines?

PostPosted: Thu Jun 27, 2002 11:22 am
by JBevis
It would seem that, as there are not independent stacks per task, one could not use OS_xxx function calls within subroutines of task functions. Such use could cause a context switch to occur within a subroutine, potentially altering the stack contents if another task runs.

Is this true? Can OS_xxx calls only be made from within the topmost function level of a task? If so, it presents a severe limitation on coding, and I am curious as to how this would be circumvented. For example, a printf() call may need to block when a serial output buffer is filled, but since it is a subroutine it would not be able to yield to other tasks without damaging their stack state and presumably the return addresse(s) to any calling function(s).

Of course, maybe I'm waaay off base here and I'm just missing something really obvious. Help?

------------------
Jeff Bevis
jbevis@graviton.com


Re: OS_xxx calls from subroutines?

PostPosted: Fri Jun 28, 2002 10:15 am
by aek
Hi Jeff.

Here's a more explicit way that you can handle the printf() issue, using a binSem:

1) Initialize the binSem to 1, indicating that your tx buffer (serial out) is available / empty.

2) In your routine to empty the buffer and send the chars out the serial port, set the binSem to 1 (via OSSignalBinSem()) when the buffer is completely empty.

3) Wherever you want to printf(), test the binSem first via OS_WaitBinSem(). Your task will block if space is not available in the buffer.

This method works by treating the entire serial output buffer as a resource, i.e. either it's completely available or it isn't. It works only for strings that will fit in the buffer.

Ideally, one would use a counting semaphore pre-set to the number of "slots" available in the buffer. However, the event-waiting interface (via OS_WaitSem()) is a one-at-a-time kind of interface, which doesn't mesh well with printf() (though it does with putchar()). I'm wondering if we ought to develop a OS_WaitSemN() service which will block the task until the semaphore in question exceeds the argument N ...

Regards,

------------------


Re: OS_xxx calls from subroutines?

PostPosted: Sun Jun 30, 2002 9:39 am
by JBevis
Okay, makes sense. I am trying to adjust my brain to the idea of working in this way. I'm not quite sure where the boundaries are going to get in the way just yet. I have a fairly complicated app, a wireless sensor network communications protocol (yeah, on a little 8051!). We'll see how it goes. Thanks for the confirmation - now I can proceed with some certainty.

BTW: I struggled to find this critical information - actually I never did - in the user manual. Perhaps it deserves a few more redundant mentions?

------------------
Jeff Bevis
jbevis@graviton.com


Re: OS_xxx calls from subroutines?

PostPosted: Mon Jul 01, 2002 10:36 am
by aek
Hi Jeff.

We're planning a fairly substantial reorganization of the documentation in an upcoming release -- I'll ensure that this issue is more obvious to the reader.

Regards,

------------------