Hello,
I think that talking about the new function OS_Interval() we have to agree that it’s look like events (and more exactly Semaphores) and it’s called from OSTimer. In fact it’s some kind of semaphore, that’s increasing after defined time (and the only one function in SALVO that initalize all other time functions is OSTimer()). So, if we need 3 different OS_Intervals in 3 different tasks we should declare them like 3 different new type events. Let’s call them TimeSem type (I propose for the new function name that includes “semaphore” and something related with the time, period, interval)
code:
OSCreateTimeSem(OSECBP(1), initial_value1);
OSCreateTimeSem(OSECBP(2), initial_value2);
OSCreateTimeSem(OSECBP(3), initial_value3);
What I can say right now is – Intervals are some kind of semaphores (or in worst case BinSemaphores) that increase their value when called OSTimer() and the desired period expires. I think that we can wait for them with the current functions in SALVO like OS_WaitSem(), OSGetSem(), OSTrySem(). In fact they have the same structure like ordinary semaphores, no difference, except that their signaling happens in OSTimer().
It’s not the best solution for them to have functionality like BinSemaphores. I’ll explain why – If one task has low priority it’s possible that it will not get the control from time to time for longer interval, that even can be bigger then 2 pace ticks (of the TimeSemaphore). So, if you get the control you’ll not have a track – is this the first and only one signalling, or there were other signallin too. In second case the user could do some other action – or to skip this delayed event or to try do some action.
Even we can declare them like ordinary semaphores, but them we have to make another declaration that exactly these semaphores will be called in OSTimer(). I think that it’s better to be declared like different type (TimeSemaphores) and then to be read and wait for them with the standard semaphore functions. Using different functions like OS_WaitTimeSem() maybe will make heavier SALVO and will consume more RAM and RAM.
The difference between ordinary semaphores and TimeSemaphores is that with their declaration we declare some additional amount of RAM, where we’ll keep in the future the interval for signaling and the counter of the current calls. That means – using 8 bit delays will consume additional 2 bytes for every TimeSemaphore, using 16 bit delays – 4 bytes and so on.
The structure of such time semaphore needs 2 additional variables – first variable keeps the total interval and second – the current value within the interval. Second variable is one counter of subtraction – after it becomes zero it’s loaded with the value of total interval (for each TimeSemaphore there are 2 different pairs of variables) and in the same moment signals the semaphore. Task that wait for such time semaphore will get this event after some time if it’s in WaitState, or if it’s enter in such function (already signaled) will return the control immediately. Well, attention to avoid “bombarding case” should be made – you know how.
It’s possible to exchange the first variable with “hard” value in the ROM – in the initial declaration of the events we’ll place some value that could not be change during the program execution – this will save some RAM. In that case we don’t need additional function in SALVO to set the interval, except the synchronization function.
Into OSTimer() should be add some part of software, that decrements the TimeSemaphore counters and if they become zero to load them with the interval values (from RAM or ROM ) and to signal one more time the time semaphore. Because you signal semaphore, even if the task doesn’t get the event immediately it will know if some extremely big delay occurred.
To make possible to switch on or off this part of the program I propose some settings like (Time semaphores number is a part of EVENT number):
code:
#define TIME_SEMAPHORES 3
// will add this functionality to SALVO – 3 time semaphores
// default value is 0 – no time semaphores
Of course we need function to reset the counters –
code:
OS_Sync(OSECBP(1));
it will immediately reset the counters – that’s equal to phase synchronization.
And we need function to set the interval for this events like:
code:
OSInterval(OSECBP(1), value_of_interval);
it will set the virst variable, which keeps the amount of interval, if we want to change it after we created them.
Maybe we need some additional function OS_ClearTime() that will reset the value of counter of signalled events (it’s like to reset the value of semaphore). It could be made with loop of OS_TrySem() until it returns zero value, but will consume more time.
code:
OS_ClearTime(OSECBP(1));
// sets the value of this time semaphore to zero
// it’s good to do this before you start the tasks, that waits the timesemaphore
After we set the interval and synchronize the timers we could wait for this event with the good known OS_WaitSem(). Well, because the ECB of the time semaphore is little bit different, maybe time semaphores have to own 2 ECB – one ordinary SEMAPHORE ECB and one additional TIMESEMAPHORE ECB. In fact when we wait for this function we’ll need only the standard semaphore ECB, and only within the OSTimer() we have to use 2 additional variables – for amount of interval and for current decrementing counter. It’s up to you how you’ll make the structure of ECB, but one is definitely sure – TimeSemaphores are ordinary Semaphores with 2 additional variables that’s used to signal the semaphore in OSTimer().
Because they look like so much to ordinary semaphores, I proposed some name that use “semaphore” inside – like Time Semaphores, Interval Semaphores, Sync Semaphores. Unfortunately English is not my native language so I can’t play with words like you can.
What I described covers all what we need to generate periodical signals, without carrying about all other possible delays after we receive control of the OS_WaitSem().
Some improvement – it’s possible to use prescaller of the timer, so we can increase the resolution of the function. When we call OSTimer and we do decrementing the prescaller, we can decrement the counters of TimeSemaphores too.
Maybe using:
code:
#define OSTIMESEMAPHORE_LENGTH 2 // will use 2 bytes variables
we can just set simply what we need. Well, before this we have to declare the prescaller of OSTimer() too.
This will need increasing of the length of the variables of TimeSemaphores too – right now I don’t have clear vision how this could be made with settings of SALVO, need time to ripe the idea. If the OSTimer is quickly enough we can increase the frequency of calling the function via ISR. Time semaphores will get very good resolution, even enough to declare multiple RS232 receive channels on high speed (with this function will be very easy to implement almost any mumber of receive and transmit RS232 channels).
Hope we approach to the final idea.
Regards
Luben
[This message has been edited by aek (edited September 24, 2001).]