Les membres ayant 30 points peuvent parler sur les canaux annonces, projets et hs du chat.
La shoutbox n'est pas chargée par défaut pour des raisons de performances. Cliquez pour charger.

Forum Casio - Vos tutoriels et astuces


Index du Forum » Vos tutoriels et astuces » librtc - Manipuler le temps, pas l'espace
Cakeisalie5 En ligne Ancien administrateur Points: 1960 Défis: 11 Message

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 ?


1, 2 Suivante
Kirafi Hors ligne Membre Points: 2180 Défis: 10 Message

Citer : Posté le 24/05/2016 17:49 | #


On peut obtenir la date de manière automatique ?
Hum va falloir réfléchir à des jeux de gestion .
iPod
Pour des parties rapides
Jusqu'où pourras-tu aller dans ce jeu "partie rapide" qu'est Dextris (élu Jeu Du Mois)
Pourras-tu survivre plus de 20 secondes dans ce fameux tunnel appelé Graviton
Rebondis entre les murs en évitant les piques dans SpikeBird
Pourras-tu éviter de te faire écraser dans FallBlocs (élu Jeu Du Mois)
Autres
Franchement ils valent le coups
Deviens l'amiral de la marine dans SeaRush (jeu concours) (élu Jeu Du Mois)
La version 2048 tactile amélioré au plus haut point : 2048 Delux !
Pars à la recherche des morceaux d'étoile dans Lumyce (élu Jeu Du Mois)
Cakeisalie5 En ligne Ancien administrateur Points: 1960 Défis: 11 Message

Citer : Posté le 24/05/2016 17:59 | #


En fait, les compteurs du module RTC (Real-Time Clock) sont, tant en SH3 qu'en SH4, organisés en date (64-Hz/sec/min/heures/semaine/jour/jour de la semaine/mois/année) [sous format BCD, mais la lib fait les conversions qu'il faut]. Les ticks et timestamps s'obtiennent avec des calculs (adaptés de la musl libc, ma référence pour pas mal de choses).

(donc mieux vaut se baser sur la date que sur les timestamps/ticks)

(j'aime donner des détails)

Ajouté le 24/05/2016 à 18:58 :
La version 0.2.1 est là !

C'est surtout une version correctrice, qui :
- corrige la gestion du jour de la semaine ;
- corrige timeofdate (pour renvoyer un timestamp Unix qui fonctionne) ;
- corrige getdate (qui ne renvoyait pas le bon compteur 64-Hz).

Les prochaines versions devraient gérer l'édition de la date.
Respirateur d'air, BDFL de Cahute, des utilitaires de communication pour calculatrices CASIO.


Mon blogMes autres projets
Suruq game Hors ligne Membre de CreativeCalc Points: 621 Défis: 20 Message

Citer : Posté le 24/05/2016 19:00 | #


cette lib est très intéressante mais la fonction :
unsigned int time = rtc_gettime();

se réfère elle forcement au 1er janvier 1970 à minuit ?
ne me charriez pas si ma question est idiote
There is only one thing that makes a dream impossible to achieve : the fear of failure
Cakeisalie5 En ligne Ancien administrateur Points: 1960 Défis: 11 Message

Citer : Posté le 24/05/2016 19:03 | #


Elle renvoie un timestamp Unix, qui représente le nombre de secondes passées depuis le 1er janvier 1970 à minuit, donc oui
Respirateur d'air, BDFL de Cahute, des utilitaires de communication pour calculatrices CASIO.


Mon blogMes autres projets
Hackcell Hors ligne Maître du Puzzle Points: 1531 Défis: 11 Message

Citer : Posté le 24/05/2016 19:53 | #


Et on peut l'avoir sur sa calculatrice
Breizh_craft En ligne Modérateur Points: 1171 Défis: 7 Message

Citer : Posté le 24/05/2016 20:10 | #


Hackcell : bien sûr. Le RTC (Real Time Clock, je crois), et une sorte de petite montre qui fonctionne tant qu'elle a du courant, et qui sert entre autre, à réguler la vitesse du processeur, synchroniser les bus… enfin bref. Il y en a une dans tout les PC, et il y en a une dans les calculatrices Casio. Et cette horloge permet aussi d'avoir l'heure (c'est le but d'une horloge, en soit). Et comme on peut y accéder depuis l'OS et ainsi avoir une horloge qui se dérègle pas et qui reste à l'heure même si la calculatrice est éteinte. Mais pas si on enlève les piles. J'ai dit qu'il fallait du courant.

Je me suis rendu compte que ce pavé risque d'embrouiller plus qu'autre chose, mais je le poste quand même. Pas envie d'avoir écrit tout ça pour rien.

Et je passe la main pour expliquer plus simplement.

Ajouté le 24/05/2016 à 20:12 :
D’ailleurs, il se peut que je me sois fourvoyé et que j'ai dit des âneries.
Breizh.pm – Un adminsys qui aime les galettes.
Cakeisalie5 En ligne Ancien administrateur Points: 1960 Défis: 11 Message

Citer : Posté le 24/05/2016 20:18 | #


En fait pas exactement Breizh

On a effectivement quelques oscillateurs qui font tout tourner, y compris la RTC. La RTC, dans l'histoire, c'est simplement un gros compteur évolué, avec un petit système d'alarme (inutilisable sans un interrupt handler custom, malheureusement).

Ajouté le 25/05/2016 à 17:40 :
Tralala, c'est la version 0.3 !

Au programme :
- des corrections, encore, toujours. (mais cette fois, c'est la bonne !)
- et la possibilité d'éditer la date dans la RTC ! (on l'attendait celle-là)

Les nouvelles fonctions sont décrites dans le post principal.

Gardez à l'esprit que l'interaction avec la RTC n'est pas encore testée (donc qu'il y a une chance que ça rate (mais théoriquement, ça devrait pas)) quand vous l'utilisez. (cependant, je serais ravi d'avoir des tests )
Respirateur d'air, BDFL de Cahute, des utilitaires de communication pour calculatrices CASIO.


Mon blogMes autres projets
Drac0300 Hors ligne Membre Points: 839 Défis: 39 Message

Citer : Posté le 26/05/2016 08:11 | #


(https://fr.m.wikipedia.org/wiki/Circuit_synchrone) qui est beaucoup plus précise que la rtc
Je me demande bien pourquoi casio a inclus ce rtc... Ils s'en servent dans l'os ?
Dans Z/1Z, 42==666
Coïncidence ? Je ne pense pas.
Cakeisalie5 En ligne Ancien administrateur Points: 1960 Défis: 11 Message

Citer : Posté le 26/05/2016 08:26 | #


Beh à vrai dire, les MPUs possèdent effectivement des circuits comme celui que tu évoques. La RTC est juste un compteur indépendant au processeur, qui fonctionne justement grâce à l'un de ces circuits (elle s'incrémente à chaque fois qu'il la poke), du coup c'est pratique, il suffit de lire où le compteur en est.

Et c'est possiblement utilisé dans l'OS, mais pas pour donner l'heure (ou pas à un endroit commun en tout cas), plus pour donner des ticks, ou pour régler une alarme quand le compteur atteint une certaine date. Enfin, on peut se demander comment l'OS de base la gère (je n'ai pas encore vérifié ça).
Respirateur d'air, BDFL de Cahute, des utilitaires de communication pour calculatrices CASIO.


Mon blogMes autres projets
Lephenixnoir Hors ligne Administrateur Points: 24574 Défis: 170 Message

Citer : Posté le 27/05/2016 22:00 | #


Breizh_craft a écrit :
et qui sert entre autre, à réguler la vitesse du processeur, synchroniser les bus… enfin bref.

Euh, tu confonds avec le Clock Pulse Generator là. La RTC en est dépendante est c'est lui qui fournit les signaux du processeur, des bus, de la mémoire et de l'horloge périphérique.

Cakeisalie5 a écrit :
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.

Heureux de savoir qu'il y en a qui s'intéressent au développement sous Linux !
J'ai regardé rapidement les sources... si je peux me permettre un commentaire, c'est pas trop mal. Y'a trop de multiplications à mon goût... après c'est une manie à moi :3 Dans include/rtc/internals.h, inclus stdint.h au lieu de redéfinir des types de base. Par contre le code dans les headers de internals, c'est impardonnable. Statique ou pas, tu multiplies du code, c'est une violation élémentaire du principe DRY ! (Je suis très chiant mais ça m'amuse.)

Je trouve juste ça un peu dommage pour le dessin et la RTC. À part que gint est (significativement) plus rapide que ML, il faut que j'y intègre l'API de gestion (entre autres pour les interruptions), du coup ça fait redondant par rapport à ta lib...

Je pense que tu vois ce que je veux dire. Je suis sincèrement content de voir cet effort vers le développement Linux, maintenant si tu le veux bien, ce serait cool qu'on puisse s'arranger pour se compléter !
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Cakeisalie5 En ligne Ancien administrateur Points: 1960 Défis: 11 Message

Citer : Posté le 28/05/2016 02:43 | #


Pour le stdint.h, malheureusement, chez moi... x)

sh3eb-elf-gcc -I ./include -Wall -Wextra -Wno-attributes -c -o obj/rtc_init.o src/rtc_init.c
In file included from ./include/rtc/internals.h:27:0,
                 from src/rtc_init.c:24:
/opt/sh3eb-elf/lib/gcc/sh3eb-elf/6.1.0/include/stdint.h:9:26: fatal error: stdint.h: No such file or directory
# include_next <stdint.h>
                          ^


(et les headers standards ont toujours un peu foiré avec gcc 4.9.1 ou 6.1.0, donc bon, j'évite)

Les fonctions des headers de internals est en always_inline, c'est une idée que j'ai reprise de la musl libc (mon point de départ pour pas mal de trucs) et que je trouvais plus propre.

Et du coup, même si cette lib est utilisable directement, elle est surtout vouée à finalement être intégrée dans des libs plus grosses, comme gint ou caphics (qui, comme elle suit des principes différents niveau graphismes, a une raison d'être). Et pour l'instant, c'est du WIP, c'est pour tester, et je trouvais ça plus propre d'avoir une lib pour ça, comme ça d'autres personnes peuvent tester et contribuer facilement.
Respirateur d'air, BDFL de Cahute, des utilitaires de communication pour calculatrices CASIO.


Mon blogMes autres projets
Lephenixnoir Hors ligne Administrateur Points: 24574 Défis: 170 Message

Citer : Posté le 28/05/2016 14:07 | #


Cakeisalie5 a écrit :
Les fonctions des headers de internals est en always_inline

Oups, au temps pour moi
Je sais pas si j'arrive à trouver ça propre par contre ! Je pense que c'est juste le fait de mettre du code dans un header : lorsque tu cherches le code d'une fonction, en général tu veux qu'il soit dans les sources... pourquoi ne pas juste mettre ça dans un fichier source ? Ce serait pareil, non (ou alors j'ai raté quelque chose) ?

J'ai l'impression d'être plus chiant qu'autre chose, alors je vais te laisser tranquille. Au passage on aura besoin d'implémenter la lib standard sous Linux : est-ce que ça te dirait de former le code pour ça, en utilisant les types et les noms de fonctions standard ?
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Cakeisalie5 En ligne Ancien administrateur Points: 1960 Défis: 11 Message

Citer : Posté le 28/05/2016 14:20 | #


En fait, faut voir ces fonctions-là comme des grosses macros, plus élégamment écrites.

Et je préfère ne pas modifier le code de cette lib pour intégrer des noms standards, faudra modifier ça quand on reprendra le code (histoire de ne pas rentrer en conflit, puisque cette lib n'est pas standard)

Ajouté le 19/07/2016 à 10:08 :
Version 1.0 publiée ! C'est bon, a priori, les fonctions marchent correctement, et une fonction bonus (rtc_adjustwday) a été ajoutée. L'addin de test est arrivé par la même occasion.

Deux informations importantes :
- cette lib n'est utilisable que par les gens sous Gnunux (qui me laisse plus libre de mes choix que le SDK de Windows) ;
- une documentation sous forme de manpages est également disponibles, les instructions pour les installer sont dans le README.
Respirateur d'air, BDFL de Cahute, des utilitaires de communication pour calculatrices CASIO.


Mon blogMes autres projets
Dyn4moo Hors ligne Membre Points: 19 Défis: 0 Message

Citer : Posté le 07/06/2017 17:25 | #


Bonjour,
J'aimerais utiliser cette lib seulement je n'arrive pas à créer de compte sur GitLab car je ne reçois aucune confirmation par Email (j'ai réessayer plusieurs fois). Est-il possible de me la donner en fichier joint(=zip) ?
Merci d'avance
Cakeisalie5 En ligne Ancien administrateur Points: 1960 Défis: 11 Message

Citer : Posté le 07/06/2017 17:28 | #


Tu peux trouver ça dans la source d'Omgclock. Cette lib n'est plus entretenue, au passage.
Respirateur d'air, BDFL de Cahute, des utilitaires de communication pour calculatrices CASIO.


Mon blogMes autres projets
Lephenixnoir Hors ligne Administrateur Points: 24574 Défis: 170 Message

Citer : Posté le 24/08/2018 13:49 | #


D'après un coup rapide sur les sources, tu ne tiens pas compte du carry dans la lecture :

// 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;

Dommage !
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Cakeisalie5 En ligne Ancien administrateur Points: 1960 Défis: 11 Message

Citer : Posté le 01/09/2018 01:23 | #


Pouh, c'est vieux cette lib maintenant. Si tu as la foi de corriger, je t'en prie
Respirateur d'air, BDFL de Cahute, des utilitaires de communication pour calculatrices CASIO.


Mon blogMes autres projets
Lephenixnoir Hors ligne Administrateur Points: 24574 Défis: 170 Message

Citer : Posté le 01/09/2018 08:58 | #


Je le ferais bien par principe, mais je ne trouve pas de dépôt Git avec le code !
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Cakeisalie5 En ligne Ancien administrateur Points: 1960 Défis: 11 Message

Citer : Posté le 01/09/2018 12:11 | # | Fichier joint


Excuse-moi, c'est vrai que j'ai changé tous les dépôts plusieurs fois sur cette forge
Voici, en pièce jointe, tout ce que j'ai en local concernant la librtc
Respirateur d'air, BDFL de Cahute, des utilitaires de communication pour calculatrices CASIO.


Mon blogMes autres projets
Lephenixnoir Hors ligne Administrateur Points: 24574 Défis: 170 Message

Citer : Posté le 01/09/2018 12:32 | #


Parfait, voilà un diff

--- librtc.old/public/src/getdate.c    2018-09-01 12:25:45.867481880 +0200
+++ 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);
}

Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
1, 2 Suivante

LienAjouter une imageAjouter une vidéoAjouter un lien vers un profilAjouter du codeCiterAjouter un spoiler(texte affichable/masquable par un clic)Ajouter une barre de progressionItaliqueGrasSoulignéAfficher du texte barréCentréJustifiéPlus petitPlus grandPlus de smileys !
Cliquez pour épingler Cliquez pour détacher Cliquez pour fermer
Alignement de l'image: Redimensionnement de l'image (en pixel):
Afficher la liste des membres
:bow: :cool: :good: :love: ^^
:omg: :fusil: :aie: :argh: :mdr:
:boulet2: :thx: :champ: :whistle: :bounce:
valider
 :)  ;)  :D  :p
 :lol:  8)  :(  :@
 0_0  :oops:  :grr:  :E
 :O  :sry:  :mmm:  :waza:
 :'(  :here:  ^^  >:)

Σ π θ ± α β γ δ Δ σ λ
Veuillez donner la réponse en chiffre
Vous devez activer le Javascript dans votre navigateur pour pouvoir valider ce formulaire.

Si vous n'avez pas volontairement désactivé cette fonctionnalité de votre navigateur, il s'agit probablement d'un bug : contactez l'équipe de Planète Casio.

Planète Casio v4.3 © créé par Neuronix et Muelsaco 2004 - 2024 | Il y a 249 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements

Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd