Pumpkin, Inc.

Pumpkin User Forums

PIC18 OS_Delay() time...

For issues specific to Microchip's PICmicro® MCUs, including compilers (e.g. HI-TECH PICC & PICC-18, Microchip MPLAB®-C18) and IDEs (e.g. Microchip MPLAB®).

PIC18 OS_Delay() time...

Postby jal » Thu Feb 14, 2008 1:00 am

I have an 10ms ISR calling OSTimer() and OSSched() called from main loop. One of my tasks does OS_Delay(100,xxx) and inside this task I keep track of a 32 bit elapsed seconds counter. I have verified w/ scope that my CPU Fosc is correct (20MHz) but when compared with an accurate external timing device, it appears that my internal seconds counter runs about 5% to fast.

One of my other tasks does occasionally take a few hundred ms to run so OSSched() does not get called after every OSTimer(). From reading on these forums, I would have expected that this would be OK due to Salvo keeping track of the OSLostTicks.

Is there any Salvo related feature that might be causing the OS_Delay(100,xxx) to not deliver the expected delays? I dont really care if each delay is exact....only that the average cycle time for the task (over 100's hrs) is 1 second.

Thanks,
Jim

jal
 
Posts: 9
Joined: Thu Feb 14, 2008 12:00 am

Re: PIC18 OS_Delay() time...

Postby jal » Thu Feb 14, 2008 6:11 am

Thanks for this informative response. I take your points and provide additional information as follows....

1. I was worried about using OS_DelayTS() because of the manual page clause about undefined behavior if you are more than 2x behind! If the TS counter is really 32 bit in the freelib versions of Salvo then I would be less concerned.

2. Have measured w/ a scope the 10ms interrupt timing and it is within 1/2% of target value. Have also measured the software timer period. Looks like the interval is 1.010 to 1.015 sec and it always runs a tad long..never short.

3. Your idea of using Salvo's native tick count might be workable. There are a couple of complication to doing so such as needing to keep a current copy in a non-volatile ram and to restore this value on the next power up.

4. Will try the OS_DelayTS() approach to see if there is any difference. Is it correct that OS_BYTES_OF_TICKS is 4 in the free library versions?

5. The other suggestions depend I think on having a source release of Salvo and I do not yet have this!

Thanks
Jim

jal
 
Posts: 9
Joined: Thu Feb 14, 2008 12:00 am

Re: PIC18 OS_Delay() time...

Postby aek » Thu Feb 14, 2008 6:32 am

A couple of things:

A) You mention you don't have Salvo Pro ... this means that Salvo is disabling both GIEL and GIEH during critical sections (this is the default in the libraries and can only be overridden with Salvo Pro). This in turn means that you cannot configure your system to avoid potentially long periods of interrupts being globally disabled (e.g. if you have lots of tasks and the lowest-priority task times out and the scheduler needs to make it eligible again). So, long-term, you may still have a (barely visible) problem with your ISR. Admittedly this is pretty unlikely because your ticks are 10ms and your clock is 20MHz, therefore you have 50,000 CPU cycles per tick (which is plenty).I say this simply because over long-time tests the Salvo timer is good to +/- 1 tick type of accuracy. Please see page 420 (468) of the new Salvo 4 user manual http://www.pumpkininc.com/content/doc/manual/SalvoUserManual.pdf for a discussion of how to completely eliminate this issue (a potential for ISRs to have jitter).

I would suggest comparing OStimerTicks to the effective number of ticks you should have in your OS_Delay(100,xxx) task ... if they're essentially equal, then the problem is with the calling of OSTimer(). If there's a 5% difference, then OS_DelayTS() is probably required.

3) OSSetTicks() and OSGetTicks() will allow you to override the value from Flash, etc.

4) Yes.

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

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

Re: PIC18 OS_Delay() time...

Postby aek » Thu Feb 14, 2008 6:34 am

Oh, one more thing ... this kind of thing lends itself very well to simulation in MPLAB ... you should be able to strip out all I/O operations and create a project that just runs the tasks with their (yieldin and non-yielding) delays. Then using the StopWatch, you should be able to confirm the behavior. At that point, we can look at the project in MPLAB + MPLAB-SIM.

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

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

Re: PIC18 OS_Delay() time...

Postby jal » Thu Feb 14, 2008 6:42 am

Good points. The MPLAB-SIM approach would take a LOT of stripping since the code depends on stuff like the extenal nvram! Still would be worthwhile excercise.

I think the interrupt disable stuff is not likely and issue since I have only one interrupt source enabled (ie the timer). There is a serial port as well actually but it is not used at all.

For me, the real head scratcher is that the software timer runs fast compared to the "gold standard" external hourmeter. I can think of all sorts of reasons why the software timer would be too slow (ie lost irqs, task latency, not using OS_DelayTS()) but not many to explain why sw timer would run fast!

jal
 
Posts: 9
Joined: Thu Feb 14, 2008 12:00 am

Re: PIC18 OS_Delay() time...

Postby aek » Thu Feb 14, 2008 7:09 am

OSlostTicks is 8 bits, so if you are exceeding 8 bits of delays while holding off OSSched() anywhere, then relative time (via OS_Delay() will be in error. Absolute time (via the ticks services) will always be correct as long as no ISRs (to call OSTimer()) are missed.

Keep in mind that Salvo's timer has an unherent (in)accuracy of +/- 1 tick.

I assume you are using a += nudge style of updating your timer, which will maintain accurate time as long as you never miss an ISR (which is diferent from holding of OSSched() for more than one tick, which is what your long task is doing). IOW, for the purpose of this discussion, I assume your ISR is showing accuracy of well under 5%.

However, your decription (one long task that does not block OSSched() for more than 8 bits of lost ticks) suggests that the lost tick function is not the root cause.

Note also that ticks (not the same as delays) are by default 32 bits, and are readable and writeable (e.g. via OSSetTicks()), so you don't have to maintain your own seconds counter -- just use Salvo's.

All this said, I think what you want is to use OS_DelayTS(), etc. These delays have long-term zero jitter, instead of OS_Delay(), etc., which is affected by short-term jitter.

So, to debug this, I would:

1) Use an accurate external timer to ensure that OSTimer() is called at the ISR without any error (ever).

2) Use Salvo's native ticks feature (and leave OSBYTES_OF_TICKS set to 4).

3) Use OS_DelayTS() and compare the results against using OS_Delay().

4) Do some long-term checks of the vaue of OStimerTicks. It should always be accurate, since it is updated in OSTimer(), not OSSched(). If it's not accurate, then that points to a problem with the rate at which OSTimer() (and hence its paret ISR) are called.

5) Using a Pro build, do a trap in timer.c on whether OSlostTicks ever rails at 255.

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

[This message has been edited by aek (edited February 14, 2008).]

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

Re: PIC18 OS_Delay() time...

Postby jal » Tue Feb 19, 2008 5:25 am

I have done some further comparison of the PIC/Salvo based timers w/ an external PC timer and find that they differ by less than 1%. At this point, I have no reason to suspect that anything about Salvo is causing timing errors.

I did try OS_DelayTS() vs OS_Delay() and as expected there is a small improvement in timing accuracy when using the TS version.

Since the errors noted in the field are greater than 5% it would appear I need to look elsewhere for the problem!

Cheers,
Jim

jal
 
Posts: 9
Joined: Thu Feb 14, 2008 12:00 am

Re: PIC18 OS_Delay() time...

Postby aek » Thu Feb 21, 2008 9:33 am

Thanks for the update.

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

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


Return to PICmicro MCUs

Who is online

Users browsing this forum: No registered users and 2 guests

cron