librtc - Manipuler le temps, pas l'espace
Posté le 24/05/2016 13:39
Ce projet est sur la forge de PC - Version actuelle : 1.0
Introduction
Comme j'étais dans un effort de simplifier encore le développement sous Linux avec des libs statiques et que je bidouillais le C-Engine, j'ai remarqué qu'il avait des fonctions que je trouvais pas très propres pour bidouiller la RTC : c'est pourquoi j'ai décidé d'en faire une lib, pour centraliser les efforts.
La RTC, késako ?
La Real-Time Clock est un simple compteur incrémenté régulièrement (64 fois par seconde) par un oscillateur. C'est un module qui tourne indépendemment du processeur.
Histoire de le préciser, cet oscillateur n'est pas magique, et a besoin de batterie pour continuer de tourner. Si vous enlevez les piles ou si elles sont mortes, il arrêtera de tourner, et peut-être que le compteur se réinitialisera : dans tous les cas, celle-ci peut se dérégler.
De plus, il n'y a pas de gestion native du fuseau horaire, ni même au niveau du système, donc l'heure est en GMT par défaut. Donc gardez à l'esprit, si votre addin utilise cette lib, qu'il y a des chances que la RTC contienne n'importe quoi à son lancement. Demandez à l'utilisateur de confirmer l'heure au lancement si vous souhaitez ne pas avoir de surprises.
Interface
Pour utiliser la librtc, pensez à inclure son header avec
#include <rtc.h> et à l'ajouter au linker avec
-lrtc (une fois installée).
Avant toute utilisation de la RTC, il faut l'initialiser :
rtc_init();
Cette initialisation ne doit être faite qu'
une seule fois pendant tout le programme. Elle retourne si tout va bien, i.e. si le microprocesseur est reconnu (la librtc se servant directement du matériel, sans appels système).
Ensuite, pour obtenir la date, prenez déjà connaissance de la structure suivante :
typedef struct {
int hz64;
int sec;
int min;
int hour;
int wday;
int day;
int month;
int year;
} rtc_date_t;
Ensuite, pour obtenir la date actuelle de la RTC, il vous suffit de la récupérer via :
rtc_date_t date = rtc_getdate();
Pour obtenir le timestamp (i.e. le nombre de secondes passées depuis
le 1er janvier 1970 à minuit), il vous suffit de faire :
unsigned int time = rtc_gettime();
Pour obtenir le nombre approximatif de millisecondes passées depuis le démarrage du programme (la fonction qui vous intéressera sans doute), vous pouvez ainsi faire :
unsigned int ticks = rtc_getticks();
Maintenant, si ce que vous voulez faire, c'est régler l'heure, deux fonctions risquent de vous intéresser :
rtc_settime(time); // régler le temps à l'aide d'un timestamp UNIX
rtc_setdate(date); // régler le temps à l'aide d'une date
Je vous conseille d'utiliser les fonctions getdate et setdate que celles utilisant des timestamps, étant donné que le compteur de la RTC est sous forme de date -- cela étant, vous avez le choix.
Aussi, si vous modifiez la date, vous risquez fort de vous en foutre du jour de la semaine (week day) alors qu'il peut être intéressant de le garder correct. Du coup, n'hésitez pas à le passer à la fonction
rtc_adjustwday qui fait ça pour vous :
rtc_date_t date = rtc_getdate();
// on modifie
rtc_adjustwday(&date);
rtc_setdate(date);
Quelques fonctions de conversion sont également disponibles :
rtc_date_t date2 = rtc_dateoftime(time);
unsigned int time2 = rtc_timeofdate(date);
Pour le moment, c'est tout.
A priori, rien à venir. Des propositions pas hors-sujet ?
Citer : Posté le 01/09/2018 12:32 | #
Parfait, voilà un diff
+++ librtc.new/public/src/getdate.c 2018-09-01 12:30:07.544791093 +0200
@@ -35,14 +35,19 @@
rtc_date_t date;
// copy as quickly as possible
- snap.year = _rtc_cnt->year;
- snap.month = _rtc_cnt->month;
- snap.wday = _rtc_cnt->wday;
- snap.day = _rtc_cnt->day;
- snap.hour = _rtc_cnt->hour;
- snap.min = _rtc_cnt->min;
- snap.sec = _rtc_cnt->sec;
- snap.hz64 = _rtc_cnt->hz64;
+ do {
+ _rtc_cr1->c.CF = 0;
+
+ snap.year = _rtc_cnt->year;
+ snap.month = _rtc_cnt->month;
+ snap.wday = _rtc_cnt->wday;
+ snap.day = _rtc_cnt->day;
+ snap.hour = _rtc_cnt->hour;
+ snap.min = _rtc_cnt->min;
+ snap.sec = _rtc_cnt->sec;
+ snap.hz64 = _rtc_cnt->hz64;
+ }
+ while(_rtc_cr1->c.CF != 0);
// get from snap
date.year = intofbcd16(snap.year); // 0000 to 9999
diff -ru librtc.old/public/src/setdate.c librtc/public/src/setdate.c
--- librtc.old/public/src/setdate.c 2018-09-01 12:25:45.867481880 +0200
+++ librtc.new/public/src/setdate.c 2018-09-01 12:30:17.510847530 +0200
@@ -31,19 +31,18 @@
void rtc_setdate(rtc_date_t date)
{
- // halt RTC
- _rtc_cr2->c.START = 0;
-
// set RTC fields
- _rtc_cnt->hz64 = (uint8bswp(date.hz64) >> 1);
- _rtc_cnt->sec = bcd8ofint(date.sec);
- _rtc_cnt->min = bcd8ofint(date.min);
- _rtc_cnt->hour = bcd8ofint(date.hour);
- _rtc_cnt->wday = bcd8ofint(date.wday);
- _rtc_cnt->day = bcd8ofint(date.day);
- _rtc_cnt->month = bcd8ofint(date.month);
- _rtc_cnt->year = bcd16ofint(date.year);
+ do {
+ _rtc_cr1->c.CF = 0;
- // restart RTC
- _rtc_cr2->c.START = 1;
+ _rtc_cnt->hz64 = (uint8bswp(date.hz64) >> 1);
+ _rtc_cnt->sec = bcd8ofint(date.sec);
+ _rtc_cnt->min = bcd8ofint(date.min);
+ _rtc_cnt->hour = bcd8ofint(date.hour);
+ _rtc_cnt->wday = bcd8ofint(date.wday);
+ _rtc_cnt->day = bcd8ofint(date.day);
+ _rtc_cnt->month = bcd8ofint(date.month);
+ _rtc_cnt->year = bcd16ofint(date.year);
+ }
+ while(_rtc_cr1->c.CF != 0);
}
Citer : Posté le 29/07/2024 12:22 | #
Réuploadée ici, pour des raisons d'archivage :
https://git.planet-casio.com/cake/librtc
Mon blog ⋅ Mes autres projets
Citer : Posté le 29/07/2024 14:11 | #
Comment tu gères les secondes intercalaires ? :troll:
Citer : Posté le 29/07/2024 14:13 | #
* internal screaming *
Mon blog ⋅ Mes autres projets