Pumpkin, Inc.

Pumpkin User Forums

Too short OSDelay()

If you can't make Salvo do what you want it to do, post it here.

Re: Too short OSDelay()

Postby aek » Tue Oct 31, 2006 9:19 am

quote:
The nestled functions are supposed to generate sound, a specific pattern 400ms*3 with an OSDelay(5, soundTask) between each repetition. So, yes the task will be occupied through several ticks (~40 between each repetition). Is this a problem? The OSTimer is still called every 10 ms. Should the task be shorter? Is there a limit to the execution time of a task?
400ms (milliseconds)? Not 400us (microseconds)? If milliseconds, yes, you will have a problem.

You're saying that the pattern should be:

...
pattern for 400ms (inline delay)
pattern for 400ms (inline delay)
pattern for 400ms (inline delay)
delay for 50ms (via OS_Delay)
...

Is this correct?

There is no limit to how long the task can run.

Please clarify, then I can continue.

Note: Any time that you are running (e.g. in a task) and not yielding back to the scheduler (via an OS_Xyz()) within a system tick, you are causing the timer system to "fill up". As soon as you yield to Salvo's scheduler, the timer system will "clear out" up to 255 "lost ticks". If e.g. a task was delayed with 3 ticks prior to the hold-off, and the holdoff lasts 19 ticks, then that task will run immediately as soon as the schduler runs, because its ticks expired while the scheduler was held off because the tasks did not yield for 19 ticks. So, normally we see these sorts of delay issues from tasks that began their delays before the failure to yield in a task. But that's not what you are doing (because you said that the problem delay is in this very task, and you said the delay is essentially 0 instead of 5 ticks).

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

-------
aek
aek
 
Posts: 1888
Joined: Sat Aug 26, 2000 11:00 pm

Re: Too short OSDelay()

Postby aek » Wed Nov 01, 2006 7:53 am

So, I think I understand your situation now.

You have a function (SED_Bell()) that generates a sound and the sound is 400ms long. Correct?

So, here is what is happening in your system:

OSTimer() is called every 40ms by an ISR. This happens all the time (i.e. every 40ms Salvo registers that a system tick has happened).

Additionally, OSSched() runs "as often as possible" from main(), i.e. it runs whenever a task yields via as OS_Xyz() call. Note that during the 400ms of SED_Bell(), OSSched() is not called (because only a task can yield to the scheduler, and SED_Bell() is a function).

So what happens is that during SED_Bell(), the numer of ticks that were called (400/40 = 10) is saved up in Salvo's lost tick counter, because OSSched() is not called during SED_Bell(). Then, after SED_Bell() finishes, you call OS_Delay() (which is a context switch), and then OSSched() runs. (BTW, you can watch OSlostTicks from within MPLAB.) Since there are lost ticks "saved up" in the system, they need to be cleared out ASAP by OSSched(), and so any delay that is less than the number of loast ticks will expire immediately. This is absolutely the correct behavior, because it's imperative that Salvo get all the delays "back on track" to correct for the fact that you have held off the scheduler for 400ms (10 ticks).

When you have a function like SED_Bell() that causes a task to no longer yield to the scheduler in a reasonable time (i.e. > 1 system tick), you are no longer multitasking, and you will see behavior like what has perplexed you here.

If you must have accurate (<< 1 system tick) timing with SED_Bell(), then you should use a High ISR to generate the sound. This will have two benefits -- 1) it will be most accurate, because it will be driven solely by the (hardware) interrupt system, and 2) as long as you set OSPIC18_INTERRUPT_MASK to only disable low-priority interrupts and make Salvo service calls (e.g. OSTimer()) from a low ISR, then the timing of your high ISR will be unaffected (zero interrupt latency) by Salvo. With a configuration like this, everything will work exactly as you think it should -- Salvo will do all the multitasking (including task delays), and your app will alsohave super-accurate timing with things like the sound. I'd suggest reviewing http://www.pumpkininc.com/content/doc/press/pumpkin_supsi2005.pdf -- this talks precisely about this sort of approach.

If the 400ms does not have to be accurate, then you could use Salvo to generate those delays as well (i.e. use in-line code to do what SED_Bell() is doing, with OS_Delay() as the means of setting the delays).

Another option is to set the tick period to be 500ms -- that would be the quickest (obvious) fix. But this solution does not address the fact that you are killing multitasking with a SED_Bell() function that lasts 400ms.

quote:
Another question out of curiosity, what happens if something is executed that takes several ticks but the OSTimer and scheduler is not called during this period of time? Will it be like if "time stood still"?
Yes, but OSTimer() is normally called from an ISR, and so you shouldn't (ever) disable that ISR. Your problem is all due to the fact that SED_Bell() lasts 400ms and during that time, you do not yield to OSSched().

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

-------
aek
aek
 
Posts: 1888
Joined: Sat Aug 26, 2000 11:00 pm

Re: Too short OSDelay()

Postby Jenny » Wed Nov 01, 2006 11:29 am

Ok, it all seems so obvious now. I'll try both of your suggestions. Thanks a lot for all help!

/Jenny

Jenny
 
Posts: 7
Joined: Wed Oct 18, 2006 11:00 pm

Re: Too short OSDelay()

Postby Jenny » Wed Nov 01, 2006 12:16 pm

Hi Andrew,

The sound pattern is; sound, OSDelay(), sound, OSDelay(), sound, OSdelay(). I did not know that the scheduler needs to be called every tick, I thought that yielding every 400 ms would be enough since the other tasks wants to run every 500ms-10,000ms (except for one task that will be slightly delayed). How can I solve this without disturbing the sound? If I yield in the middle of the loops this is the effect. Do I need to generate the sound in a high ISR instead? Another question out of curiosity, what happens if something is executed that takes several ticks but the OSTimer and scheduler is not called during this period of time? Will it be like if "time stood still"?

Thanks.
Jenny

Jenny
 
Posts: 7
Joined: Wed Oct 18, 2006 11:00 pm

Previous

Return to Coding

Who is online

Users browsing this forum: No registered users and 2 guests