[En-Nut-Discussion] NutGetMillis overflow
José Vallet
jose.vallet at hut.fi
Wed Nov 2 11:55:13 CET 2005
Hello Brett, and thanks for the fast answer.
In the file timer.h, where the function NutGetMillis is defined, we can
find the following include
#include <sys/types.h>
From /include/sys/types.h we get:
/*! \brief Unsigned 32-bit value */
typedef unsigned long u_long;
and from stdint.h (avrlibc) we get
typedef unsigned long uint32_t
/** \ingroup avr_stdint
32-bit unsigned type. */
typedef unsigned long uint32_t;
So I think gcc uses also 32 bits, which is 4 bytes.
32 bits count up to 4294967295, yes. The point is that, with a tick rate
of 1024ticks/sec and with 32 bits to count ticks we are able to count a
maximum of 194304 seconds, which is 1165.084 hours, so about 48.5 days,
not 7.9 years as it is suggessted in the comments of the code
(documentation). So either I am missing something or I think that the
comments are wrong and, perhaps, could be changed? (shy suggestion).
Regards
José
Brett Abbott wrote:
> Jose
>
> According to the Imagecraft help page, unsigned long (u_long) is 4
> bytes. I am unsure of whether this is the same in gcc or how consistent
> C compilers are across various platforms. It would be useful to know if
> gcc matches the ICC implementation.
>
> If you use ICCAVR, search on "Data Type Size". Hopefully with
> Imagecraft's permission, I include the help page notes below to allow a
> comparison with gcc.
>
> It's good to see you looking so closely at the code, this will see you
> do well.
> Cheers
> Brett
>
> TYPE SIZE (bytes) RANGE
> unsigned char 1 0..255
> signed char 1 -128..127
> char (*) 1 0..255
> unsigned short 2 0..65535
> (signed) short 2 -32768..32767
> unsigned int 2 0..65535
> (signed) int 2 -32768..32767
> pointer 2 N/A
> unsigned long 4 0..4294967295
> (signed) long 4 -2147483648..2147483647
> float 4 +/-1.175e-38..3.40e+38
> double 4 +/-1.175e-38..3.40e+38
> (*) "char" is equivalent to "unsigned char"
> floats and doubles are in IEEE standard 32-bit format with 8 bit
> exponent, 23-bit mantissa and 1 sign bit.
> Bitfield types must be either signed or unsigned but they will be packed
> into the smallest space. For example:
>
> struct {
>
> unsigned a : 1, b : 1;
>
> };
>
> Size of this structure is only 1 byte. Bitfields are packed right to left.
> José Vallet wrote:
>
>> Hello. First of all, I am novice NUT/OS user, just in case ;-)
>>
>> I need to controll a process on real time, so I need to time-stamp
>> some measurements. A precission of milliseconds seems to be good
>> enough, so the function NutGetMillis suits me. Checking the code I saw
>> that it returns a 32 bits value. However the comments of the function
>> suggest something different. Then, either there are some "mistakes" in
>> the comments or I am missing somethig...
>>
>> In the comments it is suggested that the tick counter overflows every
>> 7.9 years, and I think that that is wrong:
>>
>> the variable nut_ticks is defined as u_long, so 32 bits. Thus it can
>> count up to 4294967296 ticks. With a default tick rate of 1024 tics/s,
>> we can count a maximum of 4294967296/1024=4194304 seconds, which is
>> 1165.084 hours, which is about 48.5 days, not 7.9 years!! This value
>> is important to my application, so it doesn't start to make weird
>> things after 48 days... (now I start to understand the "terrible year
>> 2k effect" ;-))
>>
>> Thus, the upper bound of milliseconds returned by the function is
>> 4194304000 that fits in a 32 bit number. Actually the returned value
>> is a 32 bit value (u_long), not a 64 bit value as the comments suggests.
>>
>> So, now I wonder if I am missing something or is it so that the
>> comment is the result of a copy-paste-remake-and-re-bake and forgot to
>> update? ;-) Look at that scary line with the comment:
>>
>> // carefully stay within 64 bit values
>>
>> I enclose the function in the following lines.
>>
>> Regards.
>> José
>>
>>
>>
>>
>> /*!
>> * \brief Return the milliseconds counter value.
>> *
>> * This function returns the value of a counter, which is incremented
>> * every system timer tick. During system start, the counter is cleared
>> * to zero and will overflow with the 64 bit tick counter (4294967296).
>> * With the default 1024 ticks/s this will happen after 7.9 years.
>> * The resolution is also given by the system ticks.
>> *
>> * \note There is intentionally no provision to modify the seconds
>> counter.
>> * Callers can rely on a continuous update and use this value for
>> * system tick independend timeout calculations.
>> * Depending on
>> *
>> * \return Value of the seconds counter.
>> */
>> u_long NutGetMillis(void)
>> {
>> // carefully stay within 64 bit values
>> u_long ticks = NutGetTickCount();
>> u_long seconds = ticks / NutGetTickClock();
>> ticks -= seconds * NutGetTickClock();
>> return seconds * 1000 + (ticks * 1000 ) / NutGetTickClock();
>> }
>>
>> _______________________________________________
>> En-Nut-Discussion mailing list
>> En-Nut-Discussion at egnite.de
>> http://www.egnite.de/mailman/listinfo.cgi/en-nut-discussion
>>
>>
>
More information about the En-Nut-Discussion
mailing list