Author Topic: fnReduceSWTimers underflow  (Read 31812 times)

Offline Saaac

  • Newbie
  • *
  • Posts: 3
    • View Profile
fnReduceSWTimers underflow
« on: May 23, 2011, 05:46:57 PM »
Hello,

We currently have version V1.3 for coldfire M5223x uTasker.
For some strange reason, the software timers disappear. Following the path I have learned that the error is the "fnReduceSWTimers" causes a subtraction of greater value than the contents of the timer time. This causes an underflow and the timer goes down. Well, actually it is not idle, but will run after more than a year of operation.
This bug I can not specify at all, since I have not been debugging the error. Just left a mark on whether that operation was passing and it seems that it was.

I wonder if someone else has happened and as something fixed.

On the other hand, I see a correction in version V1.4 where it says "Correct Starting a new timer fires an existing Just Before"
I do not know if this arrangement would solve this error. I can not have the code for that correction V1.3 license since I have is not complete.
If this correction solve this problem, we would see how to buy the full license.

I hope I can provide some help on the subject.
Thanks.


Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3244
    • View Profile
    • uTasker
Re: fnReduceSWTimers underflow
« Reply #1 on: May 24, 2011, 01:13:39 AM »
Hi

Here is the full list of modifications in GlobalTimer.c

    18.01.2007 Correct hardware timer check                               {1}
    04.04.2007 Correct start of software timer when hardware time for the same task is active {2}
    03.01.2008 Correct deleted software timer firing early                {3}
    05.03.2008 Add ability to kill all timers belonging to a certain task {4}
    10.04.2008 Correct global HW monostable retrigger                     {5}
    22.10.2010 Correct starting a new timer just before an existing fires {6}
    17.01.2011 Ensure stTimer is zeroed at reset                          {7}


I have also attached the latest versionin case you don't have it. It should still be compatible with V1.3 projects.

The correction number 6 was due to the fact that adding a new timer - depending on when it was added and whether its value was greater or less that the next one(s) to fire (I don't remember exactly which combination) - could cause another timer to fire too early. A case of a timer being set negative hasn't been observed but maybe this was a consequence of that error (?).

Since the change number 6 there have not been any other reoprts of problems and also reference projects which have been using the timers heavily have not encountered difficulties. However, this doesn't mean that there isn't something that could still go wrong; it just hasn't been identified.

I suggest that you try the latest version in your project. It may prove to solve the difficulty. If not, it would be interesting to see exactly how you are using them. Also, is it possible that you are starting a timer from an interrupt which is causing an unprotected SW timer routine to be disturbed? (routines that could be disturbed should be protected already but this is an area which is a little more difficult to analyse and so there may still be something that needs additional protection(?)).

Regards

Mark

Offline Saaac

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: fnReduceSWTimers underflow
« Reply #2 on: May 24, 2011, 05:18:58 PM »
Hi Mark:

I'm still in search of error discussed.

However, I fail to understand the following operation: ???

UTASK_TICK RemainingTime = TimeStamp + NextFire; 
        if (RemainingTime >= uTaskerSystemTick) {
            RemainingTime -= uTaskerSystemTick;
        }
        else {
            RemainingTime = uTaskerSystemTick - RemainingTime;
        }

I think I always have to subtract the value of uTaskerSystemtick because:

uTaskerSystemTick = 0xFFFFFFFF
TimeStamp = 0xFFFFFFFE
NextFire = 0x0004

Result according to the formula of the program is 0xFFFFFFFA when it should be 3  :o .

Am I wrong?

I think this "possible error" is not what is happening to me because being the variables of type long, have to spend almost 500 days to do this subtraction. I have a 10 ms tick resolution.

Thanks.

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3244
    • View Profile
    • uTasker
Re: fnReduceSWTimers underflow
« Reply #3 on: May 24, 2011, 10:28:57 PM »
Hi

I have just spend some time testing the routines and have made a development version with some optimisations. There were three things that I didn't like:

1) When using the TICK for calculations there is a risk that the TICK increments (since it is an interrupt). This may result in an inaccuracy of 1 tick resulting, and possibly cause a calculation to result in -1 rather than 0 (thinking about your actual problem). Therefore I added a small region of code which disables interrupts and so ensures that this can not happen. Normally it is expected that there is a +0..+1 range for this time of timer accuracy when the routine is not synchronised to the TICK and so this is generally not a problem but may be a potential risk in a certain situation.

2) Related to the first point, I was worried that a timer could have fired and the global timer task be called with a delay of a TICK period. In this case a calcualation of a next setting may use a TICK value which is incorrect and so cause inaccuracy or possibly a negative value. Instead of using TICK directly I have instead used the routine uTaskerRemainingTime(). This will give a value of 0 back if a timer has expired, removing a potential risk. This routine is in uTasker.c since 30.05.2009 - you can add it to your file if needed.

3) CLOCK_LIMIT was used to define the longest timer delay. I have replaced this with DELAY_LIMIT. I am worried that there may be a combination of types that could be risky. The TICK counter uses UTASK_TICK (counter width) and the monostable timer routines use DELAY_LIMIT (longest delay). Of course DELAY_LIMIT should not be wider than UTASK_TICK but it doesn't seem to make sense using a further type since it really should match with UTASK_TICK any way.

[I think that CLOCK_LIMIT was origianlly intended for HW timers, which are presently not recommended]

Furthermore make sure that uTaskerGlobalMonoTimer() and uTaskerGlobalStopTimer() are not used from interrupt routines. I have seen that the general code is not protected from interrupts and there is a risk that something will get corrupted (this could certainly result in timers getting set with corrupted values - as you have seen in your case a small count offset changing a value from small positive to small negative results in a timer with very large count). It would otherwise be necessary to protect large code areas; since the timers are software timers (low resolution in comparison with HW timer interrup interface) I would prefer such a restriction since I don't think that it is a problem.


Note that, to conclude, fnReduceSWTimers() is used to adjust waiting timer values when a new timer (with lower timeout value that present one) is to be added, or when preparing a following timer. For it to be exact it may not make mistakes in elapsed time calculations since then an adjustment could potentially cause a timer to be adjusted incorrectly to a slightly negative value (result is large positive rather than a slight inaccuracy); these types of risk are what I was tring to exclude with the rework as noted above. This version is attached - as long as uTaskerRemainingTime() is present it should be fully compatible; I didn't see any more potential risk areas (apart from use from interrupts) and I hope that this may help you solve your problem (main change in fnStartNewTimer()).
I will continue using this version in the hope that it can be introduced as soon as possible.

Regards

Mark



Offline Saaac

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: fnReduceSWTimers underflow
« Reply #4 on: May 26, 2011, 02:39:05 PM »
Hi Mark:

I think I found the problem. Instead, you find the problem.
I have a timer in an interrupt. I did not know it was 'illegal'.
I could provoke the error after causing multiple interrupts per second.
attached Excel with the data of what has happened, if someone wants to see the event with all the data.

I modified the software so that now the timer is out of the interruption. The error has not yet appeared.

It is a bug so hard to find (I have pretty long behind him) I think it's a good idea to update the documentation of the use of timers as not to be used in interruptions. I've been searching and have not seen any note.

Thank you for everything.

A greeting.