Comment programmer un PIC avec SDCC et Code::Blocks

Bonjour à toutes et à tous !

En attendant de pouvoir récupérer mon matériel pour la suite du projet de programmateur de PIC – et parce que je ne tiens plus en place tellement je suis impatient – j’ai décidé d’ouvrir une rubrique Tutoriels pour expliquer certaines choses pour lesquelles il est difficile de trouver des informations sur internet. Je commence donc cette rubrique avec un tutoriel pour expliquer comment programmer sur des microcontrôleurs PIC – de Microchip – avec le compilateur SDCC et l’environnement de développement Code::Blocks.

Pour commencer, je vais vous présenter un petit peu ce qu’est SDCC. C’est un compilateur libre développé pour programmer en C sur différents microcontrôleurs – on parle alors de compilateur multi-cibles. Il gère différentes familles de microcontrôleurs dont une courte liste est disponible en page d’accueil du site : SDCC – Small Device C Compiler.

Concernant la programmation sur cible PIC, celle-ci n’est pas totalement intégrée bien qu’il soit tout à fait possible de programmer des PIC avec. Il faut cependant, en plus du compilateur SDCC, utiliser une autre chaine de compilation – en assembleur cette fois – qui se nomme GPUTILS, pour GNU PIC Utilities. Rassurez-vous, vous ne serez pas obligés d’apprendre l’assembleur pour programmer sur des PIC. SDCC utilise simplement GPUTILS comme outil pour transformer son code compilé en un fichier HEX exécutable par le PIC.

Notez que SDCC, en complément de GPUTILS, est très certainement l’un des meilleurs compilateurs pour microcontrôleurs qui existent dans le domaine du logiciel libre.

Passons désormais à la problématique, où je vous explique le pourquoi de ce tutoriel. Code::Blocks intègre bien la notion de systèmes embarqués, et comprend même SDCC dans sa liste de compilateurs. Néanmoins, parmi les templates de projet disponibles, il n’en existe pas pour le développement sur PIC. Il existe bien quelques tutoriels sur internet pour utiliser SDCC avec Code::Blocks mais ceux-ci sont soit obsolètes soit erronés – c’est bien connu que ce qui se trouve sur internet ne fonctionne jamais comme on le souhaite. ;)

J’ai passé un long moment à chercher comment paramétrer Code::Blocks pour créer un template personnalisé de projet PIC et il s’est finalement avéré que la solution était assez simple.

Pour commencer, si ce n’est déjà fait, téléchargez et installez Code::Blocks, GPUTILS et SDCC sur leurs sites respectifs. Le site de SDCC recommande de télécharger une version snapshot si la dernière version stable disponible date de plus de deux mois. À l’heure où j’écris ces lignes, la dernière version date de Juillet 2012, mais pensez à vérifier régulièrement la sortie d’une nouvelle mise à jour – sachez qu’il sort quasiment un snapshot par jour pour SDCC voire plus.

Configuration de SDCC

Une fois que tout est installé, ouvrez le programme Code::Blocks et dès que celui-ci est démarré, allez dans « Settings » > « Compiler… ». La fenêtre de configuration des compilateurs s’affiche. En haut, sélectionnez dans la liste « SDCC Compiler ». Sélectionnez ensuite l’onglet « Toolchain executables » et appuyez sur le bouton « Auto-detect » pour que Code::Blocks détecte automatiquement l’emplacement du compilateur SDCC.

configsdcc01

Il nous reste une dernière chose à configurer avant la création d’un projet. Il faut que l’extension pour les fichiers sources compilés soit « .o » et non « .rel ». Faites défiler les onglets avec les flèches à droite jusqu’à voir apparaître l’onglet « Other Settings ». Là, cliquez sur le bouton « Advanced options… ».

configsdcc02

Une autre fenêtre s’ouvre alors. Sélectionnez l’onglet « Others » et vérifiez que la valeur pour « Object file extension » est bien une lettre ‘o’. Si ce n’est pas le cas, modifiez la valeur qui s’y trouve – « rel » – par la lettre ‘o’. Cliquez sur « OK » pour quitter la fenêtre des options avancées et encore sur « OK » pour quitter la configuration du compilateur.

configsdcc03

Créer un projet PIC

Maintenant que SDCC est bien configuré, passons à la création d’un projet. Pour cela, cliquez sur le bouton de la barre des tâches en haut à gauche et sélectionnez « Project… » dans la liste qui apparait. Dans la fenêtre de sélection du type de projet, choisissez « Empty Project » et cliquez sur « Go ».

newprj01

Saisissez le nom de votre projet et son emplacement sur votre disque, puis faites « Next ».

newprj02

Sélectionnez le compilateur « SDCC Compiler » et vérifiez que la case « Create Release configuration » est bien cochée – personnellement je n’utilise plus « Debug » – puis cliquez sur « Finish ».

newprj03

Votre projet est maintenant créé, mais avant de programmer, il reste encore quelques petites choses à régler.

Configurer le projet

Première chose, nous allons configurer le compilateur pour ce projet. Faites un clic-droit sur le projet dans la partie « Management » à gauche, et sélectionnez « Build options » dans la liste. Une fenêtre s’ouvre, sélectionnez le nom du projet dans la partie gauche de cette fenêtre. Dans la partie droite, sélectionnez l’onglet « Compiler settings » puis l’onglet « Compiler Flags ». Dans la liste des options de compilation, toutes les cases doivent être décochées, à l’exception de :

Be verbose [--verbose],

Output Intel Hex (default) [--out-fmt-ihx],

[CPU] Microchip PIC 14-bit[-mpic14] si vous utilisez un PIC10, PIC12, un PIC14 ou un PIC16,

OU

[CPU] PIC 16-bit[-mpic16] si vous utilisez un PIC18.

configprjbuild01

Sélectionnez maintenant l’onglet « Other options » et écrivez-y --use-non-free pour indiquer au compilateur qu’il doit chercher les entêtes correspondant aux PIC dans ses dossiers d’entêtes non libres, et -pxxxxxxx pour le microcontrôleur que vous utilisez – pour moi qui utilise un PIC18F2550, je saisis -p18f2550.

configprjbuild02

Cliquez maintenant sur « OK » pour valider les changements. Si une fenêtre vous demande de confirmer que vous voulez appliquer les changements, acceptez.

Il reste une dernière étape. Faites à nouveau un clic droit sur le nom du projet et sélectionnez cette fois « Properties… ». Dans la nouvelle fenêtre, sélectionnez l’onglet « Build targets ». Dans la partie droite, pour l’attribut « Type », sélectionnez « Native ». Plus bas, pour « Output filename », remplacez le « .sys » par « .hex », puis décochez les cases « Auto-generate filename prefix » et « Auto-generate filename extension ». Enfin, cliquez sur « OK » pour quitter la fenêtre.

configprjproperties

Créer un fichier

Votre projet est désormais prêt pour la programmation. Ce dernier aspect sera abordé plus en détails dans un autre tutoriel. En attendant, voici un petit programme basique pour vous donner un aperçu d’un fichier source en C pour microcontrôleur.

</p>

<blockquote><span style="color: #008000;">#define __18F2550</span>
<span style="color: #008000;"> #include &lt;pic18f2550.h&gt;</span>

<span style="color: #008000;">#pragma stack 0x200 100</span>

<span style="color: #ff00ff;">void</span> main(<span style="color: #ff00ff;">void</span>)
{
<p style="padding-left: 30px;"><span style="color: #ff00ff;">unsigned</span> <span style="color: #ff00ff;">int</span> i;</p>
<p style="padding-left: 30px;">TRISB = <span style="color: #ff00ff;">0</span>;</p>
<p style="padding-left: 30px;"><span style="color: #ff00ff;">while</span>(<span style="color: #ff00ff;">1</span>)
{</p>
<p style="padding-left: 60px;">PORTBbits.RB7 = <span style="color: #ff00ff;">1</span>;
<span style="color: #ff00ff;">for</span> (i = <span style="color: #ff00ff;">1</span>; i &lt; <span style="color: #ff00ff;">1000</span>; i++);
PORTBbits.RB7 = 0;
<span style="color: #ff00ff;">for</span> (i = <span style="color: #ff00ff;">1</span>; i &lt; <span style="color: #ff00ff;">1000</span>; i++);</p>
<p style="padding-left: 30px;">}</p>
}

Il faut bien évidemment adapter __18F2550 et pic18f2550 selon le modèle de PIC que vous utilisez. Ce programme se contente en fait de faire clignoter en boucle la LED qui se trouve en sortie de PORTBbits.RB7 – qui est l’adresse d’un port d’entrée/sortie du microcontrôleur vous l’aurez compris. Ça fait rêver, n’est-ce pas ? ;)

EDIT : En essayant de faire fonctionner ce programme avec un PIC16F690, j’ai eu la désagréable surprise de constater que PORTBbits.RB7 n’est pas reconnu. Pas de panique, il suffit d’enlever « PORTBbits. » avant RB7. En effet, avec SDCC, les entrées/sorties sont définies différemment des cibles PIC18F. Nous reviendrons sur la portabilité dans une leçon ultérieure.

Vous pouvez enregistrer ce projet comme template personnalisé pour ne plus avoir à tout reconfigurer. Pour cela, Allez dans le menu « File » et sélectionnez « Save project as template… ». Il ne vous reste plus qu’à nommer ce template et à cliquer sur « OK ». Désormais, lors de la création d’un projet, il vous suffira d’aller dans la catégorie « User templates » et de choisir le template pour pouvoir créer un projet sur le modèle de celui que vous venez de créer et de configurer.

Pour le reste, je vous encourage à lire la documentation du compilateur SDCC et celle du microcontrôleur que vous utilisez. Nul besoin de les connaître sur le bout des doigts, mais cela vous permettra de vous familiariser avec la structure des programmes que vous devrez écrire. C’est d’ailleurs comme ça pour tous les outils de développement que vous serez amenés à utiliser. ;)

Sur ce, je vous laisse et vous dis à bientôt.

Nicolas SAN AGUSTIN

34 comments on “Comment programmer un PIC avec SDCC et Code::Blocks”

  1. bonjour,
    je viens de suivre ce billet à la lettre et pourtant je rencontre des problèmes de compliation
    1° la commande --use-nonfree est non reconnu
    Pour pallier cela j’ai introduit dans settings/compiler/global compiler settings/ onglet search directories le texte suivant : « C:\Program Files\SDCC\non-free\include\pic16 » ce qui résoud ce problème
    2° avec l’exemple du pic 18f2550 j’obtiens un warning avec la directive pragma :
    test1.c|4|warning 191: #pragma stack: bad argument(s); pragma ignored|
    comme je ne comprends pas je mets cette directive en commentaire puis je compile pour obtenir
    une nouvelle erreur généré par gpasm :
    ....Report bugs to:

    Processor: 18f452
    sdcc: Calling preprocessor..

    apparemment sdcc ne passe pas le bon processeur à gputils.
    Néanmoins j’obtiens un fichier *.asm mais pas de *hex
    Là je suis perdu.
    Je suis à la retraite et je voulais apprendre à programmer le pic en langage C.
    C’est pas gagné.
    Je réside dans les landes !
    Je vous souhaite une bonne journée, si vous avez une suggestion je suis preneur. D’avance merçi

  2. Bonjour,

    Avez-vous bien saisi --use-non-free ou --use-nonfree ?

    Pourriez-vous copier en commentaire la ligne de votre code qui pose problème, s’il vous plaît ?

    (Amusant que vous soyez landais. Je suis moi-même originaire de Bayonne :) )

  3. merçi de votre réponse
    mais j’ai été consulté la doc de SDCC et j’avais bien saisi la chaine --use-non-free enfin il me semble car j’ai bricolé les options du compilateurs de droite de gauche….. et maintenant il compile normalement.
    j’ai rajouté sur mon projet/build options/policy la chaine « use target only »
    Par contre en fin de compilation dans l’onglet build logs sdcc donne tout la chaine d’options.
    Est ce normal?
    2 question avec un pic 16f876 (qui traine dans mes tiroirs) je voudrais déclarer la configuration des fusibles CONFIG= _OSC_HS & …..
    je n’y arrive pas. Avez vous déjà fait cela ?
    Merçi d’avance

  4. je suis là à nouveau pour vous dire que tout va bien
    j’ai compiler plusieurs projet avec des 12, 16 et 18 pic. Tous compilent sans erreurs.
    J’attends votre nouveau post
    a+

    • Bonjour savin je suis comme vous je suis a la retraite et j’aimerais pouvoir écrire en c ,je n’arrive pas a configurer le compilateur ,vous dit que avez réussi a le faire pouvez vous me donner quelque conseille et exemple ,merci d’avance

  5. Si à présent cela compile parfaitement, tout va bien. C’est vrai qu’il faut parfois jouer un peu d’astuce à cause de tel ou tel caprice de la machine. Même si je me demande encore ce qui a bien pu se passer.

    Pour les bits de configuration, la doc mentionne deux méthodes (Chapitre 4.6.17 : Configuration Bits). La plus recommandée est celle qui consiste à utiliser la directive de préprocesseur #pragma config pour ensuite attribuer une valeur directement à chaque bit de configuration.
    Exemple :

    Après, pour savoir quels sont les noms des constantes correspondants à ces bits de configuration, je préconise de se référer directement à l’entête correspondant au microcontrôleur (« pic16f876.h » en ce qui vous concerne) et de recouper avec la documentation du micro.
    Ces entêtes se trouvent dans /non-free/include/pic14 (ou pic16 si on utilise des PIC18).

    J’espère avoir pu vous aider. Je vais tenter de faire d’autres tutoriels, si j’en trouve le temps.

  6. Bonjour et merci pour tous vos conseilles et astuce .je n’arrive pas a configurer le compilateur ,les fichiers code::blocks et sdcc et gputils dois t’ ils est ensemble dans le même dossier ? et comment déclaré a codeblocks le fichier gputils ,car je suis sur que mon problème de compilation et la.a chaque fois que veux compiler et me dis :
    sdcc.exe --out-fmt-ihx -mpic14 --verbose -use-non-free -I"C:\Program Files\SDCC" -c "C:\Documents and Settings\Escubedo pascal\Bureau\prog_C\toto.c" -o "C:\Documents and Settings\Escubedo pascal\Bureau\prog_C\toto.o"
    at 1: warning 117: unknown compiler option '-use-non-free' ignored
    No processor has been specified (use -pPROCESSOR_NAME)
    .
    Pouvez vous m’aider merci d’avance

    • Ils n’ont pas besoin d’être dans le même dossier. En fait, on configure Code::Blocks pour qu’il reconnaisse SDCC et sache l’utiliser mais GPUtils est utilisé directement par SDCC lorsqu’il compile un programme pour un PIC. Il ne peut l’utiliser que s’il sait où il se trouve, et pour ce faire il passe par la variable d’environnement PATH (dans Windows) qui regroupe les emplacements de différents programmes. Les dossiers des programmes SDCC et GPUtils sont automatiquement ajoutés dans la variable PATH de l’utilisateur courant lors de leur installation.

      Mais je ne pense pas que votre problème soit lié à ça. Selon le message d’erreur que vous avez reporté, dans les options du compilateur vous avez apparemment oublié de spécifier le microcontrôleur que vous utilisez (avec l’option « -pxxfxxxx » (qui désigne au compilateur le modèle de microcontrôleur que vous utilisez, comme ceci : -p18f2550).

      Tenez-moi au courant.

      • Bonjour et merci pour votre réponse ,je n’arrive toujours pas a crée un fichier .hex ,il cree un fichier asm pas plus et des warning type :

        -------------- Build: Release in toto (compiler: SDCC Compiler)---------------

        sdcc.exe -L"C:\program files\sdcc\lib" -L"C:\Program Files\SDCC\non-free\lib" -o bin\Release\toto.hex --out-fmt-ihx -mpic16 --verbose --out-fmt-ihx -mpic16 --verbose -use-non-free -p18f458 --out-fmt-ihx -mpic16 --verbose -use-non-free -pic16 -p18f458 obj\Release\main.o
        libdev18f458.lib: No such file or directory
        at 1: warning 117: unknown compiler option '-use-non-free' ignored
        at 1: warning 117: unknown compiler option '-use-non-free' ignored
        WARNING: Command line option --use-non-free not present.
        When compiling for PIC14/PIC16, please provide --use-non-free
        to get access to device headers and libraries.
        If you do not use these, you may provide --no-warn-non-free
        to suppress this warning (not recommended).
        Processor: 18f458
        sdcc: Calling linker...
        Process terminated with status 1 (0 minutes, 0 seconds)
        0 errors, 0 warnings (0 minutes, 0 seconds)

        pouvez vous me donner un peu plus de détaille sur la configuration du compilateur;
        merci d’avance

        • En fait il faut mettre deux tirets au début de l’option use-non-free mais apparemment WordPress fait des misères dans l’article et les commentaires en retirant automatiquement le deuxième tiret. Je vais essayer d’arranger ça.

          Edit : Ça y est, c’est corrigé. Vive la balise code !

  7. bonsoir j’ai suivis vos conseilles et ça marche ,
    j’ai un nouveau problème le petit programme ne fonction pas avec Isis il manque quelque chose ,bon je vais chercher ,grand merci pour votre aide

  8. Ah oui. J’en avais entendu parler (mais seulement sous le nom de Proteus). C’est vrai que c’est un logiciel intéressant même si je n’ai pas encore saisi l’occasion de l’essayer, jusqu’à présent. Je vais voir ça. Merci.

  9. root@constantin-SATELLITE-C50-A-19U:~/exemples# sdcc -mpic16 -p18f97j60 -L/usr/local/lib/pic16 led1.c
    WARNING: Command line option --use-non-free not present.
    When compiling for PIC14/PIC16, please provide --use-non-free
    to get access to device headers and libraries.
    If you do not use these, you may provide --no-warn-non-free
    to suppress this warning (not recommended).
    WARNING: The target device seems to support XINST and no #pragma config XINST=OFF was found.
    The code generated by SDCC does probably not work when XINST is enabled (possibly by default).
    Please make sure to disable XINST.
    (If the target does not actually support XINST, please report this as a bug in SDCC.)
    message: using default linker script "/usr/local/share/gputils/lkr/18f97j60.lkr"

    Bonjour ici
    je suis entrain de compiler un projet test et il me génère déja ces warning comment puis- je les corriger. ci dessus le codeb d’erreur affiché.

    • J’ai pris soin de fusionner les deux commentaires, pour plus de commodité.

      SDCC est par défaut un compilateur libre mais il utilise des fichiers non libres pour la gestion des cibles de Microchip. Comme il ne les inclut pas par défaut, il faut rajouter l’option --use-non-free pour que le compilateur prenne en compte les répertoires « non-free ».
      Pour ce qui est de XINST, le compilateur avertit juste que selon lui le programme pourrait ne pas fonctionner si XINST est activé et conseille d’ajouter une ligne #pragma config XINST=OFF pour le désactiver, au cas où.

      Edit : la ligne en question est à ajouter dans le fichier source du programme. Le mieux serait de placer cette ligne juste après #include "pic18f97j60.h".

  10. Merci pour la réponse j’ai réussir à compler le projet test qui me rassure maintenant sur la fonctionnalité de sdcc. Maitenant sur mon projet en question quand je compile je n’ai que ces erreurs
    TCPIP_Stack/ETH97J60.c:285: warning 212: support for long long literals is incomplete
    TCPIP_Stack/ETH97J60.c:285: warning 212: support for long long literals is incomplete
    TCPIP_Stack/ETH97J60.c:285: warning 212: support for long long literals is incomplete
    TCPIP_Stack/ETH97J60.c:285: warning 212: support for long long literals is incomplete
    allocated more than 4 or 0 registers for type unsigned-longlong-int fixed
    Caught signal 11: SIGSEGV
    make: *** [Objects/ETH97J60.o] Erreur 1

  11. Comment puis je interpréter ces erreurs:
    Caught signal 11: SIGSEGV
    make: *** [Objects/ETH97J60.o] Erreur 1

    • Apparemment, ce que vous essayez de compiler utilise des variables de type long long (sur 64 bits, soit 8 octets). Le souci c’est que ce type n’est pas encore supporté par le compilateur pour les cibles de type PIC. Il va falloir adapter votre code soit en utilisant des types long (4 octets), soit en usant d’astuce pour créer un type de données sur 8 octets (ce qui n’est pas forcément évident mais ça reste faisable, même si ce ne sera pas pareil qu’un type de base).

  12. Bonjour,
    j’ai suivi votre tuto mais cela ne marche pas pour moi.

    Quelle version utilisez vous pour sdcc, codeblock et gputils ?

    Merci

    Olivier

    • Bonjour.

      Sans d’autres informations, je ne saurai pas dire d’où vient votre problème. Mais il y a fort à parier que c’est bien un problème de versions. Voici donc celles que j’utilise :

      SDCC 3.4.2
      GPUtils 1.4.0
      Code::Blocks 13.12

      En espérant que cela résoudra le problème.

    • En fait c’est parce qu’il s’agit d’une version compilée directement à partir du code source – récupéré sur le dépôt SVN. Vous pouvez utiliser la version stable 3.4.0, ça devrait suffire.

      Pour savoir, quelles sont les versions dont vous disposiez avant cette question ? Je devine que vos versions ne sont pas à jour, sûrement parce que comme pour moi vous êtes sur une distribution Linux qui ne propose pas de versions récentes de SDCC et GPUtils. Mais je me trompe peut-être.
      Personnellement, il m’a fallu compiler directement les sources pour avoir une version de SDCC qui supporte la programmation PIC et qui puisse s’interfacer correctement avec GPUtils.

  13. j’ai essayé de nouveau avec
    SDCC 3.4.0
    GPUtils 1.4.0
    Code::Blocks 13.12

    sous windows 32

    j’obtient ce message :

    ————– Build: Release in testpic (compiler: SDCC Compiler)—————

    Linking stage skipped (build target has no object files to link)
    Nothing to be done (all items are up-to-date).

    • C’est étrange. Vous avez essayé de faire un « Rebuild » pour voir s’il parvient à compiler ?

  14. je viens de trouver:

    -propriété du projet dans « Build targets » , « Platforms » enlever « all » et choisir Windows.

    merci pour votre aide

  15. Merci bien, c’est le tutoriel que je cherchais pour programmer des micro-controlleurs sous linux; bonne suite.

    • Made by myself, I haven’t. But you can look into source code of the Pinguino bootloader.

      https://github.com/PinguinoIDE/pinguino-bootloaders

      Actually, it can be very interesting to study how this bootloader works, not only for USB but really for many features.

      Sorry but I’m really busy and I can’t write articles nor tutorials for the moment, but when my situation will be stable, I’ll try to publish some big article/tutorial about PIC.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Copyright Nicolas SAN AGUSTIN 2018
Tech Nerd theme designed by Siteturner