Bit de controle en attente : Logique et Physique

Bonjour à tous !

En décortiquant le fichier 'main' modifié pour ma carte (BlendMicro) je me suis arreté sur cette fonction :


1 #if defined(BLEND_MICRO_8MHZ)
2 // As the F_CPU = 8000000UL, the USB core make the PLLCSR = 0x02
3 // But the external xtal is 16000000Hz, so correct it here.
4 PLLCSR |= 0x10; // Need 16 MHz xtal
5 while (!(PLLCSR & (1<<PLOCK))); // wait for lock pll


L'octet PLLCSR se decompose comme ça

7 6 5 4 3 2 1 0
0 0 0 ? 0 0 ? ?

4 = PINDIV ( PLL input prescaler ) divise la frequence par 2 si TRUE
1 = PLLE ( PLL Enable ) start si TRUE
0 = PLOCK ( PLL Lock to reference clock ) lock si TRUE

le BIT 0 est le seul des trois à etre en READ ONLY

Donc si je comprends bien ( et c'est ma premiere question < Logique ) :

Ligne 5 : PLLCSR est egal à 0 0 0 1 . 0 0 1 0 tant que le pointeur du bit 0 n'est pas poussé à TRUE ?

et si oui ( ma deuxieme question < Physique ) :

Quelle est la cinematique de validation du bit , autrement dit comment les deux horloges se synchronisent-elles ?

Merci ! :slight_smile:

0x10 Ce n'est pas b000100[color=red][b]1[/b][/color]0....

j'ai oublié de preciser : apres la ligne 4.

c'est le while qui me pose soucis...

Merci pour ce rappel clair , c'est ce que j'avais déduis de ma lecture du datasheet et vous confirmez.
Vous trouverez la description de PLLCSR à la page 40.

J'arrive à "traduire" jusqu'à la ligne 5 , ensuite le while reste obscur , plus precisement :

1<<PLOCK

Si je me refere aux dictionnaires C++ nous avons affaire à un decalage de bit vers la gauche. Mais pour coller aux definitions il faudrait intervertir les operandes.
J'ai opté pour un pointeur mais il manque * sur &.

le commentaire de ligne precise // wait for PLOCK. Je peux deduire que la ligne 5 donne quelque chose comme:

TANT QUE LA CONDITION ( octet PLLCSR = 0001.0010 ET ( le bit PLOCK ( le bit0 ) poussé à 1 ) ) N'EST PAS VRAI

Mais c'est une traduction aleatoire , comment doit-on l'interpreter?

Bonjour,

Je ne vois pas bien ce que tu n'arrives pas à comprendre.

pepe t'a expliqué que la ligne 5 attend que le bit PLOCK soit à 1

1<<PLOCK avec PLOCK=0 ça donne 1. Donc on teste le bit 0 et on attend qu'il passe à 1.

D'avoir la tete dedans si longtemps , j'ai oublié d'etre plus precis ^^

Le fonctionnement du programme est compris , c'est uniquement cette utilisation de << qui m'echappe , je ne trouve pas de definition , ou plutot j'en trouve plusieurs !

  • Soit " decalage de bit vers la gauche " qui s'applique à tout les bits d'un octet ( wikilivres )

  • Soit un operateur d'insert ( microsoft )

Dans les deux cas rien ne me permet de traduire cette ligne correctement.

Je cherche à comprendre ce qui est ecrit pour pouvoir l'assimiler et le re-utiliser.

Pour etre encore plus precis :

Je connais son resultat mais comment traduire 1<<PLOCK ?

C'est décalage à gauche de l'entier qui vaut 1 de PLOCK crans.
Sachant que PLOCK vaut 0, il n'y a pas de décalage.

Et c'est aussi l'opérateur d'insertion pour les flux. Sachant que en C++ tous les opérateurs peuvent être redéfinis dans la class sur laquelle ils s'appliquent.

Ha ! c'est bien plus clair comme ça , merci Mr pepe !

je ne comprenais pas pourquoi utiliser un decalage à gauche si un seul BIT est concerné ?

Hors pb de syntaxe evidement , (je ne sais pas encore ecrire en c++ ) je pensais plutot à :

while ( ( PLLCSR & ( PLOCK = FALSE ) ) ) pour tester le BIT

Mais en fait il s'agit de bloquer l'etat du BIT ?

D'accord , c'etait ma question sur la cinematique. Le BIT 0 ( PLOCK ) etant en lecture seule je me demandais ce qui determinait son etat.

J'ai confondu la validation de la fonction et l'etat de l'octet ( desolé ! )

Je cherche encore le chemin du BIT salvateur dans les datablocks des datasheets par pure curiosité.

Comme quoi le binaire et l'assembleur y a rien de mieux pour s'expliquer !

Je n'appréhendais pas le masque correctement , en m'en tenant aux def. trouvé sur le net.
L'application que vous expliquez n'est jamais apparue nulle part pendant mes recherches.

C'est maintenant extremement clair ! >>> Merci beaucoup ! <<<

à ce propos , si je veux une source absolue de connaissance C++ , quel ouvrage me conseillez-vous ?
( je ne crains pas le binaire ni l'ASM ( je suis elec à l'origine ) )

En ligne je pense que ceci est une bonne référence

J'ai opté pour un pointeur mais il manque * sur &.

à lire ce que vous dites ci dessus on dirait que vous bloquiez sur le & qui est l'opérateur de bitmask ET LOGIQUE (AND) et non pas une histoire d'adresse ou de pointeur

Bonjour,

pas évident en effet, on rencontre en 2 lignes :
héxadécimal : 0x10
décimal, par défaut : le fameux 1
texte désignant le contenu d'un emplacement : PLLCSR
texte désignant une constante : PLOCK
instruction à effectuer par le mpu : |= et aussi : &
quant au non moins fameux << , qui ressemble à s'y méprendre à une instruction, est plutôt une directive destinée au préprocesseur (la preuve par l'assembleur)

@ J-M-L : ok , merci ! Pour & : je cherchais un angle de vue sur le fameux BIT 0 mais mon hypothese n'a pas tenue longtemps

@ trimarco232 : Et oui , en plus d'etre une partie importante du processus , ce petit bout de code est une epreuve pour un neophyte :slight_smile:

La possibilité de voir le bas niveau est juste essentielle , il faut que je trouve comment faire !

trimarco232:
quant au non moins fameux << , qui ressemble à s'y méprendre à une instruction, est plutôt une directive destinée au préprocesseur (la preuve par l'assembleur)

oui et non << est une instruction à part entière pour le compilateur. Dans ce cas particulier, comme le résultat est calculable lors de la compilation puisque tout est constant, le préprocesseur remplace l'expression par un littéral qui est ensuite utilisé par le compilateur pour générer un code optimisé.

si vous aviez mis PLOCK dans une variable de type volatile, le compilateur n'aurait pas pu faire l'optimisation mais le code aurait été tout aussi fonctionnel

Bonsoir , je reviens sur le sujet après avoir trouvé une explication dans un .pdf orienté robotique.

La voici :

" Comment faire pour passer le n`eme bit du registre x à 1 sans modifier les autres bits?

Le registre x est de la forme (y,y,y,n`eme bit,y,y,y,y) où y=0 ou 1.

Il suffit de savoir que (y OU 0)=y et que (y OU 1)=1.
Il suffit donc de faire x OU(0,0,0,1au neme bit,0,0,0 , 0 ) pour obtenir le registre x identique sauf le neme bit qui est passé a 1.
Ceci se fait en C par l’instruction :

x|=(1<<n) "

source : http://les-electroniciens.com/sites/default/files/cours/programmationavr.pdf

Bonjour,
exact,
et pour faire passer à 0 le bit n c'est :

x&= ~(1<<n);

Bravo vous avez compris

Maintenant pour raccrocher cela à votre sujet il suffit de remplacer n par PLOCK qui est le nom d'une constante prédéfinie donnant le "petit nom" du bit en question

Attention - histoire d'ajouter à la confusion :slight_smile: - bien que cette approche soit correcte dans 99,9999% des cas - le fonctionnement n'est pas toujours identique : certains registres ATMEL au niveau matériel sont traités comme des bascules en écriture - c'est le cas de PIND par exemple qui par le simple fait d'écrire un 1 sur un bit bascule la valeur de ce bit (donc ne met pas un 1 dedans mais inverse la valeur qui était dedans)

c'est un cas très spécial - la doc arduino dit que ce registre est en lecture seule mais la doc ATMEL explique un peu plus son comportement

Je la croise dans tout les setups que je lis ça et là , c'est en fait une syntaxe ultra courante !

Je cherche maintenant un moyen de sortir les fonctions en assembleur pour pouvoir les lires à l'ancienne.

Est-ce que l'IDE Arduino dispose de l'option ?

Je fais partager des fois que..

ok , donc je sauve mon croquis , j'ouvre un term ( OSX ) et j'invoque GCC avec ce qu'il faut d'options pour avoir mes dump ?

Apres essai , gcc m'indique qu'il ne connait pas l'extension .ino donc impossible d'obtenir les chemins des fichiers temporaires par ce biais...
(nb : le .ino , mystère à résoudre plus tard )

Direction les préférences de l'IDE et je demande les détails durant la compilation.
A la fin , dans la console , j'obtiens l'adresse du fichier ELF ( sous OSX et en 1.0.5 : /var/folders/... )

Je rejoins le répertoire avec un terminal et lance avr-objdump :

avr-objdump -d HelloWorld.cpp.elf

Et là , miracle !!! :smiley: >> j'ai mal aux yeux !

J'en profite pour tenter de désassembler la fonction qui me posait problème : il me faut compiler main.cpp et obtenir les infos.
Petite deception : man gcc : pas de man... je croyais que c'était obligatoire ?

Mode d'emploi de GCC .

En fait c'est gcc --help

Vu le nombre d'options le manuel doit faire 3 gigas !!! je comprends pourquoi personne ne veut y mettre les doigts !

Je trouve cpp...
.
.
.
.
.
.
.
.
( whaou , y'a du monde la dessous )

merci pour le coup de pouce !