+ Répondre à la discussion Actualité déjà publiée
  1. #1
    Responsable Corrections

    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    janvier 2009
    Messages
    8 444
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : janvier 2009
    Messages : 8 444
    Points : 33 361
    Points
    33 361
    Billets dans le blog
    9

    Par défaut Programmer l'Arduino en langage C



    Si vous êtes férus d'Arduino et que vous souhaitez vous mettre au langage C, ce tutoriel est peut-être fait pour vous :



    ou comment apprendre la programmation du microcontrôleur Atmel AVR de l'Arduino en véritable langage C, au cœur des registres de la puce, sans passer par l'EDI standard, et sans utiliser le fameux « langage Arduino ».

    J'adore jouer avec ma carte Arduino UNO et son environnement de développement graphique. C'est un outil qui facilite grandement la programmation en dissimulant une foule de détails. D'un autre côté, je ne peux m'empêcher d'observer dans les coulisses de l'EDI, et j'ai senti le besoin de me rapprocher des aspects matériels, de m'écarter des bibliothèques fournies par défaut et de l'EDI Java pour compiler directement mes programmes à partir de la ligne de commandes.

    Francesco Balducci
    Nom : toolchainArduino.JPG
Affichages : 793
Taille : 31,8 Ko
    Du code source en langage C jusqu'au téléversement dans la carte Arduino avec la chaîne de compilation avr-gcc.


    Bonne lecture, et bon développement, en vrai langage C...


    Retrouvez les meilleurs cours et tutoriels pour apprendre les systèmes embarqués
    Forums d'entraide Raspberry Pi et Arduino

    Arduino :
    - Aperçu de la plateforme Arduino : Parties 1 et 2
    - Arduino et le bus I2C
    - Top 10 des shields Arduino
    - Apprendre à piloter un bargraphe 12 segments bicolores [Nouveau]
    - Programmer l'Arduino en langage C, au cœur des registres de l'Atmel AVR [Nouveau]

  2. #2
    Expert confirmé
    Avatar de Vincent PETIT
    Homme Profil pro
    Ancien développeur matériel électronique (Hard/Soft)
    Inscrit en
    avril 2002
    Messages
    1 399
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ancien développeur matériel électronique (Hard/Soft)
    Secteur : Service public

    Informations forums :
    Inscription : avril 2002
    Messages : 1 399
    Points : 4 079
    Points
    4 079

    Par défaut

    Merci pour ce tuto Fabien !
    Voilà qui pourrait intéresser les copains du forum C qui n'ont qu'un petit pas à franchir pour jouer sur un microcontrôleur.

    Sur le rôle de la macro _BV
    En C, on a l'habitude d'utiliser les opérateurs d'affectation bit à bit |= et &= pour lire ou écrire dans une variable, mais le compilateur reconnaît ce genre d'accès et produit un code d'assemblage optimisé dans le cas d'opérations bit par bit, sans opération de lecture supplémentaire.

    Tu es entrain de me faire peur car je n'avais jamais constaté de différence entre :
    et
    Je vais regarder ça de prés et surtout les options d'optimisation de mon compilateur car si la lecture ne se fait pas dans le cas de :

    J'espère bien que DDRB soit lu puis aille dans un registre de travail pour se voir appliqué le OU 0x20 et enfin être remis dans DDRB

    A bientôt,

  3. #3
    Responsable Corrections

    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    janvier 2009
    Messages
    8 444
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : janvier 2009
    Messages : 8 444
    Points : 33 361
    Points
    33 361
    Billets dans le blog
    9

    Par défaut

    Salut Vincent

    Citation Envoyé par Vincent PETIT Voir le message
    Tu es entrain de me faire peur car je n'avais jamais constaté de différence entre :
    et
    Je ne te suis pas, finalement cela revient au même, non ?

    http://www.nongnu.org/avr-libc/user-...5a93800b3d9546
    #define _BV(bit ) (1 << (bit))

    #include <avr/io.h>

    Converts a bit number into a byte value.

    Note
    The bit shift is performed by the compiler which then inserts the result into the code. Thus, there is no run-time overhead when using _BV().
    Forums d'entraide Raspberry Pi et Arduino

    Arduino :
    - Aperçu de la plateforme Arduino : Parties 1 et 2
    - Arduino et le bus I2C
    - Top 10 des shields Arduino
    - Apprendre à piloter un bargraphe 12 segments bicolores [Nouveau]
    - Programmer l'Arduino en langage C, au cœur des registres de l'Atmel AVR [Nouveau]

  4. #4
    Expert confirmé
    Avatar de Vincent PETIT
    Homme Profil pro
    Ancien développeur matériel électronique (Hard/Soft)
    Inscrit en
    avril 2002
    Messages
    1 399
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ancien développeur matériel électronique (Hard/Soft)
    Secteur : Service public

    Informations forums :
    Inscription : avril 2002
    Messages : 1 399
    Points : 4 079
    Points
    4 079

    Par défaut

    Citation Envoyé par f-leb Voir le message
    Je ne te suis pas, finalement cela revient au même, non ?
    Oui oui mais lorsque j'ai lu cette phrase, qui introduit _BV dans le tuto :
    En C, on a l'habitude d'utiliser les opérateurs d'affectation bit à bit |= et &= pour lire ou écrire dans une variable,
    Jusque là pas de soucis nous sommes d'accord.

    Mais a partir du mais justement :
    mais le compilateur reconnaît ce genre d'accès et produit un code d'assemblage optimisé dans le cas d'opérations bit par bit, sans opération de lecture supplémentaire.
    Ça laisse penser qu'il y a un problème et que _BV est né de ça !

    Je me suis donc interrogé sur ce point.
    Je sais que sur GCC, et même d'autre compilateur, les options de compilations peuvent avoir un effet désastreux en programmation embarqué car des variables en attentes du matériel ou d'un registre peuvent être éliminées du source car le compilateur pense qu'elles ne servent a rien. Certain flag dans des registres se mettent a 0 après une simple lecture et là aussi certain compilateur, voyant dans le code un simple lecture, vont essayer d'optimiser et malheureusement ça fini en "comme la variable ne fait que lire une adresse et ne fait rien de cette valeur, pas de calcul ni d'opération" bah c'est qu'elle ne sert pas au final !

    A+

  5. #5
    Responsable Corrections

    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    janvier 2009
    Messages
    8 444
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : janvier 2009
    Messages : 8 444
    Points : 33 361
    Points
    33 361
    Billets dans le blog
    9

    Par défaut

    bon, je ne suis pas assez calé

    je n'ai pas compris ce "mais" comme ca, mais c'est peut-être un souci dans la traduction :
    In C we use the bitwise “|=” and “&=” assignment operators, which usually read and write a variable, but the compiler recognizes those kind of accesses generating optimized assembly in case of bit-wise operations, and there is no read operation involved.
    Forums d'entraide Raspberry Pi et Arduino

    Arduino :
    - Aperçu de la plateforme Arduino : Parties 1 et 2
    - Arduino et le bus I2C
    - Top 10 des shields Arduino
    - Apprendre à piloter un bargraphe 12 segments bicolores [Nouveau]
    - Programmer l'Arduino en langage C, au cœur des registres de l'Atmel AVR [Nouveau]

  6. #6
    Membre habitué
    Étudiant
    Inscrit en
    juin 2010
    Messages
    60
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : juin 2010
    Messages : 60
    Points : 173
    Points
    173

    Par défaut

    Dans ma tête quand je vois ça :
    une voix me dit "mais pourquoi il n'utilise pas un xor ?"
    A part ce détails des plus utile...

    DDB5 est une constante
    1<<(DDB5) peut être déterminé lors de la compilation comme une constante, et donc ne pas d'opération superflue lors de l’exécution.( pas d'opération de décalage inutile lors de l’exécution )

    Je l'ai compris comme ça.

  7. #7
    Expert confirmé
    Avatar de Vincent PETIT
    Homme Profil pro
    Ancien développeur matériel électronique (Hard/Soft)
    Inscrit en
    avril 2002
    Messages
    1 399
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ancien développeur matériel électronique (Hard/Soft)
    Secteur : Service public

    Informations forums :
    Inscription : avril 2002
    Messages : 1 399
    Points : 4 079
    Points
    4 079

    Par défaut

    Je suis d'accord et pour tout dire, je cherchais une raison technique à cette macro _BV(bit) mais c'est simplement pour des raisons de lisibilité/compréhension du programme qu'elle est défini.
    Je dois probablement avoir un raisonnement beaucoup trop électronique (binaire/assembleur/registre) car effectivement, faire :
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    DDRB |= (_BV(DDB0) | _BV(DDB1) | _BV(DDB2)); // mettre a en sortie PB0, PB1 et PB2
    Semble plus aisé à lire et à comprendre que ma version a moi :
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    DDRB |= 0x03; // mettre a en sortie PB0, PB1 et PB2
    Même si je ne me ferai jamais a la première écriture....

  8. #8
    Expert confirmé
    Avatar de Vincent PETIT
    Homme Profil pro
    Ancien développeur matériel électronique (Hard/Soft)
    Inscrit en
    avril 2002
    Messages
    1 399
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ancien développeur matériel électronique (Hard/Soft)
    Secteur : Service public

    Informations forums :
    Inscription : avril 2002
    Messages : 1 399
    Points : 4 079
    Points
    4 079

    Par défaut

    Citation Envoyé par f-leb Voir le message
    c'est peut-être un souci dans la traduction :
    Non non pas du tout !

    C'est que j'ai pensé a un problème très sournois du genre :
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    int i;
     
    interrupt (TIMERA0_VECTOR) irq_routine(void) // a chaque débordement du TIMERA
    {
        i = 42;
    }
     
    void func(void) // fonction attendre
    {
        i = 0;
        while (i == 0); 
    }

    1. Lorsque la fonction "func" sera appelée, "i" va être mis dans un registre de travail pour manipulation, donc ce registre sera mis à 0 puis testé avec la valeur 0 dans une boucle.

    2. Puis le TIMERA va déborder et la routine d'interruption va s'exécuter en stoppant tout (on empile), l'emplacement mémoire de "i" va valoir 42.

    3. Enfin, on sort de l'interruption, on retourne dans le code de la fonction "func" (on dépile) et le registre qui valait 0, avant, et qui est testé avec la valeur 0 n'a aucune raison de se mettre à jour avec la nouvelle valeur de "i", soit 42 !


    Et c'est la boucle infinie.

    Pire encore, si jamais les options d'optimisation sont activées alors GCC va voir tout de suite une comparaison avec la valeur 0 et un registre qui est mis a 0 .... et il risque de retirer la condition qui pour lui ne sert strictement a rien et c'est vrai puisqu'on teste 0 avec 0. Ce problème se règle facilement avec le mot clé volatile qui va forcer le compilateur a aller voir l'emplacement mémoire de la variable "i" à chaque vérification ou manipulation.

    D'où la frousse que j'ai eu en voyant ce _BV(bit) que je ne connaissais pas et la phrase :
    En C, on a l'habitude d'utiliser [...], mais le compilateur reconnaît ce genre d'accès et produit un code d'assemblage optimisé dans le cas d'opérations bit par bit, sans opération de lecture supplémentaire.
    J'ai pris le "mais" dans le sens attention alors que ce n'est pas ça... bref c'est rien, c'était juste un peu de paranoïa mais je me soigne C'est rien Vincent, ce n'est qu'une macro, ça va aller

  9. #9
    Membre confirmé
    Homme Profil pro
    Ingénieur électricien
    Inscrit en
    septembre 2008
    Messages
    194
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur électricien

    Informations forums :
    Inscription : septembre 2008
    Messages : 194
    Points : 496
    Points
    496

    Par défaut

    Bonsoir

    Pour le coup j'ai lu ce tuto à la sortie du suivant.

    Juste pour "optimisation", en fait c'est bien de le connaître, une écriture sur le registre PINx inverse les sorties dont la valeur écrite est à 1.

    Donc la boucle
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
      while(1) {
      /* set pin 5 high to turn led on */
      PORTB |= _BV(PORTB5);
      _delay_ms(BLINK_DELAY_MS);
     
      /* set pin 5 low to turn led off */
      PORTB &= ~_BV(PORTB5);
      _delay_ms(BLINK_DELAY_MS);
     };
    peut-être simplifiée de la manière suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      while(1) {
      /* toggle pin 5 to blink LED */
      PINB = _BV(PORTB5);
      _delay_ms(BLINK_DELAY_MS);
    };
    Ici cela n'a pas d'importance, mais dans les projets un peu plus complexe cela peut beaucoup aider.

    Je manque d’expérience en C, les AVR je les travaille en ASM. Je ne peux pas apporter de réponse à vos questions sur le volatile.

    Bonne soirée.

    Delias

Discussions similaires

  1. Python, pourquoi programmer avec un autre langages?
    Par kayzra dans le forum Général Python
    Réponses: 9
    Dernier message: 31/03/2007, 19h57
  2. Réécrire un programme dans un autre langage/Licence ?
    Par VinnieMc dans le forum Licences
    Réponses: 1
    Dernier message: 15/03/2007, 11h32
  3. Création d'un programme de Gestion / compta : langage ?
    Par Alexino2 dans le forum Langages de programmation
    Réponses: 7
    Dernier message: 11/04/2006, 15h00

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo