Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.arch.embedded > #32348 > unrolled thread

32 bits time_t and Y2038 issue

Started bypozz <pozzugno@gmail.com>
First post2025-03-11 16:22 +0100
Last post2025-03-18 18:44 +0000
Articles 20 on this page of 55 — 6 participants

Back to article view | Back to comp.arch.embedded


Contents

  32 bits time_t and Y2038 issue pozz <pozzugno@gmail.com> - 2025-03-11 16:22 +0100
    Re: 32 bits time_t and Y2038 issue David Brown <david.brown@hesbynett.no> - 2025-03-11 17:32 +0100
      Re: 32 bits time_t and Y2038 issue pozz <pozzugno@gmail.com> - 2025-03-11 23:21 +0100
        Re: 32 bits time_t and Y2038 issue David Brown <david.brown@hesbynett.no> - 2025-03-12 10:33 +0100
          Re: 32 bits time_t and Y2038 issue pozz <pozzugno@gmail.com> - 2025-03-12 16:48 +0100
            Re: 32 bits time_t and Y2038 issue David Brown <david.brown@hesbynett.no> - 2025-03-12 17:39 +0100
              Re: 32 bits time_t and Y2038 issue pozz <pozzugno@gmail.com> - 2025-03-12 18:13 +0100
                Re: 32 bits time_t and Y2038 issue David Brown <david.brown@hesbynett.no> - 2025-03-12 19:18 +0100
                  Re: 32 bits time_t and Y2038 issue pozz <pozzugno@gmail.com> - 2025-03-13 09:57 +0100
                    Re: 32 bits time_t and Y2038 issue David Brown <david.brown@hesbynett.no> - 2025-03-13 16:51 +0100
                      Re: 32 bits time_t and Y2038 issue pozz <pozzugno@gmail.com> - 2025-03-14 13:27 +0100
                        Re: 32 bits time_t and Y2038 issue David Brown <david.brown@hesbynett.no> - 2025-03-14 14:20 +0100
      Re: 32 bits time_t and Y2038 issue pozz <pozzugno@gmail.com> - 2025-03-12 08:44 +0100
        Re: 32 bits time_t and Y2038 issue David Brown <david.brown@hesbynett.no> - 2025-03-12 11:14 +0100
        Re: 32 bits time_t and Y2038 issue antispam@fricas.org (Waldek Hebisch) - 2025-03-14 01:48 +0000
          Re: 32 bits time_t and Y2038 issue pozz <pozzugno@gmail.com> - 2025-03-14 08:36 +0100
      Re: 32 bits time_t and Y2038 issue Michael Schwingen <news-1513678000@discworld.dascon.de> - 2025-03-15 16:30 +0000
        Re: 32 bits time_t and Y2038 issue Grant Edwards <invalid@invalid.invalid> - 2025-03-15 17:02 +0000
          Re: 32 bits time_t and Y2038 issue Michael Schwingen <news-1513678000@discworld.dascon.de> - 2025-03-15 23:26 +0000
        Re: 32 bits time_t and Y2038 issue pozz <pozzugno@gmail.com> - 2025-03-18 09:21 +0100
          Re: 32 bits time_t and Y2038 issue David Brown <david.brown@hesbynett.no> - 2025-03-18 11:34 +0100
            Re: 32 bits time_t and Y2038 issue pozz <pozzugno@gmail.com> - 2025-03-18 17:31 +0100
              Re: 32 bits time_t and Y2038 issue David Brown <david.brown@hesbynett.no> - 2025-03-18 20:29 +0100
                Re: 32 bits time_t and Y2038 issue Michael Schwingen <news-1513678000@discworld.dascon.de> - 2025-03-21 09:20 +0000
                  Re: 32 bits time_t and Y2038 issue David Brown <david.brown@hesbynett.no> - 2025-03-21 13:54 +0100
                    Re: 32 bits time_t and Y2038 issue Michael Schwingen <news-1513678000@discworld.dascon.de> - 2025-03-21 20:53 +0000
                      Re: 32 bits time_t and Y2038 issue David Brown <david.brown@hesbynett.no> - 2025-03-22 11:19 +0100
                  Re: 32 bits time_t and Y2038 issue antispam@fricas.org (Waldek Hebisch) - 2025-03-21 14:35 +0000
            Re: 32 bits time_t and Y2038 issue Michael Schwingen <news-1513678000@discworld.dascon.de> - 2025-03-18 18:28 +0000
              Re: 32 bits time_t and Y2038 issue David Brown <david.brown@hesbynett.no> - 2025-03-18 20:43 +0100
                Re: 32 bits time_t and Y2038 issue Grant Edwards <invalid@invalid.invalid> - 2025-03-18 20:58 +0000
                  Re: 32 bits time_t and Y2038 issue Hans-Bernhard Bröker <HBBroeker@gmail.com> - 2025-03-18 23:31 +0100
                    Re: 32 bits time_t and Y2038 issue David Brown <david.brown@hesbynett.no> - 2025-03-19 11:24 +0100
                      Re: 32 bits time_t and Y2038 issue Grant Edwards <invalid@invalid.invalid> - 2025-03-19 14:27 +0000
                        Re: 32 bits time_t and Y2038 issue David Brown <david.brown@hesbynett.no> - 2025-03-19 17:33 +0100
                          Re: 32 bits time_t and Y2038 issue Grant Edwards <invalid@invalid.invalid> - 2025-03-19 19:08 +0000
                            Re: 32 bits time_t and Y2038 issue David Brown <david.brown@hesbynett.no> - 2025-03-19 21:14 +0100
                              Re: 32 bits time_t and Y2038 issue Michael Schwingen <news-1513678000@discworld.dascon.de> - 2025-03-21 09:48 +0000
                                Re: 32 bits time_t and Y2038 issue Grant Edwards <invalid@invalid.invalid> - 2025-03-21 13:27 +0000
                          Re: 32 bits time_t and Y2038 issue antispam@fricas.org (Waldek Hebisch) - 2025-03-19 22:09 +0000
                            Re: 32 bits time_t and Y2038 issue David Brown <david.brown@hesbynett.no> - 2025-03-20 09:26 +0100
                              Re: 32 bits time_t and Y2038 issue pozz <pozzugno@gmail.com> - 2025-03-21 22:40 +0100
                    Re: 32 bits time_t and Y2038 issue Michael Schwingen <news-1513678000@discworld.dascon.de> - 2025-03-21 09:23 +0000
                      Re: 32 bits time_t and Y2038 issue Hans-Bernhard Bröker <HBBroeker@gmail.com> - 2025-03-21 22:38 +0100
                  Re: 32 bits time_t and Y2038 issue David Brown <david.brown@hesbynett.no> - 2025-03-19 08:24 +0100
                Re: 32 bits time_t and Y2038 issue antispam@fricas.org (Waldek Hebisch) - 2025-03-21 14:04 +0000
                  Re: 32 bits time_t and Y2038 issue David Brown <david.brown@hesbynett.no> - 2025-03-21 16:45 +0100
                    Re: 32 bits time_t and Y2038 issue pozz <pozzugno@gmail.com> - 2025-03-21 22:51 +0100
                    Re: 32 bits time_t and Y2038 issue Hans-Bernhard Bröker <HBBroeker@gmail.com> - 2025-03-22 00:00 +0100
                      Re: 32 bits time_t and Y2038 issue David Brown <david.brown@hesbynett.no> - 2025-03-22 14:29 +0100
                        Re: 32 bits time_t and Y2038 issue Michael Schwingen <news-1513678000@discworld.dascon.de> - 2025-03-22 14:46 +0000
                          Re: 32 bits time_t and Y2038 issue David Brown <david.brown@hesbynett.no> - 2025-03-22 17:57 +0100
                    Re: 32 bits time_t and Y2038 issue antispam@fricas.org (Waldek Hebisch) - 2025-03-22 15:57 +0000
                      Re: 32 bits time_t and Y2038 issue David Brown <david.brown@hesbynett.no> - 2025-03-22 18:02 +0100
          Re: 32 bits time_t and Y2038 issue Michael Schwingen <news-1513678000@discworld.dascon.de> - 2025-03-18 18:44 +0000

Page 1 of 3  [1] 2 3  Next page →


#32348 — 32 bits time_t and Y2038 issue

Frompozz <pozzugno@gmail.com>
Date2025-03-11 16:22 +0100
Subject32 bits time_t and Y2038 issue
Message-ID<vqpkf9$1sbsa$1@dont-email.me>
I have an embedded project that is compiled in Atmel Studio 7.0. The 
target is and ARM MCU, so the toolchain is arm-gnu-toolchain. The 
installed toolchain version is 6.3.1.508. newlib version is 2.5.0.

In this build system the type time_t is defined as long, so 32 bits.

I'm using time_t mainly to show it on a display for the user (as a 
broken down time) and tag with a timestamp some events (that the user 
will see as broken down time).

The time can be received by Internet or by the user, if the device is 
not connected. In both cases, time_t is finally used.

As you know, my system will show the Y2038 issue. I don't know if some 
of my devices will be active in 2038, anyway I'd like to fix this 
potential issue now.

One possibility is to use a modern toolchain[1] that most probably uses 
a new version of newlib that manages 64 bits time_t. However I think I 
should address several warnings and other problems after upgrading the 
toolchain.

Another possibility is to rewrite my own my_mktime(), my_localtime() and 
so on that accepts and returns my_time_t variables, defined as 64 bits. 
However I'm not capable in writing such functions. Do you have some 
implementations? I don't need full functional time functions, for 
example the timezone can be fixed at build time, I don't need to set it 
at runtime.

Any suggestions?


[1] 
https://developer.arm.com/-/media/Files/downloads/gnu/14.2.rel1/binrel/arm-gnu-toolchain-14.2.rel1-mingw-w64-i686-arm-none-eabi.zip

[toc] | [next] | [standalone]


#32349

FromDavid Brown <david.brown@hesbynett.no>
Date2025-03-11 17:32 +0100
Message-ID<vqpoi3$226ih$1@dont-email.me>
In reply to#32348
On 11/03/2025 16:22, pozz wrote:
> I have an embedded project that is compiled in Atmel Studio 7.0. The 
> target is and ARM MCU, so the toolchain is arm-gnu-toolchain. The 
> installed toolchain version is 6.3.1.508. newlib version is 2.5.0.
> 

I /seriously/ dislike Microchip's way of handling toolchains.  They work 
with old, outdated versions, rename and rebrand them and their 
documentation to make it look like they wrote them themselves, then add 
license checks and software locks so that optimisation is disabled 
unless you pay them vast amounts of money for the software other people 
wrote and gave away freely.  To my knowledge, they do not break the 
letter of the license for GCC and other tools and libraries, but they 
most certainly break the spirit of the licenses in every way imaginable.

Prior to being bought by Microchip, Atmel was bad - but not as bad.

So if for some reason I have no choice but to use a device from Atmel / 
Microchip, I do so using tools from elsewhere.

As a general rule, the gcc-based toolchains from ARM are the industry 
standard, and are used as the base by most ARM microcontroller 
suppliers.  Some include additional library options, others provide the 
package as-is.  For anything other than a quick demo, my preferred setup 
is using makefiles for the build along with an ARM gcc toolchain.  That 
way I can always build my software, from any system, and archive the 
toolchain.  (One day, I will also try using clang with these packages, 
but I haven't done so yet.)

Any reasonably modern ARM gcc toolchain will have 64-bit time_t.  I 
never like changing toolchains on an existing project, but you might 
make an exception here.

However, writing functions to support time conversions is not difficult. 
  The trick is not to start at 01.01.1970, but start at a convenient 
date as early as you will need to handle - 01.01.2025 would seem a 
logical point.  Use <https://www.unixtimestamp.com/> to get the time_t 
constant for the start of your epoch.

To turn the current time_t value into a human-readable time and date, 
first take the current time_t and subtract the epoch start.  Divide by 
365 * 24 * 60 * 60 to get the additional years.  Divide the leftovers by 
24 * 60 * 60 to get the additional days.  Use a table of days in the 
months to figure out the month.  Leap year handling is left as an 
exercise for the reader (hint - 2100, 2200 and 2300 are not leap years, 
while 2400 is).  Use the website I linked to check your results.

Or you can get the sources for a modern version of newlib, and pull the 
routines from there.


David


> In this build system the type time_t is defined as long, so 32 bits.
> 
> I'm using time_t mainly to show it on a display for the user (as a 
> broken down time) and tag with a timestamp some events (that the user 
> will see as broken down time).
> 
> The time can be received by Internet or by the user, if the device is 
> not connected. In both cases, time_t is finally used.
> 
> As you know, my system will show the Y2038 issue. I don't know if some 
> of my devices will be active in 2038, anyway I'd like to fix this 
> potential issue now.
> 
> One possibility is to use a modern toolchain[1] that most probably uses 
> a new version of newlib that manages 64 bits time_t. However I think I 
> should address several warnings and other problems after upgrading the 
> toolchain.
> 
> Another possibility is to rewrite my own my_mktime(), my_localtime() and 
> so on that accepts and returns my_time_t variables, defined as 64 bits. 
> However I'm not capable in writing such functions. Do you have some 
> implementations? I don't need full functional time functions, for 
> example the timezone can be fixed at build time, I don't need to set it 
> at runtime.
> 
> Any suggestions?
> 
> 
> [1] 
> https://developer.arm.com/-/media/Files/downloads/gnu/14.2.rel1/binrel/arm-gnu-toolchain-14.2.rel1-mingw-w64-i686-arm-none-eabi.zip

[toc] | [prev] | [next] | [standalone]


#32350

Frompozz <pozzugno@gmail.com>
Date2025-03-11 23:21 +0100
Message-ID<vqqd1l$26qs8$1@dont-email.me>
In reply to#32349
Il 11/03/2025 17:32, David Brown ha scritto:
> On 11/03/2025 16:22, pozz wrote:
>> I have an embedded project that is compiled in Atmel Studio 7.0. The 
>> target is and ARM MCU, so the toolchain is arm-gnu-toolchain. The 
>> installed toolchain version is 6.3.1.508. newlib version is 2.5.0.
>>
> 
> I /seriously/ dislike Microchip's way of handling toolchains.  They work 
> with old, outdated versions, rename and rebrand them and their 
> documentation to make it look like they wrote them themselves, then add 
> license checks and software locks so that optimisation is disabled 
> unless you pay them vast amounts of money for the software other people 
> wrote and gave away freely.  To my knowledge, they do not break the 
> letter of the license for GCC and other tools and libraries, but they 
> most certainly break the spirit of the licenses in every way imaginable.

Maybe you are thinking about Microchip IDE named MPLAB X or something 
similar. I read something about disabled optimizations in the free 
version of the toolchain.

However I'm using *Atmel Studio* IDE, that is an old IDE distributed by 
Atmel, before the Microchip purchase. The documentation speaks about 
some Atmel customization of ARM gcc toolchain, but it clearly specified 
the toolchain is an arm gcc.


> Prior to being bought by Microchip, Atmel was bad - but not as bad.

Why do you think Atmel was bad? I think they had good products.


> So if for some reason I have no choice but to use a device from Atmel / 
> Microchip, I do so using tools from elsewhere.
> 
> As a general rule, the gcc-based toolchains from ARM are the industry 
> standard, and are used as the base by most ARM microcontroller 
> suppliers.  Some include additional library options, others provide the 
> package as-is.  For anything other than a quick demo, my preferred setup 
> is using makefiles for the build along with an ARM gcc toolchain.  That 
> way I can always build my software, from any system, and archive the 
> toolchain.  (One day, I will also try using clang with these packages, 
> but I haven't done so yet.)

Yes, you're right, but now it's too late to change the toolchain.


> Any reasonably modern ARM gcc toolchain will have 64-bit time_t.  I 
> never like changing toolchains on an existing project, but you might 
> make an exception here.

I will check.


> However, writing functions to support time conversions is not difficult. 
>   The trick is not to start at 01.01.1970, but start at a convenient 
> date as early as you will need to handle - 01.01.2025 would seem a 
> logical point.  Use <https://www.unixtimestamp.com/> to get the time_t 
> constant for the start of your epoch.
> 
> To turn the current time_t value into a human-readable time and date, 
> first take the current time_t and subtract the epoch start.  Divide by 
> 365 * 24 * 60 * 60 to get the additional years.  Divide the leftovers by 
> 24 * 60 * 60 to get the additional days.  Use a table of days in the 
> months to figure out the month.  Leap year handling is left as an 
> exercise for the reader (hint - 2100, 2200 and 2300 are not leap years, 
> while 2400 is).  Use the website I linked to check your results.

If I had to rewrite my own functions, I could define time64_t as 
uint64_t, keeping the Unix epoch as my epoch.

Regarding implementation, I don't know if it so simple. mktime() fix the 
members of struct tm passed as an argument (and this is useful to 
calculate the day of the week). Moreover I don't only need the 
conversion from time64_t to struct tm, but viceversa too.

> 
> Or you can get the sources for a modern version of newlib, and pull the 
> routines from there.

It's a very complex code. time functions are written for whatever 
timezone is set at runtime (TZ env variable), so their complexity are 
higher.

> 
> 
> David
> 
> 
>> In this build system the type time_t is defined as long, so 32 bits.
>>
>> I'm using time_t mainly to show it on a display for the user (as a 
>> broken down time) and tag with a timestamp some events (that the user 
>> will see as broken down time).
>>
>> The time can be received by Internet or by the user, if the device is 
>> not connected. In both cases, time_t is finally used.
>>
>> As you know, my system will show the Y2038 issue. I don't know if some 
>> of my devices will be active in 2038, anyway I'd like to fix this 
>> potential issue now.
>>
>> One possibility is to use a modern toolchain[1] that most probably 
>> uses a new version of newlib that manages 64 bits time_t. However I 
>> think I should address several warnings and other problems after 
>> upgrading the toolchain.
>>
>> Another possibility is to rewrite my own my_mktime(), my_localtime() 
>> and so on that accepts and returns my_time_t variables, defined as 64 
>> bits. However I'm not capable in writing such functions. Do you have 
>> some implementations? I don't need full functional time functions, for 
>> example the timezone can be fixed at build time, I don't need to set 
>> it at runtime.
>>
>> Any suggestions?
>>
>>
>> [1] https://developer.arm.com/-/media/Files/downloads/gnu/14.2.rel1/ 
>> binrel/arm-gnu-toolchain-14.2.rel1-mingw-w64-i686-arm-none-eabi.zip
> 

[toc] | [prev] | [next] | [standalone]


#32352

FromDavid Brown <david.brown@hesbynett.no>
Date2025-03-12 10:33 +0100
Message-ID<vqrkd5$2hnm3$1@dont-email.me>
In reply to#32350
On 11/03/2025 23:21, pozz wrote:
> Il 11/03/2025 17:32, David Brown ha scritto:
>> On 11/03/2025 16:22, pozz wrote:
>>> I have an embedded project that is compiled in Atmel Studio 7.0. The 
>>> target is and ARM MCU, so the toolchain is arm-gnu-toolchain. The 
>>> installed toolchain version is 6.3.1.508. newlib version is 2.5.0.
>>>
>>
>> I /seriously/ dislike Microchip's way of handling toolchains.  They 
>> work with old, outdated versions, rename and rebrand them and their 
>> documentation to make it look like they wrote them themselves, then 
>> add license checks and software locks so that optimisation is disabled 
>> unless you pay them vast amounts of money for the software other 
>> people wrote and gave away freely.  To my knowledge, they do not break 
>> the letter of the license for GCC and other tools and libraries, but 
>> they most certainly break the spirit of the licenses in every way 
>> imaginable.
> 
> Maybe you are thinking about Microchip IDE named MPLAB X or something 
> similar. I read something about disabled optimizations in the free 
> version of the toolchain.
> 

I believe it applies to all of Microchip's toolchains - and that now 
includes those for the Atmel devices it acquired.

> However I'm using *Atmel Studio* IDE, that is an old IDE distributed by 
> Atmel, before the Microchip purchase. The documentation speaks about 
> some Atmel customization of ARM gcc toolchain, but it clearly specified 
> the toolchain is an arm gcc.

OK.

> 
> 
>> Prior to being bought by Microchip, Atmel was bad - but not as bad.
> 
> Why do you think Atmel was bad? I think they had good products.

It is not the products that I am talking about.  I've always like the 
AVR architecture (though it could have been massively better with a few 
small changes).  Though I haven't used their ARM devices myself, I have 
heard nice things about them.  I am talking about the toolchains.

They had a very mixed attitude to open source software.  For a long 
time, they dismissed GCC completely, and gave no help or information for 
other parts of the ecosystem (debuggers, programmers, etc.).  Eventually 
they realised that there was a substantial customer base who did not 
want to pay huge prices for IAR toolchains, or preferred open-source 
toolchains for other reasons, and they made various half-hearted efforts 
to support GCC for the AVR.  Basically, they did enough to be able to 
have a working setup that they could provide it for free, but not enough 
to make it efficient.  I think they spent more money on rebranding GCC 
for the AVR and ARM than they did on technically improving them.  People 
looking for AVR GCC toolchains were left with no idea what version of 
GCC they can get from Atmel, or how those builds compare with mainline 
GCC versions, what devices they support, or how the various required 
extensions are handled.  Their ARM toolchains were a bit more standard, 
and a bit less obfuscated in their branding and versioning.

So not as bad as Microchip, but still far from good.

> 
> 
>> So if for some reason I have no choice but to use a device from Atmel 
>> / Microchip, I do so using tools from elsewhere.
>>
>> As a general rule, the gcc-based toolchains from ARM are the industry 
>> standard, and are used as the base by most ARM microcontroller 
>> suppliers.  Some include additional library options, others provide 
>> the package as-is.  For anything other than a quick demo, my preferred 
>> setup is using makefiles for the build along with an ARM gcc 
>> toolchain.  That way I can always build my software, from any system, 
>> and archive the toolchain.  (One day, I will also try using clang with 
>> these packages, but I haven't done so yet.)
> 
> Yes, you're right, but now it's too late to change the toolchain.
> 
> 
>> Any reasonably modern ARM gcc toolchain will have 64-bit time_t.  I 
>> never like changing toolchains on an existing project, but you might 
>> make an exception here.
> 
> I will check.
> 
> 
>> However, writing functions to support time conversions is not 
>> difficult.   The trick is not to start at 01.01.1970, but start at a 
>> convenient date as early as you will need to handle - 01.01.2025 would 
>> seem a logical point.  Use <https://www.unixtimestamp.com/> to get the 
>> time_t constant for the start of your epoch.
>>
>> To turn the current time_t value into a human-readable time and date, 
>> first take the current time_t and subtract the epoch start.  Divide by 
>> 365 * 24 * 60 * 60 to get the additional years.  Divide the leftovers 
>> by 24 * 60 * 60 to get the additional days.  Use a table of days in 
>> the months to figure out the month.  Leap year handling is left as an 
>> exercise for the reader (hint - 2100, 2200 and 2300 are not leap 
>> years, while 2400 is).  Use the website I linked to check your results.
> 
> If I had to rewrite my own functions, I could define time64_t as 
> uint64_t, keeping the Unix epoch as my epoch.
> 
> Regarding implementation, I don't know if it so simple. mktime() fix the 
> members of struct tm passed as an argument (and this is useful to 
> calculate the day of the week). Moreover I don't only need the 
> conversion from time64_t to struct tm, but viceversa too.
> 

Day of week calculations are peanuts - divide the seconds count by the 
number of seconds in a day, add a constant value for whatever day 
01.01.1970 was, and reduce modulo 7.

Most of the effort for converting a struct tm into a time_t is checking 
that the values make sense.

For all of this, the big question is /why/ you are doing it.  What are 
you doing with your times?  Where are you getting them?  Are you 
actually doing this in a sensible way because they suit your 
application, or are you just using these types and structures because 
they are part of the standard C library - which is not good enough for 
your needs here?

Maybe you are going about it all the wrong way.  If you need to be able 
to display and set the current time and date, and to be able to 
conveniently measure time differences for alarms, repetitive tasks, 
etc., then you probably don't need any correlation between your 
monotonic seconds counter and your time/date tracker.  All you need to 
do is add one second to each, every second.  I don't know the details of 
your application (obviously), but often no conversion is needed either way.

>>
>> Or you can get the sources for a modern version of newlib, and pull 
>> the routines from there.
> 
> It's a very complex code. time functions are written for whatever 
> timezone is set at runtime (TZ env variable), so their complexity are 
> higher.
> 

So find a simpler standard C library implementation.  Try the avrlibc, 
for example.

But I have no doubt at all that you can make all this yourself easily 
enough.

[toc] | [prev] | [next] | [standalone]


#32354

Frompozz <pozzugno@gmail.com>
Date2025-03-12 16:48 +0100
Message-ID<vqsacn$2g8c7$1@dont-email.me>
In reply to#32352
Il 12/03/2025 10:33, David Brown ha scritto:
> On 11/03/2025 23:21, pozz wrote:
>> Il 11/03/2025 17:32, David Brown ha scritto:
>>> On 11/03/2025 16:22, pozz wrote:
>>>> I have an embedded project that is compiled in Atmel Studio 7.0. The 
>>>> target is and ARM MCU, so the toolchain is arm-gnu-toolchain. The 
>>>> installed toolchain version is 6.3.1.508. newlib version is 2.5.0.
>>>>
>>>
>>> I /seriously/ dislike Microchip's way of handling toolchains.  They 
>>> work with old, outdated versions, rename and rebrand them and their 
>>> documentation to make it look like they wrote them themselves, then 
>>> add license checks and software locks so that optimisation is 
>>> disabled unless you pay them vast amounts of money for the software 
>>> other people wrote and gave away freely.  To my knowledge, they do 
>>> not break the letter of the license for GCC and other tools and 
>>> libraries, but they most certainly break the spirit of the licenses 
>>> in every way imaginable.
>>
>> Maybe you are thinking about Microchip IDE named MPLAB X or something 
>> similar. I read something about disabled optimizations in the free 
>> version of the toolchain.
>>
> 
> I believe it applies to all of Microchip's toolchains - and that now 
> includes those for the Atmel devices it acquired.
> 
>> However I'm using *Atmel Studio* IDE, that is an old IDE distributed 
>> by Atmel, before the Microchip purchase. The documentation speaks 
>> about some Atmel customization of ARM gcc toolchain, but it clearly 
>> specified the toolchain is an arm gcc.
> 
> OK.
> 
>>
>>
>>> Prior to being bought by Microchip, Atmel was bad - but not as bad.
>>
>> Why do you think Atmel was bad? I think they had good products.
> 
> It is not the products that I am talking about.  I've always like the 
> AVR architecture (though it could have been massively better with a few 
> small changes).  Though I haven't used their ARM devices myself, I have 
> heard nice things about them.  I am talking about the toolchains.
> 
> They had a very mixed attitude to open source software.  

I suspect because of Arduino, that is open source and started with 
ATmega328.


> For a long 
> time, they dismissed GCC completely, and gave no help or information for 
> other parts of the ecosystem (debuggers, programmers, etc.).  Eventually 
> they realised that there was a substantial customer base who did not 
> want to pay huge prices for IAR toolchains, or preferred open-source 
> toolchains for other reasons, and they made various half-hearted efforts 
> to support GCC for the AVR.  Basically, they did enough to be able to 
> have a working setup that they could provide it for free, but not enough 
> to make it efficient.  I think they spent more money on rebranding GCC 
> for the AVR and ARM than they did on technically improving them.  People 
> looking for AVR GCC toolchains were left with no idea what version of 
> GCC they can get from Atmel, or how those builds compare with mainline 
> GCC versions, what devices they support, or how the various required 
> extensions are handled.  Their ARM toolchains were a bit more standard, 
> and a bit less obfuscated in their branding and versioning.
> 
> So not as bad as Microchip, but still far from good.

I didn't follow the history of AVR MCUs and the available toolchains. I 
only used the AVR toolchain installed by Atmel Studio (I think by 
Atmel), but I know there's at leat winavr project. I don't know if there 
are real differeces between them.


>>> So if for some reason I have no choice but to use a device from Atmel 
>>> / Microchip, I do so using tools from elsewhere.
>>>
>>> As a general rule, the gcc-based toolchains from ARM are the industry 
>>> standard, and are used as the base by most ARM microcontroller 
>>> suppliers.  Some include additional library options, others provide 
>>> the package as-is.  For anything other than a quick demo, my 
>>> preferred setup is using makefiles for the build along with an ARM 
>>> gcc toolchain.  That way I can always build my software, from any 
>>> system, and archive the toolchain.  (One day, I will also try using 
>>> clang with these packages, but I haven't done so yet.)
>>
>> Yes, you're right, but now it's too late to change the toolchain.
>>
>>
>>> Any reasonably modern ARM gcc toolchain will have 64-bit time_t.  I 
>>> never like changing toolchains on an existing project, but you might 
>>> make an exception here.
>>
>> I will check.
>>
>>
>>> However, writing functions to support time conversions is not 
>>> difficult.   The trick is not to start at 01.01.1970, but start at a 
>>> convenient date as early as you will need to handle - 01.01.2025 
>>> would seem a logical point.  Use <https://www.unixtimestamp.com/> to 
>>> get the time_t constant for the start of your epoch.
>>>
>>> To turn the current time_t value into a human-readable time and date, 
>>> first take the current time_t and subtract the epoch start.  Divide 
>>> by 365 * 24 * 60 * 60 to get the additional years.  Divide the 
>>> leftovers by 24 * 60 * 60 to get the additional days.  Use a table of 
>>> days in the months to figure out the month.  Leap year handling is 
>>> left as an exercise for the reader (hint - 2100, 2200 and 2300 are 
>>> not leap years, while 2400 is).  Use the website I linked to check 
>>> your results.
>>
>> If I had to rewrite my own functions, I could define time64_t as 
>> uint64_t, keeping the Unix epoch as my epoch.
>>
>> Regarding implementation, I don't know if it so simple. mktime() fix 
>> the members of struct tm passed as an argument (and this is useful to 
>> calculate the day of the week). Moreover I don't only need the 
>> conversion from time64_t to struct tm, but viceversa too.
>>
> 
> Day of week calculations are peanuts - divide the seconds count by the 
> number of seconds in a day, add a constant value for whatever day 
> 01.01.1970 was, and reduce modulo 7.

Yes, you should be right.


> Most of the effort for converting a struct tm into a time_t is checking 
> that the values make sense.
> 
> For all of this, the big question is /why/ you are doing it.  What are 
> you doing with your times?  Where are you getting them?  Are you 
> actually doing this in a sensible way because they suit your 
> application, or are you just using these types and structures because 
> they are part of the standard C library - which is not good enough for 
> your needs here?

When the user wants to set the current date and time, I fill a struct tm 
with user values. Next I call mktime() to calculate time_t that is been 
incrementing every second.

When I need to show the current date and time to the user, I call 
localtime() to convert time_t in struct tm. And I have day of the week too.

Consider that mktime() and localtime() take into account timezone, that 
is important for me. In Italy we have daylight savings time with not so 
simple rules. Standard time functions work well with timezones.


> Maybe you are going about it all the wrong way.  If you need to be able 
> to display and set the current time and date, and to be able to 
> conveniently measure time differences for alarms, repetitive tasks, 
> etc., then you probably don't need any correlation between your 
> monotonic seconds counter and your time/date tracker.  All you need to 
> do is add one second to each, every second.  I don't know the details of 
> your application (obviously), but often no conversion is needed either way.

I'm talking about *wall* clock only. Internally I have a time_t variable 
that is incremented every second. But I need to show it to the user and 
I can't show the seconds from the epoch.


>>> Or you can get the sources for a modern version of newlib, and pull 
>>> the routines from there.
>>
>> It's a very complex code. time functions are written for whatever 
>> timezone is set at runtime (TZ env variable), so their complexity are 
>> higher.
>>
> 
> So find a simpler standard C library implementation.  Try the avrlibc, 
> for example.
> 
> But I have no doubt at all that you can make all this yourself easily 
> enough.

I think timezone rules are not so simple to implement.

[toc] | [prev] | [next] | [standalone]


#32355

FromDavid Brown <david.brown@hesbynett.no>
Date2025-03-12 17:39 +0100
Message-ID<vqsdcv$2mp5u$1@dont-email.me>
In reply to#32354
On 12/03/2025 16:48, pozz wrote:
> Il 12/03/2025 10:33, David Brown ha scritto:

>> For all of this, the big question is /why/ you are doing it.  What are 
>> you doing with your times?  Where are you getting them?  Are you 
>> actually doing this in a sensible way because they suit your 
>> application, or are you just using these types and structures because 
>> they are part of the standard C library - which is not good enough for 
>> your needs here?
> 
> When the user wants to set the current date and time, I fill a struct tm 
> with user values. Next I call mktime() to calculate time_t that is been 
> incrementing every second.
> 
> When I need to show the current date and time to the user, I call 
> localtime() to convert time_t in struct tm. And I have day of the week too.
> 
> Consider that mktime() and localtime() take into account timezone, that 
> is important for me. In Italy we have daylight savings time with not so 
> simple rules. Standard time functions work well with timezones.
> 
> 
>> Maybe you are going about it all the wrong way.  If you need to be 
>> able to display and set the current time and date, and to be able to 
>> conveniently measure time differences for alarms, repetitive tasks, 
>> etc., then you probably don't need any correlation between your 
>> monotonic seconds counter and your time/date tracker.  All you need to 
>> do is add one second to each, every second.  I don't know the details 
>> of your application (obviously), but often no conversion is needed 
>> either way.
> 
> I'm talking about *wall* clock only. Internally I have a time_t variable 
> that is incremented every second. But I need to show it to the user and 
> I can't show the seconds from the epoch.
> 

The sane way to do this - the way it has been done for decades on small 
embedded systems - is to track both a human-legible date/time structure 
(ignore standard struct tm - make your own) /and/ to track a monotonic 
seconds counter (or milliseconds counter, or minutes counter - whatever 
you need).  Increment both of them every second.  Both operations are 
very simple - far easier than any conversions.  Adding or subtracting an 
hour on occasion is also simple.

If your system is connected to the internet, then occasionally pick up 
the current wall-clock time (and unix epoch, if you like) from a server, 
along with the time of the next daylight savings change.  If it is not 
connected, then the user is going to have to make adjustments to the 
time and date occasionally anyway, as there is always drift - they can 
do the daylight saving change at the same time as they change their 
analogue clocks, their cooker clock, and everything else that is not 
connected.

> 
>>>> Or you can get the sources for a modern version of newlib, and pull 
>>>> the routines from there.
>>>
>>> It's a very complex code. time functions are written for whatever 
>>> timezone is set at runtime (TZ env variable), so their complexity are 
>>> higher.
>>>
>>
>> So find a simpler standard C library implementation.  Try the avrlibc, 
>> for example.
>>
>> But I have no doubt at all that you can make all this yourself easily 
>> enough.
> 
> I think timezone rules are not so simple to implement.
> 

You don't need them.  That makes them simple.

[toc] | [prev] | [next] | [standalone]


#32356

Frompozz <pozzugno@gmail.com>
Date2025-03-12 18:13 +0100
Message-ID<vqsfc3$2g8c7$2@dont-email.me>
In reply to#32355
Il 12/03/2025 17:39, David Brown ha scritto:
> On 12/03/2025 16:48, pozz wrote:
>> Il 12/03/2025 10:33, David Brown ha scritto:
> 
>>> For all of this, the big question is /why/ you are doing it.  What 
>>> are you doing with your times?  Where are you getting them?  Are you 
>>> actually doing this in a sensible way because they suit your 
>>> application, or are you just using these types and structures because 
>>> they are part of the standard C library - which is not good enough 
>>> for your needs here?
>>
>> When the user wants to set the current date and time, I fill a struct 
>> tm with user values. Next I call mktime() to calculate time_t that is 
>> been incrementing every second.
>>
>> When I need to show the current date and time to the user, I call 
>> localtime() to convert time_t in struct tm. And I have day of the week 
>> too.
>>
>> Consider that mktime() and localtime() take into account timezone, 
>> that is important for me. In Italy we have daylight savings time with 
>> not so simple rules. Standard time functions work well with timezones.
>>
>>
>>> Maybe you are going about it all the wrong way.  If you need to be 
>>> able to display and set the current time and date, and to be able to 
>>> conveniently measure time differences for alarms, repetitive tasks, 
>>> etc., then you probably don't need any correlation between your 
>>> monotonic seconds counter and your time/date tracker.  All you need 
>>> to do is add one second to each, every second.  I don't know the 
>>> details of your application (obviously), but often no conversion is 
>>> needed either way.
>>
>> I'm talking about *wall* clock only. Internally I have a time_t 
>> variable that is incremented every second. But I need to show it to 
>> the user and I can't show the seconds from the epoch.
>>
> 
> The sane way to do this - the way it has been done for decades on small 
> embedded systems - is to track both a human-legible date/time structure 
> (ignore standard struct tm - make your own) /and/ to track a monotonic 
> seconds counter (or milliseconds counter, or minutes counter - whatever 
> you need).  Increment both of them every second.  Both operations are 
> very simple - far easier than any conversions.  

If I got your point, adding one second to struct mytm isn't reduced to a 
++ on one of its member. I should write something similar to this:

if (mytm.tm_sec < 59) {
   mytm.tm_sec += 1;
} else {
   mytm.tm_sec = 0;
   if (mytm.tm_min < 59) {
     mytm.tm_min += 1;
   } else {
     mytm.tm_min = 0;
     if (mytm.tm_hour < 23) {
       mytm.tm_hour += 1;
     } else {
       mytm.tm_hour = 0;
       if (mytm.tm_mday < days_in_month(mytm.tm_mon, mytm.tm_year)) {
         mytm.tm_mday += 1;
       } else {
         mytm.tm_mday = 1;
         if (mytm.tm_mon < 12) {
           mytm.tm_mon += 1;
         } else {
           mytm.tm_mon = 0;
           mytm.tm_year += 1;
         }
       }
     }
   }
}

However taking into account dst is much more complex. The rule is the 
last sunday of March and last sunday of October (if I'm not wrong).

All can be coded manually from the scratch, but there are standard 
functions just to avoid reinventing the wheel.

Tomorrow I could install my device in another country in the world and 
it could be easy to change the timezone with standard function.


> Adding or subtracting an hour on occasion is also simple.

Yes, but the problem is *when*. You need to know the rules and you need 
to implement them. localtime() just works.


> If your system is connected to the internet, then occasionally pick up 
> the current wall-clock time (and unix epoch, if you like) from a server, 
> along with the time of the next daylight savings change.  

What do you mean with "next daylight savings change"? I'm using NTP 
(specifically SNTP from a public server) and I'm able to retrive the 
current UTC time in seconds from Unix epoch.

I just take this value and overwrite my internal counter.

In other application, I retrive the current time from incoming SMS. In 
this case I have a local broken down time.


> If it is not 
> connected, then the user is going to have to make adjustments to the 
> time and date occasionally anyway, as there is always drift 

Drifts? By using a 32.768kHz quartz to generate a 1 Hz clock that 
increases the internal counter avoid any drifts.

- they can
> do the daylight saving change at the same time as they change their 
> analogue clocks, their cooker clock, and everything else that is not 
> connected.

I think you can take into account dst even if the device is not connected.

I bet Windows is able to show the correct time (with dst changes) even 
if the PC is not connected.


>>>>> Or you can get the sources for a modern version of newlib, and pull 
>>>>> the routines from there.
>>>>
>>>> It's a very complex code. time functions are written for whatever 
>>>> timezone is set at runtime (TZ env variable), so their complexity 
>>>> are higher.
>>>>
>>>
>>> So find a simpler standard C library implementation.  Try the 
>>> avrlibc, for example.
>>>
>>> But I have no doubt at all that you can make all this yourself easily 
>>> enough.
>>
>> I think timezone rules are not so simple to implement.
>>
> 
> You don't need them.  That makes them simple.

[toc] | [prev] | [next] | [standalone]


#32357

FromDavid Brown <david.brown@hesbynett.no>
Date2025-03-12 19:18 +0100
Message-ID<vqsj69$2o1s0$1@dont-email.me>
In reply to#32356
On 12/03/2025 18:13, pozz wrote:
> Il 12/03/2025 17:39, David Brown ha scritto:
>> On 12/03/2025 16:48, pozz wrote:
>>> Il 12/03/2025 10:33, David Brown ha scritto:
>>
>>>> For all of this, the big question is /why/ you are doing it.  What 
>>>> are you doing with your times?  Where are you getting them?  Are you 
>>>> actually doing this in a sensible way because they suit your 
>>>> application, or are you just using these types and structures 
>>>> because they are part of the standard C library - which is not good 
>>>> enough for your needs here?
>>>
>>> When the user wants to set the current date and time, I fill a struct 
>>> tm with user values. Next I call mktime() to calculate time_t that is 
>>> been incrementing every second.
>>>
>>> When I need to show the current date and time to the user, I call 
>>> localtime() to convert time_t in struct tm. And I have day of the 
>>> week too.
>>>
>>> Consider that mktime() and localtime() take into account timezone, 
>>> that is important for me. In Italy we have daylight savings time with 
>>> not so simple rules. Standard time functions work well with timezones.
>>>
>>>
>>>> Maybe you are going about it all the wrong way.  If you need to be 
>>>> able to display and set the current time and date, and to be able to 
>>>> conveniently measure time differences for alarms, repetitive tasks, 
>>>> etc., then you probably don't need any correlation between your 
>>>> monotonic seconds counter and your time/date tracker.  All you need 
>>>> to do is add one second to each, every second.  I don't know the 
>>>> details of your application (obviously), but often no conversion is 
>>>> needed either way.
>>>
>>> I'm talking about *wall* clock only. Internally I have a time_t 
>>> variable that is incremented every second. But I need to show it to 
>>> the user and I can't show the seconds from the epoch.
>>>
>>
>> The sane way to do this - the way it has been done for decades on 
>> small embedded systems - is to track both a human-legible date/time 
>> structure (ignore standard struct tm - make your own) /and/ to track a 
>> monotonic seconds counter (or milliseconds counter, or minutes counter 
>> - whatever you need).  Increment both of them every second.  Both 
>> operations are very simple - far easier than any conversions. 
> 
> If I got your point, adding one second to struct mytm isn't reduced to a 
> ++ on one of its member. I should write something similar to this:
> 
> if (mytm.tm_sec < 59) {
>    mytm.tm_sec += 1;
> } else {
>    mytm.tm_sec = 0;
>    if (mytm.tm_min < 59) {
>      mytm.tm_min += 1;
>    } else {
>      mytm.tm_min = 0;
>      if (mytm.tm_hour < 23) {
>        mytm.tm_hour += 1;
>      } else {
>        mytm.tm_hour = 0;
>        if (mytm.tm_mday < days_in_month(mytm.tm_mon, mytm.tm_year)) {
>          mytm.tm_mday += 1;
>        } else {
>          mytm.tm_mday = 1;
>          if (mytm.tm_mon < 12) {
>            mytm.tm_mon += 1;
>          } else {
>            mytm.tm_mon = 0;
>            mytm.tm_year += 1;
>          }
>        }
>      }
>    }
> }
> 

Yes, that's about it.

> However taking into account dst is much more complex. The rule is the 
> last sunday of March and last sunday of October (if I'm not wrong).

No, it is not complex.  Figure out the rule for your country (I'm sure 
Wikipedia well tell you if you are not sure) and then apply it.  It's 
just a comparison to catch the right time and date, and then you add or 
subtract an extra hour.

> 
> All can be coded manually from the scratch, but there are standard 
> functions just to avoid reinventing the wheel.

You've just written the code!  You have maybe 10-15 more lines to add to 
handle daylight saving.

> 
> Tomorrow I could install my device in another country in the world and 
> it could be easy to change the timezone with standard function.

How many countries are you targeting?  Europe all uses the same system.

<https://en.wikipedia.org/wiki/Daylight_saving_time_by_country>

> 
>> Adding or subtracting an hour on occasion is also simple.
> 
> Yes, but the problem is *when*. You need to know the rules and you need 
> to implement them. localtime() just works.
> 

You are getting ridiculous.  This is not rocket science.

Besides, any fixed system is at risk from changes - and countries have 
in the past and will in the future change their systems for daylight 
saving.  (Many have at least vague plans of scraping it.)  So if a 
simple fixed system is not good enough for you, use the other method I 
suggested - handle it by regular checks from a server that you will need 
anyway for keeping an accurate time, or let the user fix it for 
unconnected systems.

> 
>> If your system is connected to the internet, then occasionally pick up 
>> the current wall-clock time (and unix epoch, if you like) from a 
>> server, along with the time of the next daylight savings change. 
> 
> What do you mean with "next daylight savings change"? I'm using NTP 
> (specifically SNTP from a public server) and I'm able to retrive the 
> current UTC time in seconds from Unix epoch.
> 
> I just take this value and overwrite my internal counter.
> 
> In other application, I retrive the current time from incoming SMS. In 
> this case I have a local broken down time.
> 
> 
>> If it is not connected, then the user is going to have to make 
>> adjustments to the time and date occasionally anyway, as there is 
>> always drift 
> 
> Drifts? By using a 32.768kHz quartz to generate a 1 Hz clock that 
> increases the internal counter avoid any drifts.

There is no such thing as a 32.768 kHz crystal - there are only 
approximate crystals.  If you don't update often enough from an accurate 
time source, you will have drift.  (How much drift you have, and what 
effect it has, is another matter.)

> 
> - they can
>> do the daylight saving change at the same time as they change their 
>> analogue clocks, their cooker clock, and everything else that is not 
>> connected.
> 
> I think you can take into account dst even if the device is not connected.
> 

You certainly can.  But then you have to have a fixed algorithm known in 
advance.

> I bet Windows is able to show the correct time (with dst changes) even 
> if the PC is not connected.
> 

I bet it can't, in cases where the date system for the daylight savings 
time has changed or been removed.  Other than that, it will just use a 
table of date systems such as on the Wikipedia page.  Or perhaps MS 
simply redefined what they think other people should use.

Older Windows needed manual changes for the date and time, even when it 
was connected - their support for NTP was late.

> 
>>>>>> Or you can get the sources for a modern version of newlib, and 
>>>>>> pull the routines from there.
>>>>>
>>>>> It's a very complex code. time functions are written for whatever 
>>>>> timezone is set at runtime (TZ env variable), so their complexity 
>>>>> are higher.
>>>>>
>>>>
>>>> So find a simpler standard C library implementation.  Try the 
>>>> avrlibc, for example.
>>>>
>>>> But I have no doubt at all that you can make all this yourself 
>>>> easily enough.
>>>
>>> I think timezone rules are not so simple to implement.
>>>
>>
>> You don't need them.  That makes them simple.
> 

[toc] | [prev] | [next] | [standalone]


#32358

Frompozz <pozzugno@gmail.com>
Date2025-03-13 09:57 +0100
Message-ID<vqu6lo$34o8d$1@dont-email.me>
In reply to#32357
Il 12/03/2025 19:18, David Brown ha scritto:
> On 12/03/2025 18:13, pozz wrote:
>> Il 12/03/2025 17:39, David Brown ha scritto:
>>> On 12/03/2025 16:48, pozz wrote:
>>>> Il 12/03/2025 10:33, David Brown ha scritto:
>>>
>>>>> For all of this, the big question is /why/ you are doing it.  What 
>>>>> are you doing with your times?  Where are you getting them?  Are 
>>>>> you actually doing this in a sensible way because they suit your 
>>>>> application, or are you just using these types and structures 
>>>>> because they are part of the standard C library - which is not good 
>>>>> enough for your needs here?
>>>>
>>>> When the user wants to set the current date and time, I fill a 
>>>> struct tm with user values. Next I call mktime() to calculate time_t 
>>>> that is been incrementing every second.
>>>>
>>>> When I need to show the current date and time to the user, I call 
>>>> localtime() to convert time_t in struct tm. And I have day of the 
>>>> week too.
>>>>
>>>> Consider that mktime() and localtime() take into account timezone, 
>>>> that is important for me. In Italy we have daylight savings time 
>>>> with not so simple rules. Standard time functions work well with 
>>>> timezones.
>>>>
>>>>
>>>>> Maybe you are going about it all the wrong way.  If you need to be 
>>>>> able to display and set the current time and date, and to be able 
>>>>> to conveniently measure time differences for alarms, repetitive 
>>>>> tasks, etc., then you probably don't need any correlation between 
>>>>> your monotonic seconds counter and your time/date tracker.  All you 
>>>>> need to do is add one second to each, every second.  I don't know 
>>>>> the details of your application (obviously), but often no 
>>>>> conversion is needed either way.
>>>>
>>>> I'm talking about *wall* clock only. Internally I have a time_t 
>>>> variable that is incremented every second. But I need to show it to 
>>>> the user and I can't show the seconds from the epoch.
>>>>
>>>
>>> The sane way to do this - the way it has been done for decades on 
>>> small embedded systems - is to track both a human-legible date/time 
>>> structure (ignore standard struct tm - make your own) /and/ to track 
>>> a monotonic seconds counter (or milliseconds counter, or minutes 
>>> counter - whatever you need).  Increment both of them every second.  
>>> Both operations are very simple - far easier than any conversions. 
>>
>> If I got your point, adding one second to struct mytm isn't reduced to 
>> a ++ on one of its member. I should write something similar to this:
>>
>> if (mytm.tm_sec < 59) {
>>    mytm.tm_sec += 1;
>> } else {
>>    mytm.tm_sec = 0;
>>    if (mytm.tm_min < 59) {
>>      mytm.tm_min += 1;
>>    } else {
>>      mytm.tm_min = 0;
>>      if (mytm.tm_hour < 23) {
>>        mytm.tm_hour += 1;
>>      } else {
>>        mytm.tm_hour = 0;
>>        if (mytm.tm_mday < days_in_month(mytm.tm_mon, mytm.tm_year)) {
>>          mytm.tm_mday += 1;
>>        } else {
>>          mytm.tm_mday = 1;
>>          if (mytm.tm_mon < 12) {
>>            mytm.tm_mon += 1;
>>          } else {
>>            mytm.tm_mon = 0;
>>            mytm.tm_year += 1;
>>          }
>>        }
>>      }
>>    }
>> }
>>
> 
> Yes, that's about it.
> 
>> However taking into account dst is much more complex. The rule is the 
>> last sunday of March and last sunday of October (if I'm not wrong).
> 
> No, it is not complex.  Figure out the rule for your country (I'm sure 
> Wikipedia well tell you if you are not sure) and then apply it.  It's 
> just a comparison to catch the right time and date, and then you add or 
> subtract an extra hour.
> 
>>
>> All can be coded manually from the scratch, but there are standard 
>> functions just to avoid reinventing the wheel.
> 
> You've just written the code!  You have maybe 10-15 more lines to add to 
> handle daylight saving.
> 
>>
>> Tomorrow I could install my device in another country in the world and 
>> it could be easy to change the timezone with standard function.
> 
> How many countries are you targeting?  Europe all uses the same system.
> 
> <https://en.wikipedia.org/wiki/Daylight_saving_time_by_country>
> 
>>
>>> Adding or subtracting an hour on occasion is also simple.
>>
>> Yes, but the problem is *when*. You need to know the rules and you 
>> need to implement them. localtime() just works.
>>
> 
> You are getting ridiculous.  This is not rocket science.

Ok, but I don't understand why you prefer to write your own code (yes, 
you're an exper programmer, but you can introduce some bugs, you have to 
write  some tests), while there are standard functions that make the job 
for you.

I could rewrite memcpy, strcat, strcmp, they aren't rocket science, but 
why? IMHO there is no sense.

In my case standard functions aren't good (because of Y2038 issue) and 
rewriting them can be a valid solution. But if I had a 64 bits time_t, I 
would live with standard functions very well.


> Besides, any fixed system is at risk from changes - and countries have 
> in the past and will in the future change their systems for daylight 
> saving.  (Many have at least vague plans of scraping it.)  So if a 
> simple fixed system is not good enough for you, use the other method I 
> suggested - handle it by regular checks from a server that you will need 
> anyway for keeping an accurate time, or let the user fix it for 
> unconnected systems.

My users like the automatic dst changes on my connected and unconnected 
devices. The risk of a future changes in the dst rules doesn't seem to 
me a good reason to remove that feature.


>>> If your system is connected to the internet, then occasionally pick 
>>> up the current wall-clock time (and unix epoch, if you like) from a 
>>> server, along with the time of the next daylight savings change. 
>>
>> What do you mean with "next daylight savings change"? I'm using NTP 
>> (specifically SNTP from a public server) and I'm able to retrive the 
>> current UTC time in seconds from Unix epoch.
>>
>> I just take this value and overwrite my internal counter.
>>
>> In other application, I retrive the current time from incoming SMS. In 
>> this case I have a local broken down time.
>>
>>
>>> If it is not connected, then the user is going to have to make 
>>> adjustments to the time and date occasionally anyway, as there is 
>>> always drift 
>>
>> Drifts? By using a 32.768kHz quartz to generate a 1 Hz clock that 
>> increases the internal counter avoid any drifts.
> 
> There is no such thing as a 32.768 kHz crystal - there are only 
> approximate crystals.  If you don't update often enough from an accurate 
> time source, you will have drift.  (How much drift you have, and what 
> effect it has, is another matter.)

Of course, the quartz has an accuracy that changes with life, 
temperature an so on. However the real accuracy doesn't allow the time 
drifting so much the user needs to reset the time.


>> - they can
>>> do the daylight saving change at the same time as they change their 
>>> analogue clocks, their cooker clock, and everything else that is not 
>>> connected.
>>
>> I think you can take into account dst even if the device is not 
>> connected.
>>
> 
> You certainly can.  But then you have to have a fixed algorithm known in 
> advance.
> 
>> I bet Windows is able to show the correct time (with dst changes) even 
>> if the PC is not connected.
> 
> I bet it can't, in cases where the date system for the daylight savings 
> time has changed or been removed.  Other than that, it will just use a 
> table of date systems such as on the Wikipedia page.  Or perhaps MS 
> simply redefined what they think other people should use.
> 
> Older Windows needed manual changes for the date and time, even when it 
> was connected - their support for NTP was late.

Maybe Windows is not able, but I'm reading Linux is. It saves the time 
as UTC on the hw RTC and shows it to the user as localtime, of course 
applying dst and timezone rules from a database of rules.

So, as long as the timezone/dst info for my timezone is correct, I think 
Linux could manage dst changes automatically without user activity.

My approach is identical to what Linux does.


>>>>>>> Or you can get the sources for a modern version of newlib, and 
>>>>>>> pull the routines from there.
>>>>>>
>>>>>> It's a very complex code. time functions are written for whatever 
>>>>>> timezone is set at runtime (TZ env variable), so their complexity 
>>>>>> are higher.
>>>>>>
>>>>>
>>>>> So find a simpler standard C library implementation.  Try the 
>>>>> avrlibc, for example.
>>>>>
>>>>> But I have no doubt at all that you can make all this yourself 
>>>>> easily enough.
>>>>
>>>> I think timezone rules are not so simple to implement.
>>>>
>>>
>>> You don't need them.  That makes them simple.

[toc] | [prev] | [next] | [standalone]


#32359

FromDavid Brown <david.brown@hesbynett.no>
Date2025-03-13 16:51 +0100
Message-ID<vquuts$3et7q$1@dont-email.me>
In reply to#32358
On 13/03/2025 09:57, pozz wrote:
> Il 12/03/2025 19:18, David Brown ha scritto:
>> On 12/03/2025 18:13, pozz wrote:
>>> Il 12/03/2025 17:39, David Brown ha scritto:
>>>> On 12/03/2025 16:48, pozz wrote:
>>>>> Il 12/03/2025 10:33, David Brown ha scritto:
>>>>
>>>>>> For all of this, the big question is /why/ you are doing it.  What 
>>>>>> are you doing with your times?  Where are you getting them?  Are 
>>>>>> you actually doing this in a sensible way because they suit your 
>>>>>> application, or are you just using these types and structures 
>>>>>> because they are part of the standard C library - which is not 
>>>>>> good enough for your needs here?
>>>>>
>>>>> When the user wants to set the current date and time, I fill a 
>>>>> struct tm with user values. Next I call mktime() to calculate 
>>>>> time_t that is been incrementing every second.
>>>>>
>>>>> When I need to show the current date and time to the user, I call 
>>>>> localtime() to convert time_t in struct tm. And I have day of the 
>>>>> week too.
>>>>>
>>>>> Consider that mktime() and localtime() take into account timezone, 
>>>>> that is important for me. In Italy we have daylight savings time 
>>>>> with not so simple rules. Standard time functions work well with 
>>>>> timezones.
>>>>>
>>>>>
>>>>>> Maybe you are going about it all the wrong way.  If you need to be 
>>>>>> able to display and set the current time and date, and to be able 
>>>>>> to conveniently measure time differences for alarms, repetitive 
>>>>>> tasks, etc., then you probably don't need any correlation between 
>>>>>> your monotonic seconds counter and your time/date tracker.  All 
>>>>>> you need to do is add one second to each, every second.  I don't 
>>>>>> know the details of your application (obviously), but often no 
>>>>>> conversion is needed either way.
>>>>>
>>>>> I'm talking about *wall* clock only. Internally I have a time_t 
>>>>> variable that is incremented every second. But I need to show it to 
>>>>> the user and I can't show the seconds from the epoch.
>>>>>
>>>>
>>>> The sane way to do this - the way it has been done for decades on 
>>>> small embedded systems - is to track both a human-legible date/time 
>>>> structure (ignore standard struct tm - make your own) /and/ to track 
>>>> a monotonic seconds counter (or milliseconds counter, or minutes 
>>>> counter - whatever you need).  Increment both of them every second. 
>>>> Both operations are very simple - far easier than any conversions. 
>>>
>>> If I got your point, adding one second to struct mytm isn't reduced 
>>> to a ++ on one of its member. I should write something similar to this:
>>>
>>> if (mytm.tm_sec < 59) {
>>>    mytm.tm_sec += 1;
>>> } else {
>>>    mytm.tm_sec = 0;
>>>    if (mytm.tm_min < 59) {
>>>      mytm.tm_min += 1;
>>>    } else {
>>>      mytm.tm_min = 0;
>>>      if (mytm.tm_hour < 23) {
>>>        mytm.tm_hour += 1;
>>>      } else {
>>>        mytm.tm_hour = 0;
>>>        if (mytm.tm_mday < days_in_month(mytm.tm_mon, mytm.tm_year)) {
>>>          mytm.tm_mday += 1;
>>>        } else {
>>>          mytm.tm_mday = 1;
>>>          if (mytm.tm_mon < 12) {
>>>            mytm.tm_mon += 1;
>>>          } else {
>>>            mytm.tm_mon = 0;
>>>            mytm.tm_year += 1;
>>>          }
>>>        }
>>>      }
>>>    }
>>> }
>>>
>>
>> Yes, that's about it.
>>
>>> However taking into account dst is much more complex. The rule is the 
>>> last sunday of March and last sunday of October (if I'm not wrong).
>>
>> No, it is not complex.  Figure out the rule for your country (I'm sure 
>> Wikipedia well tell you if you are not sure) and then apply it.  It's 
>> just a comparison to catch the right time and date, and then you add 
>> or subtract an extra hour.
>>
>>>
>>> All can be coded manually from the scratch, but there are standard 
>>> functions just to avoid reinventing the wheel.
>>
>> You've just written the code!  You have maybe 10-15 more lines to add 
>> to handle daylight saving.
>>
>>>
>>> Tomorrow I could install my device in another country in the world 
>>> and it could be easy to change the timezone with standard function.
>>
>> How many countries are you targeting?  Europe all uses the same system.
>>
>> <https://en.wikipedia.org/wiki/Daylight_saving_time_by_country>
>>
>>>
>>>> Adding or subtracting an hour on occasion is also simple.
>>>
>>> Yes, but the problem is *when*. You need to know the rules and you 
>>> need to implement them. localtime() just works.
>>>
>>
>> You are getting ridiculous.  This is not rocket science.
> 
> Ok, but I don't understand why you prefer to write your own code (yes, 
> you're an exper programmer, but you can introduce some bugs, you have to 
> write  some tests), while there are standard functions that make the job 
> for you.
> 

I prefer to use a newer version of the toolchain that does not have such 
problems :-)

I am quite happy to re-use known good standard functions.  There is no 
need to reinvent the wheel if you already have one conveniently 
available.  But you don't have standard functions conveniently available 
here - the ones from your toolchain are not up to the task, and you are 
not happy with the other sources you have found for the standard functions.

So once you have eliminated the possibility of using pre-written 
standard functions, you then need to re-evaluate what you actually need. 
  And that is much less than the standard functions provide.  So write 
your own versions to do what you need to do - no more, no less.


> I could rewrite memcpy, strcat, strcmp, they aren't rocket science, but 
> why? IMHO there is no sense.

I have re-written such functionality a number of times - because 
sometimes I can do a better job for the task in hand than the standard 
functions.  For example, strncpy() is downright silly - it is 
inefficient (it copies more than it needs to), and potentially unsafe as 
it doesn't necessarily copy the terminator.  memcpy() can be inefficient 
in cases where the programmer knows more about the alignment or size 
than the compiler can prove.  And so on.

> 
> In my case standard functions aren't good (because of Y2038 issue) and 
> rewriting them can be a valid solution. But if I had a 64 bits time_t, I 
> would live with standard functions very well.
> 

And if pigs could fly, you could probably teach them to program too. 
You can't use the standard functions, so you have to look elsewhere. 
Writing them yourself is a simple and convenient solution.

> 
>> Besides, any fixed system is at risk from changes - and countries have 
>> in the past and will in the future change their systems for daylight 
>> saving.  (Many have at least vague plans of scraping it.)  So if a 
>> simple fixed system is not good enough for you, use the other method I 
>> suggested - handle it by regular checks from a server that you will 
>> need anyway for keeping an accurate time, or let the user fix it for 
>> unconnected systems.
> 
> My users like the automatic dst changes on my connected and unconnected 
> devices. The risk of a future changes in the dst rules doesn't seem to 
> me a good reason to remove that feature.
> 

Okay, so you have to put it in.

As I see it, the options are :

1. Use the standard functions from your toolchain.  You've ruled out 
using those with your current toolchain, and ruled out changing the 
toolchain, so this won't do.

2. Use an implementation from other library sources online.  You've 
ruled those out as too complicated.

3. Write your own functions.  Yes, that involves a certain amount of 
work, testing and risk.  That's your job.


Am I missing anything?


> 
>>>> If your system is connected to the internet, then occasionally pick 
>>>> up the current wall-clock time (and unix epoch, if you like) from a 
>>>> server, along with the time of the next daylight savings change. 
>>>
>>> What do you mean with "next daylight savings change"? I'm using NTP 
>>> (specifically SNTP from a public server) and I'm able to retrive the 
>>> current UTC time in seconds from Unix epoch.
>>>
>>> I just take this value and overwrite my internal counter.
>>>
>>> In other application, I retrive the current time from incoming SMS. 
>>> In this case I have a local broken down time.
>>>
>>>
>>>> If it is not connected, then the user is going to have to make 
>>>> adjustments to the time and date occasionally anyway, as there is 
>>>> always drift 
>>>
>>> Drifts? By using a 32.768kHz quartz to generate a 1 Hz clock that 
>>> increases the internal counter avoid any drifts.
>>
>> There is no such thing as a 32.768 kHz crystal - there are only 
>> approximate crystals.  If you don't update often enough from an 
>> accurate time source, you will have drift.  (How much drift you have, 
>> and what effect it has, is another matter.)
> 
> Of course, the quartz has an accuracy that changes with life, 
> temperature an so on. However the real accuracy doesn't allow the time 
> drifting so much the user needs to reset the time.
> 

A standard cheap nominal 32.768 kHz is +/- 20 ppm.  That's 1.7 seconds 
per day - assuming everything in the hardware is good.  Often that's 
good enough, but sometimes it is not.  Only you can answer that one.

> 
>>> - they can
>>>> do the daylight saving change at the same time as they change their 
>>>> analogue clocks, their cooker clock, and everything else that is not 
>>>> connected.
>>>
>>> I think you can take into account dst even if the device is not 
>>> connected.
>>>
>>
>> You certainly can.  But then you have to have a fixed algorithm known 
>> in advance.
>>
>>> I bet Windows is able to show the correct time (with dst changes) 
>>> even if the PC is not connected.
>>
>> I bet it can't, in cases where the date system for the daylight 
>> savings time has changed or been removed.  Other than that, it will 
>> just use a table of date systems such as on the Wikipedia page.  Or 
>> perhaps MS simply redefined what they think other people should use.
>>
>> Older Windows needed manual changes for the date and time, even when 
>> it was connected - their support for NTP was late.
> 
> Maybe Windows is not able, but I'm reading Linux is. It saves the time 
> as UTC on the hw RTC and shows it to the user as localtime, of course 
> applying dst and timezone rules from a database of rules.

Yes, Linux has had NTP, timezones and daylight savings since its early 
days (as have other *nix OS's).

> 
> So, as long as the timezone/dst info for my timezone is correct, I think 
> Linux could manage dst changes automatically without user activity.
> 
> My approach is identical to what Linux does.
> 

[toc] | [prev] | [next] | [standalone]


#32362

Frompozz <pozzugno@gmail.com>
Date2025-03-14 13:27 +0100
Message-ID<vr17ak$rtjs$2@dont-email.me>
In reply to#32359
Il 13/03/2025 16:51, David Brown ha scritto:
> On 13/03/2025 09:57, pozz wrote:
>> Il 12/03/2025 19:18, David Brown ha scritto:
>>> On 12/03/2025 18:13, pozz wrote:
>>>> Il 12/03/2025 17:39, David Brown ha scritto:
>>>>> On 12/03/2025 16:48, pozz wrote:
>>>>>> Il 12/03/2025 10:33, David Brown ha scritto:
>>>>>
>>>>>>> For all of this, the big question is /why/ you are doing it.  
>>>>>>> What are you doing with your times?  Where are you getting them?  
>>>>>>> Are you actually doing this in a sensible way because they suit 
>>>>>>> your application, or are you just using these types and 
>>>>>>> structures because they are part of the standard C library - 
>>>>>>> which is not good enough for your needs here?
>>>>>>
>>>>>> When the user wants to set the current date and time, I fill a 
>>>>>> struct tm with user values. Next I call mktime() to calculate 
>>>>>> time_t that is been incrementing every second.
>>>>>>
>>>>>> When I need to show the current date and time to the user, I call 
>>>>>> localtime() to convert time_t in struct tm. And I have day of the 
>>>>>> week too.
>>>>>>
>>>>>> Consider that mktime() and localtime() take into account timezone, 
>>>>>> that is important for me. In Italy we have daylight savings time 
>>>>>> with not so simple rules. Standard time functions work well with 
>>>>>> timezones.
>>>>>>
>>>>>>
>>>>>>> Maybe you are going about it all the wrong way.  If you need to 
>>>>>>> be able to display and set the current time and date, and to be 
>>>>>>> able to conveniently measure time differences for alarms, 
>>>>>>> repetitive tasks, etc., then you probably don't need any 
>>>>>>> correlation between your monotonic seconds counter and your 
>>>>>>> time/date tracker.  All you need to do is add one second to each, 
>>>>>>> every second.  I don't know the details of your application 
>>>>>>> (obviously), but often no conversion is needed either way.
>>>>>>
>>>>>> I'm talking about *wall* clock only. Internally I have a time_t 
>>>>>> variable that is incremented every second. But I need to show it 
>>>>>> to the user and I can't show the seconds from the epoch.
>>>>>>
>>>>>
>>>>> The sane way to do this - the way it has been done for decades on 
>>>>> small embedded systems - is to track both a human-legible date/time 
>>>>> structure (ignore standard struct tm - make your own) /and/ to 
>>>>> track a monotonic seconds counter (or milliseconds counter, or 
>>>>> minutes counter - whatever you need).  Increment both of them every 
>>>>> second. Both operations are very simple - far easier than any 
>>>>> conversions. 
>>>>
>>>> If I got your point, adding one second to struct mytm isn't reduced 
>>>> to a ++ on one of its member. I should write something similar to this:
>>>>
>>>> if (mytm.tm_sec < 59) {
>>>>    mytm.tm_sec += 1;
>>>> } else {
>>>>    mytm.tm_sec = 0;
>>>>    if (mytm.tm_min < 59) {
>>>>      mytm.tm_min += 1;
>>>>    } else {
>>>>      mytm.tm_min = 0;
>>>>      if (mytm.tm_hour < 23) {
>>>>        mytm.tm_hour += 1;
>>>>      } else {
>>>>        mytm.tm_hour = 0;
>>>>        if (mytm.tm_mday < days_in_month(mytm.tm_mon, mytm.tm_year)) {
>>>>          mytm.tm_mday += 1;
>>>>        } else {
>>>>          mytm.tm_mday = 1;
>>>>          if (mytm.tm_mon < 12) {
>>>>            mytm.tm_mon += 1;
>>>>          } else {
>>>>            mytm.tm_mon = 0;
>>>>            mytm.tm_year += 1;
>>>>          }
>>>>        }
>>>>      }
>>>>    }
>>>> }
>>>>
>>>
>>> Yes, that's about it.
>>>
>>>> However taking into account dst is much more complex. The rule is 
>>>> the last sunday of March and last sunday of October (if I'm not wrong).
>>>
>>> No, it is not complex.  Figure out the rule for your country (I'm 
>>> sure Wikipedia well tell you if you are not sure) and then apply it.  
>>> It's just a comparison to catch the right time and date, and then you 
>>> add or subtract an extra hour.
>>>
>>>>
>>>> All can be coded manually from the scratch, but there are standard 
>>>> functions just to avoid reinventing the wheel.
>>>
>>> You've just written the code!  You have maybe 10-15 more lines to add 
>>> to handle daylight saving.
>>>
>>>>
>>>> Tomorrow I could install my device in another country in the world 
>>>> and it could be easy to change the timezone with standard function.
>>>
>>> How many countries are you targeting?  Europe all uses the same system.
>>>
>>> <https://en.wikipedia.org/wiki/Daylight_saving_time_by_country>
>>>
>>>>
>>>>> Adding or subtracting an hour on occasion is also simple.
>>>>
>>>> Yes, but the problem is *when*. You need to know the rules and you 
>>>> need to implement them. localtime() just works.
>>>>
>>>
>>> You are getting ridiculous.  This is not rocket science.
>>
>> Ok, but I don't understand why you prefer to write your own code (yes, 
>> you're an exper programmer, but you can introduce some bugs, you have 
>> to write  some tests), while there are standard functions that make 
>> the job for you.
>>
> 
> I prefer to use a newer version of the toolchain that does not have such 
> problems :-)

Sure, but the project is old. I will check if using a newer toolchain is 
a feasible solution for this project.


> I am quite happy to re-use known good standard functions.  There is no 
> need to reinvent the wheel if you already have one conveniently 
> available.  But you don't have standard functions conveniently available 
> here - the ones from your toolchain are not up to the task, and you are 
> not happy with the other sources you have found for the standard functions.
> 
> So once you have eliminated the possibility of using pre-written 
> standard functions, you then need to re-evaluate what you actually need. 
>   And that is much less than the standard functions provide.  So write 
> your own versions to do what you need to do - no more, no less.

I agree with you. I thought you were suggesting to use custom made 
functions in any case, because my approach that uses time_t counter 
(seconds from epoch) and localtime()/mktime() isn't good.


>> I could rewrite memcpy, strcat, strcmp, they aren't rocket science, 
>> but why? IMHO there is no sense.
> 
> I have re-written such functionality a number of times - because 
> sometimes I can do a better job for the task in hand than the standard 
> functions.  For example, strncpy() is downright silly - it is 
> inefficient (it copies more than it needs to), and potentially unsafe as 
> it doesn't necessarily copy the terminator.  memcpy() can be inefficient 
> in cases where the programmer knows more about the alignment or size 
> than the compiler can prove.  And so on.

Yes, if your functios are better than standard functions, it's the way 
to go for me too.


>> In my case standard functions aren't good (because of Y2038 issue) and 
>> rewriting them can be a valid solution. But if I had a 64 bits time_t, 
>> I would live with standard functions very well.
> 
> And if pigs could fly, you could probably teach them to program too. You 
> can't use the standard functions, so you have to look elsewhere. Writing 
> them yourself is a simple and convenient solution.

Yes.

>>> Besides, any fixed system is at risk from changes - and countries 
>>> have in the past and will in the future change their systems for 
>>> daylight saving.  (Many have at least vague plans of scraping it.)  
>>> So if a simple fixed system is not good enough for you, use the other 
>>> method I suggested - handle it by regular checks from a server that 
>>> you will need anyway for keeping an accurate time, or let the user 
>>> fix it for unconnected systems.
>>
>> My users like the automatic dst changes on my connected and 
>> unconnected devices. The risk of a future changes in the dst rules 
>> doesn't seem to me a good reason to remove that feature.
> 
> Okay, so you have to put it in.
> 
> As I see it, the options are :
> 
> 1. Use the standard functions from your toolchain.  You've ruled out 
> using those with your current toolchain, and ruled out changing the 
> toolchain, so this won't do.

Chaning the toolchain is a possibile solution. I have to check yet.


> 2. Use an implementation from other library sources online.  You've 
> ruled those out as too complicated.

In the past I sometimes lurked in the newlib code and it seems too 
complicated for me. I will search for other simple implementations of 
localtime()/mktime().


> 3. Write your own functions.  Yes, that involves a certain amount of 
> work, testing and risk.  That's your job.
> 
> Am I missing anything?

I don't think.


>>>>> If your system is connected to the internet, then occasionally pick 
>>>>> up the current wall-clock time (and unix epoch, if you like) from a 
>>>>> server, along with the time of the next daylight savings change. 
>>>>
>>>> What do you mean with "next daylight savings change"? I'm using NTP 
>>>> (specifically SNTP from a public server) and I'm able to retrive the 
>>>> current UTC time in seconds from Unix epoch.
>>>>
>>>> I just take this value and overwrite my internal counter.
>>>>
>>>> In other application, I retrive the current time from incoming SMS. 
>>>> In this case I have a local broken down time.
>>>>
>>>>
>>>>> If it is not connected, then the user is going to have to make 
>>>>> adjustments to the time and date occasionally anyway, as there is 
>>>>> always drift 
>>>>
>>>> Drifts? By using a 32.768kHz quartz to generate a 1 Hz clock that 
>>>> increases the internal counter avoid any drifts.
>>>
>>> There is no such thing as a 32.768 kHz crystal - there are only 
>>> approximate crystals.  If you don't update often enough from an 
>>> accurate time source, you will have drift.  (How much drift you have, 
>>> and what effect it has, is another matter.)
>>
>> Of course, the quartz has an accuracy that changes with life, 
>> temperature an so on. However the real accuracy doesn't allow the time 
>> drifting so much the user needs to reset the time.
>>
> 
> A standard cheap nominal 32.768 kHz is +/- 20 ppm.  That's 1.7 seconds 
> per day - assuming everything in the hardware is good.  Often that's 
> good enough, but sometimes it is not.  Only you can answer that one.

It's enough.


>>>> - they can
>>>>> do the daylight saving change at the same time as they change their 
>>>>> analogue clocks, their cooker clock, and everything else that is 
>>>>> not connected.
>>>>
>>>> I think you can take into account dst even if the device is not 
>>>> connected.
>>>>
>>>
>>> You certainly can.  But then you have to have a fixed algorithm known 
>>> in advance.
>>>
>>>> I bet Windows is able to show the correct time (with dst changes) 
>>>> even if the PC is not connected.
>>>
>>> I bet it can't, in cases where the date system for the daylight 
>>> savings time has changed or been removed.  Other than that, it will 
>>> just use a table of date systems such as on the Wikipedia page.  Or 
>>> perhaps MS simply redefined what they think other people should use.
>>>
>>> Older Windows needed manual changes for the date and time, even when 
>>> it was connected - their support for NTP was late.
>>
>> Maybe Windows is not able, but I'm reading Linux is. It saves the time 
>> as UTC on the hw RTC and shows it to the user as localtime, of course 
>> applying dst and timezone rules from a database of rules.
> 
> Yes, Linux has had NTP, timezones and daylight savings since its early 
> days (as have other *nix OS's).
> 
>>
>> So, as long as the timezone/dst info for my timezone is correct, I 
>> think Linux could manage dst changes automatically without user activity.
>>
>> My approach is identical to what Linux does.

[toc] | [prev] | [next] | [standalone]


#32363

FromDavid Brown <david.brown@hesbynett.no>
Date2025-03-14 14:20 +0100
Message-ID<vr1afo$19unh$2@dont-email.me>
In reply to#32362
On 14/03/2025 13:27, pozz wrote:
> Il 13/03/2025 16:51, David Brown ha scritto:
>> On 13/03/2025 09:57, pozz wrote:
>>> Il 12/03/2025 19:18, David Brown ha scritto:
>>>> On 12/03/2025 18:13, pozz wrote:

>>> Ok, but I don't understand why you prefer to write your own code 
>>> (yes, you're an exper programmer, but you can introduce some bugs, 
>>> you have to write  some tests), while there are standard functions 
>>> that make the job for you.
>>>
>>
>> I prefer to use a newer version of the toolchain that does not have 
>> such problems :-)
> 
> Sure, but the project is old. I will check if using a newer toolchain is 
> a feasible solution for this project.
> 

I fully appreciate - and agree with - not wanting to change toolchains 
on an existing established project.  It might be the best solution here, 
but it is certainly not one to be picked lightly.

> 
>> I am quite happy to re-use known good standard functions.  There is no 
>> need to reinvent the wheel if you already have one conveniently 
>> available.  But you don't have standard functions conveniently 
>> available here - the ones from your toolchain are not up to the task, 
>> and you are not happy with the other sources you have found for the 
>> standard functions.
>>
>> So once you have eliminated the possibility of using pre-written 
>> standard functions, you then need to re-evaluate what you actually 
>> need.   And that is much less than the standard functions provide.  So 
>> write your own versions to do what you need to do - no more, no less.
> 
> I agree with you. I thought you were suggesting to use custom made 
> functions in any case, because my approach that uses time_t counter 
> (seconds from epoch) and localtime()/mktime() isn't good.
> 

No.  I am merely saying that if you can't use the standard functions and 
have to get other ones from somewhere (or write them yourself), making 
them match standard function interfaces is of no benefit.  There are 
many alternative formats that could be better for your use.

> 
>> 2. Use an implementation from other library sources online.  You've 
>> ruled those out as too complicated.
> 
> In the past I sometimes lurked in the newlib code and it seems too 
> complicated for me. I will search for other simple implementations of 
> localtime()/mktime().
> 

There are other C standard libraries around - maybe others are better 
than newlib for this purpose.  (I don't know if newlib nano is mixed in 
with newlib here.)  Newlib sources are, at least in parts, a monstrosity 
of conditional compilation to support vast numbers of targets, 
compilers, OS's, and options.

> 
>> 3. Write your own functions.  Yes, that involves a certain amount of 
>> work, testing and risk.  That's your job.
>>
>> Am I missing anything?
> 
> I don't think.
> 

I really hope you missed a word in that sentence :-)

[toc] | [prev] | [next] | [standalone]


#32351

Frompozz <pozzugno@gmail.com>
Date2025-03-12 08:44 +0100
Message-ID<vqre18$2g8c8$1@dont-email.me>
In reply to#32349
Il 11/03/2025 17:32, David Brown ha scritto:
[...]
> For anything other than a quick demo, my preferred setup 
> is using makefiles for the build along with an ARM gcc toolchain.  That 
> way I can always build my software, from any system, and archive the 
> toolchain.  
[...]

Regading this point, it's what I want to do in new projects. What I 
don't know is...

Why many silicon vendors provide a *custom* arm gcc toolchain? Are those 
customizations important to build firmware for their MCUs? If not, why 
they invest money to make changes in a toolchain? It isn't a simple job.

Another point is visual debugging. I don't mean text editor with syntax 
hilighting, code completion, project management and so on. There are 
many tools around for this.
I used to have a button in the IDE to launch a debugging session. The 
generation of a good debugging session configuration is simplified in 
IDE if you use main debuggin probe (for example, J-Link).

How do you debug your projects without a full-features and ready-to-use 
IDE from the silicon vendor?

[toc] | [prev] | [next] | [standalone]


#32353

FromDavid Brown <david.brown@hesbynett.no>
Date2025-03-12 11:14 +0100
Message-ID<vqrmq4$2i773$1@dont-email.me>
In reply to#32351
On 12/03/2025 08:44, pozz wrote:
> Il 11/03/2025 17:32, David Brown ha scritto:
> [...]
>> For anything other than a quick demo, my preferred setup is using 
>> makefiles for the build along with an ARM gcc toolchain.  That way I 
>> can always build my software, from any system, and archive the toolchain. 
> [...]
> 
> Regading this point, it's what I want to do in new projects. What I 
> don't know is...
> 
> Why many silicon vendors provide a *custom* arm gcc toolchain? Are those 
> customizations important to build firmware for their MCUs? If not, why 
> they invest money to make changes in a toolchain? It isn't a simple job.
> 

Some changes are reasonable.  A prime example is support for newer 
devices - or workarounds for bugs in existing devices.  The ideal way to 
handle this sort of thing, as done by a number of suppliers, is to 
figure out a fix and push it upstream.

Full upstream projects - primarily GCC and binutils - will generally add 
these in to their current development line.  They will generally only 
add it in to previous lines if the changes are small, fairly clean 
patches, important for code correctness, and don't require changes in 
additional areas (such as command-line options or documentation).  Even 
then, they only go a few releases back.

The main next-step upstream project for ARM GCC tools is ARM's GCC 
toolchain - they can be a bit more flexible, and maintain a list of 
patches that go on top of GCC and binutils releases so that such fixes 
can be back-ported to older sets.  Their releases are always a bit 
behind upstream mainline, because they need time to do their testing and 
packaging.

Finally, some microcontroller manufacturers will have their own packed 
builds based on ARM's builds.  (Other intermediaries used to be popular 
before, such as Code Sourcery, but I think ARM's builds are now 
ubiquitous.)  They can react faster to adding fixes and patches to 
existing code - they don't need to think about conflicts or testing with 
other people's ARM cores, for example.  But again, their releases will 
be even further behind mainline because they must be tested against all 
their SDK's and other code.

These sorts of things are all good for the user, good for the community 
as a whole, and good for the manufacturer - they can make quick fixes if 
they have to, but in the long term they keep aligned with mainline.


But some vendors - such as Microchip - put a great deal of effort into 
re-branding.  They are looking for marketing, control, and forced tie-in 
- they want it to be as hard as possible to move to other vendors.  And 
they can have PHB's that think the development tool department of the 
company should make a profit on its own, rather than be there to support 
sales from the device production - thus they try to force developers to 
pay for licenses.  IMHO this is all counter-productive - I am sure I am 
not the only developer who would not consider using microcontrollers 
from Microchip unless there was no other option.  (I am happy to use 
other parts from Microchip - they make good devices.)


> Another point is visual debugging. I don't mean text editor with syntax 
> hilighting, code completion, project management and so on. There are 
> many tools around for this.
> I used to have a button in the IDE to launch a debugging session. The 
> generation of a good debugging session configuration is simplified in 
> IDE if you use main debuggin probe (for example, J-Link).
> 
> How do you debug your projects without a full-features and ready-to-use 
> IDE from the silicon vendor?

That varies from project to project, part to part.  But I am quite happy 
to use an IDE from a vendor while using an external makefile and a 
standard GNU ARM toolchain for the build.


[toc] | [prev] | [next] | [standalone]


#32360

Fromantispam@fricas.org (Waldek Hebisch)
Date2025-03-14 01:48 +0000
Message-ID<vr01sl$cpvn$2@paganini.bofh.team>
In reply to#32351
pozz <pozzugno@gmail.com> wrote:
> 
> How do you debug your projects without a full-features and ready-to-use 
> IDE from the silicon vendor?

With STM devices I use Linux 'stlink' program and gdb.  That is
command line debugging.  I can set breakpoints, single step,
view and and modify device registers, those are main things
that I need.  I also use debugging UART.  For debugging I
normally load code into RAM which means that I can have
unlimited number of breakpoints without writning to flash
(I am not sure if that is really important, but at least
makes me feel better).

I have also used stlink with some non-STM devices (IIRC LPC),
but that required modification to 'stlink' code and IIUC
use of of non-STM devices is blocked in new firmware for
the debugging dongle.

'gdb' can be used with many other debugging dongles.

Visual tools may be nicer and automatically do some extra
things.  But I got used to gdb.

-- 
                              Waldek Hebisch

[toc] | [prev] | [next] | [standalone]


#32361

Frompozz <pozzugno@gmail.com>
Date2025-03-14 08:36 +0100
Message-ID<vr0m9l$rtjt$1@dont-email.me>
In reply to#32360
Il 14/03/2025 02:48, Waldek Hebisch ha scritto:
> pozz <pozzugno@gmail.com> wrote:
>>
>> How do you debug your projects without a full-features and ready-to-use
>> IDE from the silicon vendor?
> 
> With STM devices I use Linux 'stlink' program and gdb.  That is
> command line debugging.  I can set breakpoints, single step,
> view and and modify device registers, those are main things
> that I need.  I also use debugging UART.  For debugging I
> normally load code into RAM which means that I can have
> unlimited number of breakpoints without writning to flash
> (I am not sure if that is really important, but at least
> makes me feel better).
> 
> I have also used stlink with some non-STM devices (IIRC LPC),
> but that required modification to 'stlink' code and IIUC
> use of of non-STM devices is blocked in new firmware for
> the debugging dongle.
> 
> 'gdb' can be used with many other debugging dongles.
> 
> Visual tools may be nicer and automatically do some extra
> things.  But I got used to gdb.

I always used visual debuggers. I know they generally uses gdb 
internally, but I don't know how.

I'm feeling better when I use mouse, point on a variable in the code and 
see its content. And similar things.

I'm sure it's possible to let a generic IDE (like Visual Studio Code) 
permforms visual debugging session with J-Link (or similar probes), but 
you have to install/configure many things to reach a functional system.

I'm going to try when I have free time... free time? What is it?

[toc] | [prev] | [next] | [standalone]


#32364

FromMichael Schwingen <news-1513678000@discworld.dascon.de>
Date2025-03-15 16:30 +0000
Message-ID<slrnvtbaot.sal.news-1513678000@a-tuin.ms.intern>
In reply to#32349
On 2025-03-11, David Brown <david.brown@hesbynett.no> wrote:
> package as-is.  For anything other than a quick demo, my preferred setup 
> is using makefiles for the build along with an ARM gcc toolchain.  That 
> way I can always build my software, from any system, and archive the 
> toolchain.  (One day, I will also try using clang with these packages, 
> but I haven't done so yet.)

Same here.  I just switched to ARM gcc + picolibc for all my ARM projects -
this required some changes in the way my makefiles generate linker scripts
and startup code, and now I am quite happy with that setup.


I have one project where I needed custom time functions: a nixie clock that
has both a RTC (with seconds/minutes/... registers), and NTP to get current
time. NTP time is seconds since 1.1.1900 and UTC.

The sane approach to handling timezones and DST is the unix way: keep
everything in UTC internally and convert to localtime when displaying the
time.  To set the RTC, that requires a version of mktime that does *not* do
timezone conversion - I simply pulled mktime from the newlib sources and
removed the timezone stuff - done.  You could write that stuff yourself, but
getting all the corner cases right will take some time.  The existing code
is there and works fine.

cu
Michael
-- 
Some people have no respect of age unless it is bottled.

[toc] | [prev] | [next] | [standalone]


#32365

FromGrant Edwards <invalid@invalid.invalid>
Date2025-03-15 17:02 +0000
Message-ID<vr4bqc$1sg$1@reader1.panix.com>
In reply to#32364
On 2025-03-15, Michael Schwingen <news-1513678000@discworld.dascon.de> wrote:
> On 2025-03-11, David Brown <david.brown@hesbynett.no> wrote:
>> package as-is.  For anything other than a quick demo, my preferred setup 
>> is using makefiles for the build along with an ARM gcc toolchain.  That 
>> way I can always build my software, from any system, and archive the 
>> toolchain.  (One day, I will also try using clang with these packages, 
>> but I haven't done so yet.)
>
> Same here.  I just switched to ARM gcc + picolibc for all my ARM projects -
> this required some changes in the way my makefiles generate linker scripts
> and startup code, and now I am quite happy with that setup.

Yep. IMO, that's definitely the "One True Answer" for embedded
development.

I worked with a guy who wanted to use Eclipse for embedded
development. After _months_ of f&*king around, he was finally able to
build a binary that worked.

But trying to build that Eclipse "project" on another computer (same
OS, same version of Eclips, same toolchain) was a complete failure.

I finally told him it was fine if he wanted to use Eclipse as his
editor, gdb front-end, SVN gui, filesystem browser, office-cleaner and
nose-wiper. But it was a non-negotiable requirement that it be
possible to check the source tree and toolchain out of SVN, type
"make", hit enter, and end up with a working binary.

--
Grant

[toc] | [prev] | [next] | [standalone]


#32366

FromMichael Schwingen <news-1513678000@discworld.dascon.de>
Date2025-03-15 23:26 +0000
Message-ID<slrnvtc35p.sal.news-1513678000@a-tuin.ms.intern>
In reply to#32365
On 2025-03-15, Grant Edwards <invalid@invalid.invalid> wrote:
> I finally told him it was fine if he wanted to use Eclipse as his
> editor, gdb front-end, SVN gui, filesystem browser, office-cleaner and
> nose-wiper. But it was a non-negotiable requirement that it be
> possible to check the source tree and toolchain out of SVN, type
> "make", hit enter, and end up with a working binary.

Yes, we do that at work - build using makefiles, and some colleagues use
eclipse as their editor/debugger. I prefer emacs / ddd.

Getting reproducable build results using eclipse (or some vendor-patched
eclipse) is a PITA.

cu
Michael
-- 
Some people have no respect of age unless it is bottled.

[toc] | [prev] | [next] | [standalone]


#32367

Frompozz <pozzugno@gmail.com>
Date2025-03-18 09:21 +0100
Message-ID<vrbado$2133a$1@dont-email.me>
In reply to#32364
Il 15/03/2025 17:30, Michael Schwingen ha scritto:
> On 2025-03-11, David Brown <david.brown@hesbynett.no> wrote:
>> package as-is.  For anything other than a quick demo, my preferred setup
>> is using makefiles for the build along with an ARM gcc toolchain.  That
>> way I can always build my software, from any system, and archive the
>> toolchain.  (One day, I will also try using clang with these packages,
>> but I haven't done so yet.)
> 
> Same here.  I just switched to ARM gcc + picolibc for all my ARM projects -
> this required some changes in the way my makefiles generate linker scripts
> and startup code, and now I am quite happy with that setup.

One day or another I will try to move from my actual build system (that 
depends on silicon vendor IDE, libraries, middleware, drivers, and so 
on) to a generic makefile and generic toolchain.

Sincerely I tried in the past with some issues. First of all, I use a 
Windows machine for development and writing makefiles that work on 
Windows is not simple. Maybe next time I will try with WSL, writing 
makefiles that work directly in Unix.

Another problem that I see is the complexity of actual projects: TCP/IP 
stack, cripto libraries, drivers, RTOS, and so on. Silicon vendors 
usually give you several example projects that just works with one 
click, using their IDE, libraries, debuggers, and so on. Moving from 
this complex build system to custom makefiles and toolchain isn't so simple.

Suppose you make the job to "transform" the example project into a 
makefile. You start working with your preferred IDE/text 
editor/toolchain, you are happy.
After some months the requirements change and you need to add a driver 
for a new peripheral or a complex library. You know there are 
ready-to-use example projects in the original IDE from silicon vendor 
that use exactly what you need (mbedtls, DMA, ADC...), but you can't use 
them because you changed your build system.

Another problem is debugging: launch a debug sessions that means 
download the binary through a USB debugger/probe and SWD port, add some 
breakpoints, see the actual values of some variables and so on. All this 
works very well without big issues if using original IDE. Are you able 
to configure *your* custom development system to launch debug sessions?

Eventually another question. Silicon vendors usually provide custom 
toolchains that often are a customized version of arm-gcc toolchian 
(yes, here I'm talking about Cortex-M MCUs only, otherwise it would be 
much more complex).
What happens if I move to the generic arm-gcc?


> I have one project where I needed custom time functions: a nixie clock that
> has both a RTC (with seconds/minutes/... registers), and NTP to get current
> time. NTP time is seconds since 1.1.1900 and UTC.
> 
> The sane approach to handling timezones and DST is the unix way: keep
> everything in UTC internally and convert to localtime when displaying the
> time.  To set the RTC, that requires a version of mktime that does *not* do
> timezone conversion - I simply pulled mktime from the newlib sources and
> removed the timezone stuff - done.  You could write that stuff yourself, but
> getting all the corner cases right will take some time.  The existing code
> is there and works fine.

This is exactly what I do. I don't use RTC with registers (seconds, 
minutes...) anymore, only a 32.768kHz oscillator (present in many MCUs) 
that increments a counter.

[toc] | [prev] | [next] | [standalone]


Page 1 of 3  [1] 2 3  Next page →

Back to top | Article view | comp.arch.embedded


csiph-web