FULL-C: time functions: Porovnání verzí
Řádek 11: | Řádek 11: | ||
Za účelem převodu jsou k dispozici tyto funkce: | Za účelem převodu jsou k dispozici tyto funkce: | ||
<pre> | <pre> | ||
+ | |||
+ | POZOR - tyto C funkce jsou dostupné až pro firmware od 11.7.2022 | ||
+ | |||
unsigned int mktime(void * timeptr); | unsigned int mktime(void * timeptr); | ||
void gmtime(unsigned int * timer, void * timeptr); | void gmtime(unsigned int * timer, void * timeptr); | ||
void localtime(unsigned int * timer, void * timeptr); | void localtime(unsigned int * timer, void * timeptr); | ||
+ | |||
+ | POZOR - tyto C funkce jsou dostupné až pro firmware od 17.11.2022 | ||
+ | |||
+ | int SDS_set_RTC(void * timeptr, unsigned int epochtime); | ||
+ | |||
</pre> | </pre> | ||
Řádek 38: | Řádek 46: | ||
}; | }; | ||
− | * tm_isdst : pouze pro čtení, vyplněno funkcí localtime() a gmtime(), hodnota je ignorována funkcí mktime() | + | Detaily: |
− | * tm_gmtoff : pouze pro čtení, vyplněno funkcí localtime() a gmtime(), hodnota je ignorována funkcí mktime() | + | * tm_isdst : pouze pro čtení, vyplněno funkcí localtime() a gmtime(), hodnota je ignorována funkcí mktime() a SDS_set_RTC() |
+ | * tm_gmtoff : pouze pro čtení, vyplněno funkcí localtime() a gmtime(), hodnota je ignorována funkcí mktime() a SDS_set_RTC() | ||
Řádek 46: | Řádek 55: | ||
SDS primárně využívá NTP pro pravidelnou časovou synchronizaci. SDS tedy pravidelně pomocí NTP aktualizuje svůj interní čas, který udržuje platný. | SDS primárně využívá NTP pro pravidelnou časovou synchronizaci. SDS tedy pravidelně pomocí NTP aktualizuje svůj interní čas, který udržuje platný. | ||
− | + | V základu, interně, je čas v SDS udržován jako hodnota EPOCH (UTC + 0), tedy počet sekund od pevného epoch data. | |
Uživatel může nastavit offset (v hodinách) vůči UTC a také zapnout automatický posun pro letní čas (dle pravidel CEST / CET). | Uživatel může nastavit offset (v hodinách) vůči UTC a také zapnout automatický posun pro letní čas (dle pravidel CEST / CET). | ||
− | V případě, že nechcete aby SDS využívalo NTP, lze NTP v nastavení vypnout. Čas pak musíte celému systému dodat sami, zápisem do příslušných indexů (viz seznam). Typicky se toto používá pokud získáváte čas z jiných zdrojů (GSM/LTE nebo např. LoRA síť). | + | Program může získat z SDS tento základní EPOCH čas (odpovídající 1:1 (bez posunů) tomu co přichází z NTP), nebo tzv. místní (LOKÁLNÍ) čas (což je upravený - posunutý - čas o uživatelem nastavený offset a také o automatický posun letního času). |
+ | |||
+ | Oba tyto časy jsou dostupné pro váš FC program, a modul SDS se stará aby oba byly trvale aktální. | ||
+ | |||
+ | V případě, že nechcete aby SDS využívalo NTP, lze NTP v nastavení vypnout. Čas pak musíte celému systému dodat sami, zápisem do příslušných indexů (viz seznam). Typicky se toto používá pokud získáváte čas z jiných zdrojů (GSM/LTE nebo např. LoRA síť), nebo pokud používáte externí zálohované RTC (neplatí pro BIG2-DP-DS84 které má interní RTC zálohované baterií). | ||
+ | |||
+ | |||
+ | Základní principu údržby času v SDS: | ||
+ | |||
+ | +------------------+ | ||
+ | | přečtení obsahu | | ||
+ | | RTC po bootu SDS | (pouze ale pokud v RTC je platný čas - pozor!) | ||
+ | +------------------+ | ||
+ | .... . | ||
+ | . . . | ||
+ | . . . | ||
+ | +------------------------------------+ +----------------+ +-----------+ | ||
+ | | pravidelné dotazy na NTP server | "epoch NTP UTC čas" | interní HW RTC | zpracování | + offset | | ||
+ | | (provádí SDS NTP klient) |-------------------------->| v SDS modulu | -------------->| + DST | | ||
+ | +--+---------------------------------+ +----+-----------+ +---+-------+ | ||
+ | | | | | ||
+ | +----> GET index 44 : stav +----> GET index 139 : epoch +----> GET index 4 : local time (modified epoch) | ||
+ | indexy 5 .. 11 : local time (items) | ||
+ | |||
+ | Program tedy může sledovat, jestli se povedlo přes NTP protokol získat čas z NTP serveru. Dále může program sledovat, jestli po zapnutí se povedlo z interního HW RTC (vnitřní RTC v základu SDS) získat čas (např. pokud SDS prošlo restartem, je čas zachován). | ||
+ | |||
+ | Upozorňuji na dva typy interních RTC v SDS modulu. Pouze modul typu "SDS-BIG2-DP-DS84" má RTC zálohované baterií, ostatní moduly ne. Proto, pokud potřebujete funkci zálohovaného RTC i u ostatních modulů SDS, musíte připojit externí doplňující RTC (viz nabídka doplňujících modulů), a doplnit si potřebnou obsluhu do svého programu.- | ||
+ | |||
+ | Paralelně s tímto je v SDS udržováno počítadlo "doby běhu od spuštění" tzv. UpTime. Toto počítadlo se nuluje při každém restartu firmware (libovolný důvod), a také při překročení hodnoty (počítá do 2^32). | ||
+ | |||
+ | UpTime počítadla jsou záměrně udržovány dvě nezávislé (ale jsou nulovány společně při startu - ale '''nejsou''' nulovány společně při přetečení jednoho z nich, to je důležitá informace). Jedno počítadlo je zvyšováno s krokem 1 msec, a druhé s krokem (co) 10 msec. Počítadlo s krokem 1 msec přeteče dříve než to s krokem 10 msec, takže se dá snadno identifikovat tato situace (porovnáním obou počítadel). | ||
+ | |||
+ | Využití UpTime je v programech kritické, zejména pro sledování běhu programu, pro funkce odpočtu (neblokující čekání), a také zejména pro výpisy ladících informací (krátká časová značka). | ||
Řádek 77: | Řádek 118: | ||
− | == | + | == Příklad == |
Následující příklad přečte UTC EPOCH čas ze systému (index 139) a převede to na jednotlivé položky do struktury tmp (definována jako: struct tm). | Následující příklad přečte UTC EPOCH čas ze systému (index 139) a převede to na jednotlivé položky do struktury tmp (definována jako: struct tm). | ||
Řádek 99: | Řádek 140: | ||
void main(void) | void main(void) | ||
{ | { | ||
− | unsigned int | + | unsigned int timeUTC; |
struct tm tmp; | struct tm tmp; | ||
− | printf("time | + | printf("time conversion test - localtime()\n"); |
// get NTP UTC time | // get NTP UTC time | ||
− | + | timeUTC = SDS_get_u32(139); | |
+ | // or try to put any different value to "timeUTC" to test this | ||
+ | |||
+ | // local conversion | ||
localtime(&systemUTC, (void *)&tmp); | localtime(&systemUTC, (void *)&tmp); | ||
− | printf("% | + | printf("%02d:%02d:%02d\n", tmp.tm_hour, tmp.tm_min, tmp.tm_sec); |
− | printf("% | + | printf("%d.%d.%d\n", tmp.tm_mday, tmp.tm_mon+1, tmp.tm_year+1900); |
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | == SDS_set_RTC() == | ||
+ | |||
+ | Společná funkce pro zápis času, do interního RTC v modulu SDS. Zavoláním této funkce jsou zapsány vždy všechny položky (tzn. celý čas a datum), nelze touto funkcí zapisovat jednotlivé položky samostatně. |
Verze z 17. 11. 2022, 19:28
Tato stránka popisuje programovací jazyk FULL-C, který je dostupný na vybraných zařízeních SDS. Některá zařízení používají SDS-C, pro který máme návody jinde na této WiKi.
Funkce pro převod časových struktur
POZOR - tyto C funkce jsou dostupné až pro firmware od 11.7.2022
Zařízení SDS pracuje s různou reprezentací časové značky - ta může být poskytována a zpracována jako počet sekund od určeného data (tzv. EPOCH čas), nebo v "položkově-rozpadnuté" formě ve formě jednotlivých časových údajů (hodina, minuta, sekunda atd.), uložených ve společné struktuře.
Za účelem převodu jsou k dispozici tyto funkce:
POZOR - tyto C funkce jsou dostupné až pro firmware od 11.7.2022 unsigned int mktime(void * timeptr); void gmtime(unsigned int * timer, void * timeptr); void localtime(unsigned int * timer, void * timeptr); POZOR - tyto C funkce jsou dostupné až pro firmware od 17.11.2022 int SDS_set_RTC(void * timeptr, unsigned int epochtime);
Struktura "tm"
Položky označené jako " * timeptr " jsou ukazatele na strukturu tm.
Struktura tm je pro účely FULL-C, definována takto:
struct tm { int tm_sec; // seconds after the minute [0-60] int tm_min; // minutes after the hour [0-59] int tm_hour; // hours since midnight [0-23] int tm_mday; // day of the month [1-31] int tm_mon; // months since January [0-11] int tm_year; // years since 1900 int tm_wday; // days since Sunday [0-6] int tm_yday; // days since January 1 [0-365] // int tm_isdst; // Daylight Saving Time flag int tm_gmtoff; // offset from UTC in seconds };
Detaily:
- tm_isdst : pouze pro čtení, vyplněno funkcí localtime() a gmtime(), hodnota je ignorována funkcí mktime() a SDS_set_RTC()
- tm_gmtoff : pouze pro čtení, vyplněno funkcí localtime() a gmtime(), hodnota je ignorována funkcí mktime() a SDS_set_RTC()
Čas v SDS
SDS primárně využívá NTP pro pravidelnou časovou synchronizaci. SDS tedy pravidelně pomocí NTP aktualizuje svůj interní čas, který udržuje platný.
V základu, interně, je čas v SDS udržován jako hodnota EPOCH (UTC + 0), tedy počet sekund od pevného epoch data.
Uživatel může nastavit offset (v hodinách) vůči UTC a také zapnout automatický posun pro letní čas (dle pravidel CEST / CET).
Program může získat z SDS tento základní EPOCH čas (odpovídající 1:1 (bez posunů) tomu co přichází z NTP), nebo tzv. místní (LOKÁLNÍ) čas (což je upravený - posunutý - čas o uživatelem nastavený offset a také o automatický posun letního času).
Oba tyto časy jsou dostupné pro váš FC program, a modul SDS se stará aby oba byly trvale aktální.
V případě, že nechcete aby SDS využívalo NTP, lze NTP v nastavení vypnout. Čas pak musíte celému systému dodat sami, zápisem do příslušných indexů (viz seznam). Typicky se toto používá pokud získáváte čas z jiných zdrojů (GSM/LTE nebo např. LoRA síť), nebo pokud používáte externí zálohované RTC (neplatí pro BIG2-DP-DS84 které má interní RTC zálohované baterií).
Základní principu údržby času v SDS:
+------------------+ | přečtení obsahu | | RTC po bootu SDS | (pouze ale pokud v RTC je platný čas - pozor!) +------------------+ .... . . . . . . . +------------------------------------+ +----------------+ +-----------+ | pravidelné dotazy na NTP server | "epoch NTP UTC čas" | interní HW RTC | zpracování | + offset | | (provádí SDS NTP klient) |-------------------------->| v SDS modulu | -------------->| + DST | +--+---------------------------------+ +----+-----------+ +---+-------+ | | | +----> GET index 44 : stav +----> GET index 139 : epoch +----> GET index 4 : local time (modified epoch) indexy 5 .. 11 : local time (items)
Program tedy může sledovat, jestli se povedlo přes NTP protokol získat čas z NTP serveru. Dále může program sledovat, jestli po zapnutí se povedlo z interního HW RTC (vnitřní RTC v základu SDS) získat čas (např. pokud SDS prošlo restartem, je čas zachován).
Upozorňuji na dva typy interních RTC v SDS modulu. Pouze modul typu "SDS-BIG2-DP-DS84" má RTC zálohované baterií, ostatní moduly ne. Proto, pokud potřebujete funkci zálohovaného RTC i u ostatních modulů SDS, musíte připojit externí doplňující RTC (viz nabídka doplňujících modulů), a doplnit si potřebnou obsluhu do svého programu.-
Paralelně s tímto je v SDS udržováno počítadlo "doby běhu od spuštění" tzv. UpTime. Toto počítadlo se nuluje při každém restartu firmware (libovolný důvod), a také při překročení hodnoty (počítá do 2^32).
UpTime počítadla jsou záměrně udržovány dvě nezávislé (ale jsou nulovány společně při startu - ale nejsou nulovány společně při přetečení jednoho z nich, to je důležitá informace). Jedno počítadlo je zvyšováno s krokem 1 msec, a druhé s krokem (co) 10 msec. Počítadlo s krokem 1 msec přeteče dříve než to s krokem 10 msec, takže se dá snadno identifikovat tato situace (porovnáním obou počítadel).
Využití UpTime je v programech kritické, zejména pro sledování běhu programu, pro funkce odpočtu (neblokující čekání), a také zejména pro výpisy ladících informací (krátká časová značka).
mktime()
Funkce mktime převede položkově rozpadnutý čas (obsah struktury tm) na epoch čas. Při převodu není aplikován jakýkoliv offset a není aplikován letní čas.
Epoch čas je často vyžadován např. pro známkování dat při přenosu po síti atd. - zejména protože se vždy vleze do 32 bitů, a tak zabírá minimum místa.
gmtime() a localtime()
Funkce převedou hodnotu ze vstupu (na který ukazuje "timer") na obsah struktury (na kterou ukazuje "timeptr").
gmtime() provede přímý "čistý" převod, tedy bez aplikace jakýchkoliv offsetů a posunů.
localtime() provede to samé co gmtime() ale s aplikací (1) letního času a za (2) nastaveného NTP offsetu. Letní čas je aplikován jen pouze pokud je právě aktivní (indikováno v tm_isdst, odpovídá hodnotě na indexu 65). Hodnota offsetu je zapsána do tm_gmtoff - jedná se o hodnotu nastavenou uživatelem v administraci (položka "NTP offset") - respektive lze číst jako proměnnou na indexu 26.
Pozn.: Aktuální systémový lokální čas (tedy UTC čas s aplikací letního času a offsetu) je k dispozici na indexu 4 - a rozpad pak na indexech 5 až 11, viz seznam všech položek.
Kde je funkce time() ?
Funkce time() není v SDS definována, protože UTC čas systému (tedy výstup takovéto funkce) získáte přímo čtením hodnoty na indexu 139.
Příklad
Následující příklad přečte UTC EPOCH čas ze systému (index 139) a převede to na jednotlivé položky do struktury tmp (definována jako: struct tm).
struct tm
{
int tm_sec; // seconds after the minute [0-60]
int tm_min; // minutes after the hour [0-59]
int tm_hour; // hours since midnight [0-23]
int tm_mday; // day of the month [1-31]
int tm_mon; // months since January [0-11]
int tm_year; // years since 1900
int tm_wday; // days since Sunday [0-6]
int tm_yday; // days since January 1 [0-365]
//
int tm_isdst; // Daylight Saving Time flag
int tm_gmtoff; // offset from UTC in seconds
};
void main(void)
{
unsigned int timeUTC;
struct tm tmp;
printf("time conversion test - localtime()\n");
// get NTP UTC time
timeUTC = SDS_get_u32(139);
// or try to put any different value to "timeUTC" to test this
// local conversion
localtime(&systemUTC, (void *)&tmp);
printf("%02d:%02d:%02d\n", tmp.tm_hour, tmp.tm_min, tmp.tm_sec);
printf("%d.%d.%d\n", tmp.tm_mday, tmp.tm_mon+1, tmp.tm_year+1900);
}
SDS_set_RTC()
Společná funkce pro zápis času, do interního RTC v modulu SDS. Zavoláním této funkce jsou zapsány vždy všechny položky (tzn. celý čas a datum), nelze touto funkcí zapisovat jednotlivé položky samostatně.