Pumpkin User Forums
Coding Too short OSDelay()
|
UBBFriend: Email This Page to Someone! | next newest topic | next oldest topic |
Author | Topic: Too short OSDelay() |
Jenny Junior Member |
posted November 01, 2006 11:29
Ok, it all seems so obvious now. I'll try both of your suggestions. Thanks a lot for all help! /Jenny IP: |
aek Moderator |
posted November 01, 2006 07:53
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: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(). ------------------ IP: |
Jenny Junior Member |
posted November 01, 2006 00:16
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. IP: |
aek Moderator |
posted October 31, 2006 09:19
quote:400ms (milliseconds)? Not 400us (microseconds)? If milliseconds, yes, you will have a problem. You're saying that the pattern should be: ... 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). ------------------ IP: |
Jenny Junior Member |
posted October 31, 2006 06:03
Hi again! I have narrowed it down to just one task and tested it in MPLAB SIM (10 MHz). The problem still exists. 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? I attach the code used in MPLAB SIM: code: [This message has been edited by aek (edited October 31, 2006).] IP: |
Jenny Junior Member |
posted October 27, 2006 07:04
I have tried without optimization, will try to narrow it down to just this task. Thanks! IP: |
aek Moderator |
posted October 27, 2006 00:19
Looking at your latest description, it sounds like there is some effect of your nested functions that is affecting overall timing. Do you have some numbers (in ms) as to how long those delays take? I suspect what is happening is that you have something in that task that is taking much longer than you think -- several ticks worth -- and this is skewing the behavior of OS_Delay(). ------------------ IP: |
aek Moderator |
posted October 27, 2006 00:14
Two things: 1) Have you tried the code with all optimizations disabled? 2) Can you reproduce the problem (maybe a simple applicvation with only this task) in the mPLAB SIM? ------------------ IP: |
Jenny Junior Member |
posted October 26, 2006 22:26
Sorry for being unclear 25' = 25,000 instructions. I was a bit quick when I cut'n pasted the code, of course it should be static, I changed this but the problem still exists. Any ideas? IP: |
aek Moderator |
posted October 26, 2006 09:16
quote:Change it (tmpTimeHigh) to static. The current Salvo port for MCC18 does not support any auto variables in tasks. Note that in your original post all of the task's variables were static, and so I didn't mention this -- thought you knew. ------------------ [This message has been edited by aek (edited October 26, 2006).] IP: |
aek Moderator |
posted October 26, 2006 09:13
quote:25 instructions? Or 25,000 instructions. I.e. what is the rate (measured, with a 'scope) at which you are calling OSTimer()? ------------------ IP: |
Jenny Junior Member |
posted October 26, 2006 01:11
Hello again, Thanks for your quick reply, I've been occupied but looked at your tips yesterday. Code: code:static void TaskBacAlarm(void) [This message has been edited by aek (edited October 26, 2006).] IP: |
aek Moderator |
posted October 19, 2006 09:51
That's odd ... since Salvo's timer accuracy is specified as +/- 1 tick, you should only see "nonexistent" delays if you are doing OS_Delay(1) since 1 (-1) = 0. Any delay argument > 1 should always result in a proper, noticeable delay. I can think of a few things: 1) your tick rate is too fast for your clock, i.e. not enough instructions transpire between calls to OSTimer(). We recommend 2,000-10,000 instruction cycles between calls to OSTimer(). Is it possible some other part of your application is messing with your clock? 2) I would examine the disassembly to ensure that the value=5 parameter is in fact being used in that particular call to OS_Delay(). Occasionally one finds a compiler error. 3) Are you controlling your interrupts (see OSPIC18_INTERRUPT_MASK) properly? If not, you could have an interrupt-based corruption of that parameter or of Salvo itself. 4) Are you _sure_ that the OS_Delay() call is failing, and that it's not something else in overall program flow. The way I would debug this would be to step through the Salvo source (either via a debug-enabled library, or via a source-code build) and verify that a value of 5 is making its way into the function OSDelay(). This would eliminate all the variable issues and point most likely at incorrect use of OSPIC18_INTERRUPT_MASK. The way you're using OS_Delay() is consistent across the calls and I don't see any glaring errors. ------------------ IP: |
Jenny Junior Member |
posted October 19, 2006 08:02
I am using a PIC18F4620 with compiler mcc18 v2.4 and salvo pro v3.2.2, MPLAB v7.31. I have some problems with one OSDelay() call in a task, it seems as though it is just yielding. The OSTimer() is called in an ISR every 10 ms. The other OSDelay:s seems to work fine, the one:s in the same task as well as in the other tasks. The delay I want is 50 ms ( OSDelay(5,Task) ) but when I debug it the execution time often is around 1 ms and the OSTimer() is only called once before it returns to the next instruction in the task. What am I doing wrong? If I change the number of ticks I start to get a delay when tick >40 (40 ms when tick=40, tick=50 -> delay of 160ms). Code: code: [This message has been edited by aek (edited October 19, 2006).] IP: |
All times are ET | next newest topic | next oldest topic |
©2000-2008 Pumpkin, Inc. All Rights Reserved. Pumpkin and the Pumpkin logo, Salvo and the Salvo logo, The RTOS that runs in tiny places, CubeSat Kit and the CubeSat Kit logo are all trademarks of Pumpkin, Inc. All other trademarks are the properties of their respective owners.