Page 1 of 1

ISR and OSSignalXYZ improvements

PostPosted: Fri Jan 12, 2001 12:03 pm
by luben
Hello,

I think that you need to make different routines for calling OSSignalXYZ from tasks and ISR. This will save you a lot of headaches and hidden problems.

What I offer is to make OSISRSignalXYZ(). Such functions (or macros) should be called only from ISR. The idea is - when such function is executed it makes only simple setting of one flag (if SignalBin or SignalSem) or in case of messages - the value is kept in one additional (needed extra RAM) cell and one flag is set. Flags are just bit variables. Of course before you set these flags you have to ensure that there is no oveflow of the event (the event could be set, it's empty)

In the kernel you should make receptor of these flags - it will imitate OSSignalXYZ, but from the main stack level. If the flag is set - the OSSignalXYZ is executed, just like the user made it, only this will be hidden from the user. After they are signalled the flags should be cleared. These will bring some limitation to message queues - only one message could be transvered to the queue, before it's not processed from the kernel.

For each different event, called from ISR you have to create at least one bit variable (flag) and one or two bytes additional memory for messages and message queues.

This will not result big changes in Salvo, because the transport flags are "Salvo's style".

Think about such "transport flags". Because the demo doesn't supposrt OSSignalXYZ from ISR, I succeed to make working project using such transport keys. In fact, before the kernel is not started, the OSSignalXYZ doesn't take effect. So, if I check the "transport flags" before starting OSSched() I can imitate OSSignalXYZ() from ISR, without worrying about ISR conflicts and stack depth.

Regards
Luben


Re: ISR and OSSignalXYZ improvements

PostPosted: Fri Jan 12, 2001 12:35 pm
by aek
You're on the right track, but your method has three major problems:

1. It does not preserve the order in which events are signaled. This is very bad.

2. It's limited to one event signaled per event type. This is bad.

3. Having separate functions increases the code size. This should be avoided if possible.

Transport flags work if i) order isn't important and ii) you'll only signal once before the scheduler is called. They're more suited to binsems than anything else.

We consider both of these limitations unacceptable for Salvo. However, we think we've come up with a way to solve all of this, and use only one stack level in OSSignalXyz(), making it quite ISR-and-small-stack-friendly. Look for it in a future release.

[This message has been edited by aek (edited January 12, 2001).]


Re: ISR and OSSignalXYZ improvements

PostPosted: Fri Jan 19, 2001 1:13 am
by aek
I'm happy to report that OSSignalXyz() has now been reduced to a single call depth, and is callable (as before) from both mainline code and from ISRs.

This means that on a PIC16 with a call...return stack depth of 8 levels, your Salvo tasks can call functions up to five additional levels deep while running Salvo. This requires that the v2.2 in-line scheduler be used:

code:
OSSched()                      0
Task() 1
FnA() 2
FnB() 3
FnC() 4
FnD() 5
FnE() 6
ISR() 7
OSSignalXyz() 8

This new functionality will be available in all Salvo v2.2 versions.


Re: ISR and OSSignalXYZ improvements

PostPosted: Fri Jan 19, 2001 9:16 am
by luben
Hello,

Sounds really nice that you succeed to change the Salvo to better. By the way when we could enjoy meeting the new Salvo too? Some "dead line"?

I think that there is a some small mistake in your example.
Scheduler is on level 1, and the first task is called from Sheduler with "goto" command - so it's the same stack depth. So if I really undesrstood Salvo the example should look like

code:

main() 0
sched() 1
task() 1
funct1() 2
funct2() 3
funct3() 4
funct4() 5
funct5() 6
ISR 7
OSSignalXYZ() 8

By the way, looking at this graph I just wonder why scheduler have to use and consume from the stack depth? If you can make it like macro you can decrease the stack depth. I mean - because OSSched() in on level 0 it can consume up to 6 stack levels (calling some Salvo functions), even it can disable ISR and can consume all levels. But because it's called from the main level with "call" all other tasks lift with one level. If you can make the OSSched() not to be called from main level with "call", but with goto or like macro, you'll save one stack level more. In short - I think that it's possible to call the tasks (with "goto") from the main level, not from level 1, well, it's just a feeling.

Don't forget that using ICD in PIC consumes one stack level more. The idea of ICD is that inside of PIC are 2 registers (address compare registers, nowhere documented even with one single word). In the compare registers you put the address of the break point. That's why in the manual they say about these registers - "never try to modify them!!!" If the Program counter is equal to these registers - a "call" to routine 1f00 occures (consumes 1 stack level)- this is in short the idea of ICD, that is nowhere documented. And of course every stack level is worth. Because I don't have look at the source code I don't know that this could be done or not.

Regards
Luben


Re: ISR and OSSignalXYZ improvements

PostPosted: Fri Jan 19, 2001 10:06 am
by aek
No, the graph is correct, but maybe I should have added main(), like this:

code:
main()                         0
OSSched() 0
Task() 1
FnA() 2
FnB() 3
FnC() 4
FnD() 5
FnE() 6
ISR() 7
OSSignalXyz() 8

The scheduler can be in-lined, so it's at level 0. Indirect function calls to the task result in one stack level used (in PIC C, at least), because _indir_func is called, and from inside it there's a GOTO to the task.

Interesting about the ICD ... but there's not much we can do about it.

We're looking at a release of v2.2 in 4-6 weeks. We've decided that arrays will be part of v3.0, which will follow 6-8 weeks later.