Variable assembleur + UART

Bonjour,

Pour convaincre un prof qu'arduino est pas si nul que ça j'ai besoin de coder mes arduinos en assembleur. en effet pour lui on a accès a aucune donnée interne au microcontrôleur. Je développe donc un petit programme pour lui montrer qu'on peut avoir accès à la mémoire EEPROM, SRAM, FLASH. Et qu'en plus on peut le faire en assembleur.

Je développe sur la Due mais ça peut fonctionner sous UNO (c'est pas tout à fait les même instructions mais je me débrouillerais).

J'aimerais donc avoir un petit programme qui communique avec le PC.

Exemple en C :

int test=4;
int R0=0;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println(test);
  Serial.println(R0);
  R0=test;
  Serial.println(R0);

}

void loop() {
  // put your main code here, to run repeatedly:

}

En assembleur ça donnerait quelque chose du genre :

int test=4;

void setup() {
  // put your setup code here, to run once:
  asm("MOV R0, #0");
  Serial.begin(115200);
  Serial.println(test);
  Serial.println(R0);
  asm("MOV R0, test");
  Serial.println(R0);

}

void loop() {
  // put your main code here, to run repeatedly:

}

Déjà est-il possible de mélanger le C et l'assembleur comme ça ?
Ensuite, est-il possible de savoir où est enregistrer "test" (son adresse) ?
Enfin, peut-on envoyer sur le port série facilement des registres ? (Je sais que pour un 8051 il suffit d'écrire la valeur à envoyer dans le registre SBUF, puis l'envoie est automatique mais ici ?)

Cordialement,
Minicarpet

Salut Minicarpet,

et à l'essai, ça donne quoi ?

Je peux te répondre pour l'arduino uno ou méga : ça se programme très bien en assembleur. Pour insérer des lignes assembleur dans du c, c'est faisable mais un peu coton, il faut une bonne raison pour en justifier l'effort.

Faut pas tout mélanger. Avoir accès aux données internes ne nécessite pas de passer par l'assembleur.
Tu peux accéder à tout l'espace mémoire (RAM) en utilisant des pointeurs.
Pour accéder aux registres spéciaux il y a des pseudo-variables qui permettent de le faire en écrivant du C. Il suffit d'aller regarder comment est écrite la librairie SPI elle manipule directement les registres du périphérique SPI.

ça fonctionne pas : R0 n'est pas déclarer (logique).
La raison : Je sais pas vraiment soit disant que le Bluetooth n'est pas facilement programmable en C (perso j'y arrive très bien xD) et la raison du prof c'est surtout que apparement beaucoup d'arduino plante pendant le fonctionnement (problème de SRAM) mais perso j'ai jamais eu ce soucis en 500 programmes -_-

d'accord mais bon un asm("MOV Registre, DIRECT"); est l'affaire est réglé pour modifier un Special Function Register :wink:

Même si les AVR et ARM diffèrent, il suffit de suivre les instructions du M3 et non de l'atmega328. Cependant ton document GCC est super dur à comprendre mais j'ai fini par faire fonctionner, je n'envoie pas sur le port série par l'assembleur mais par la fonction Serial.print.

Le code suivant fonctionne et m'affiche bien 4, puis 200 puis 201.

int test=4;

void setup() {
  // put your setup code here, to run once:
  asm("MOV R8, #200");
  //asm("MOV R4, #150"); problème (mais du a l'assembleur);
  Serial.begin(115200);
  Serial.println(test);
  asm("MOV %0,R8 \n\t" :  "+r" (test)); 
  Serial.println(test);
  test+=1;
  Serial.println(test);

}

void loop() {
  // put your main code here, to run repeatedly:

}

Mais j'ai un soucis avec les registres Rn avec 0<=n<8 qui me renvoie des valeurs bizarre (4 puis 537329708 puis 537329709) j'ai bien le +1 mais j'ai pas le 150. C'est apparement un soucis lors de l'instruction MOV mais en cherchant je trouverais :wink:

"

Ok pour les adresses des variables. Pour le port série, il faudra donc faire très attention si je m'en sers, c'est noté.

Merci encore :wink:

asm("MOV R4, #150"); problème (mais du a l'assembleur);

j'ai un soucis avec les registres Rn avec 0<=n<8

du fait de l'architecture de l'AVR, ces registres ne peuvent pas recevoir directement de littéral (d'ailleurs ils ne permettent pas non plus la manipulations de bits)

l'instruction pour charger un littéral est normalement LDI. Peut-être que dans ce cas GCC signale l'erreur ?

trimarco232:
l'instruction pour charger un littéral est normalement LDI. Peut-être que dans ce cas GCC signale l'erreur ?

Pour les ARM cette instruction n'existe pas, et donc le GCC plante.

pepe:
Comme je l'ai suggéré précédemment, les opérations réalisées en C peuvent modifier les registres lus.

Possible, mais avec tous les Low Registers c'est quand même chelou :stuck_out_tongue: