‘TMS320F28335 Experimenter Kit’ – Détails sur l’exemple de mise en oeuvre du kit.

Vous trouverez ici la présentation détaillée du projet d’exemple de mise en oeuvre du ‘TMS320F2833 Experimenter Kit‘. L’exemple proposé ici permet de créer deux versions du même programme, l’un destiné à être chargé en RAM, l’autre à être implanté en mémoire FLASH pour rester résident sur la cible et s’exécuter automatiquement à la mise sous tension du Kit. De plus, l’exemple que nous proposons exploite une liaison RS232 et la connexion JTAG pour échanger des messages avec la console de Code Composer Studio et acceder au système de fichiers de l’ordinateur hôte.

Télécharger les fichiers sources du projet d’exemple ici

La structure des projets.

Zoom sur la vue des projets CCS

 

La vue ‘Project Explorer’ fait apparaître les deux projets ‘RAM_loaded’ et ‘FLASH_loaded’ basés sur les mêmes fichiers sources. Les deux projets présentent bien entendu de fortes similitudes mais l’on note que la différence principale réside dans le nom du fichier de commande destiné à fournir les directive de placement au ‘linker’. L’analyse des fichiers de commande ‘28335_FLASH_lnk.cmd’ et ‘28335_RAM_lnk.cmd’ vous permettra de comprendre comment les différentes sections de code seront placées en mémoire FLASH ou en mémoire RAM à l’aide de l’interface JTAG intégré sur le Kit du TMS320F28335.

Même lorsque le programme doit résider en mémoire FLASH, il est nécessaire que certaines fonctions d’initialisation soient relogées en RAM. C’est le cas notamment de la fonction qui initialise les registres de contrôle de la mémoire FLASH pour ajuster les temps d’attente afin de tirer les meilleures performances possible de cette zone de mémoire (pendant l’initialisation de ces registres la mémoire peut ne pas répondre normalement et le code ne peut donc pas s’exécuter directement à partir de cet espace mémoire). L’initialisation des périphériques est donc légèrement différente selon la version d’exécution du programme. Le code source contient des directives conditionnelles (#if / #endif) qui permettent de gérer les deux versions à l’aide d’un symbole prédéfini dans les options de chacun des projet. La version du projet destiné au chargement du programme en mémoire FLASH contient la définition du symbole nommé ‘FLASH_CODE’ afin de faire apparaître les directives conditionnelles nécessaires à l’initialisation de la mémoire FLASH dans la fonction ‘InitHW()’ appelée depuis la fonction ‘Main()’ (c’est la première fonction appelée par le programme).

Symbole prédéfini pour exécution du code en FLASH
Définition du symbole FLASH_CODE dans les options du projet

L’initialisation du TMS320F28335

Le fichier source ‘init.c’ regroupe l’essentiel des initialisations réalisée par la fonction ‘InitHW()’.  L’initialisation du DSP TMS320F28335 comprend en premier lieu la désactivation du watchdog interne du DSP, l’initialisation de la PLL à la vitesse maximum supportée par ce DSP (150MHz) et la configuration de la distribution de l’horloge principale aux périphériques internes du DSP.

CCS HW init view

Vient ensuite l’initialisation des entrées et sorties du DSP, et en particulier celles qui sont accessibles à partir des connecteurs du ‘TMS320F28335 Experimenter Kit’ (voir la fonction ‘InitGPIO’ contenue dans le fichier ‘init.c’). Pour notre application de démonstration, la plupart des entrées / sorties ne sont pas utilisées. Les signaux du DSP sont alors configurés en mode GPIO (General Purspose Input / Output), en tant qu’entrée avec activation d’une résistance de rappel à l’état haut (résistance de ‘pull-up’ programmable).

Les signaux GPIO 31 et GPIO 34 sont utilisés sur le kit pour piloter l’allumage de deux diodes LED rouges (GPIO 31 pour la diode LED n° 1 et GPIO 34 pour la diode LED n°2). Ces signaux sont donc configurés en sortie et mis au repos (état haut pour éteindre les diode LED). Les résistances de ‘pull-up’ sont également désactivées pour ces deux sorties.

Les signaux nécessaires au fonctionnement de la liaison RS232 supportée par le Kit (GPIO 28 et GPIO 29) sont initialisés dans un premier temps en tant qu’entrées par la fonction ‘InitGPIO’ . Elles seront ensuite affectées à la fonction SCI ce qui aura pour effet de surpasser la configuration initiale de ces signaux.

CCS init interruptVient ensuite l’initialisation du contrôleur d’interruption et la table des vecteurs d’interruption. Ici nous avons fait appel aux fonctions fournies par Texas Instrument qui propose un gestionnaire d’interruption par défaut pour toutes le interruptions potentielles que sait gérer le DSP TMS320F28335 (voir le fichier ‘DSP2833x_DefaultIsr.c’ contenu dans le sous répertoire ‘COMMON_LIB\DSP2833x_common\source’).

Les fonctions d’interruptions par défaut se contentent de mettre le DSP en mode ‘halt’ si d’aventure l’interruption venait a être servie. Bien entendu cela n’est pas le traitement approprié pour les interruptions que nous souhaitons exploiter, cependant cette initialisation des vecteurs d’interruptions permet de garantir que les interruptions mal gérées seront au moins interceptées.

Immédiatement après, le vecteur d’interruption du TIMER0 est remplacé par un pointeur sur la routine ‘GESTION_INT_TIMER0’ localisée dans le fichier source ‘gestion_timer.c’. Notre application utilise le TIMER0 pour séquencer un petit automate ‘temps réel’ à la milliseconde (pour cette version du programme, notre séquenceur se contente d’appeler les fonctions de gestion des entrées et des sorties toutes les 10ms).

Vient ensuite l’initialisation de la mémoire FLASH. Cette opération est réalisée seulement pour la version du programme destiné à être chargée en FLASH. La fonction ‘InitFlash’ est recopiée en RAM avant d’être appelée depuis la zone fraîchement copiée (voir les explications à ce sujet, en début de page, dans la section sur la structure des projets).

La fonction main poursuit ensuite avec l’initialisation du module SCI n°1 qui sera utilisée en tant qu’UART (Universal Asynchronous Receiver Transmitter) puis l’initialisation des variables globales du programme. Nous avons ajouter la déclaration de la variable globale ‘tmp’  juste pour l’exemple car notre programme ne fait pas grand chose de cette variable à part l’incrémenter à chaque itération de la boucle principale, pour pouvoir observer une variable ‘vivante’ dans l’interface de debug offerte par CCS. Notez la petite astuce que nous utilisons régulièrement dans nos applications, pour instancier les variables et les déclarer en même temps depuis le fichier d’entête ‘Variables.h’. Dans le fichier ‘Variables.c’, nous définissons une constante nommée ‘CREATION_VARIABLES’ avant l’inclusion du fichier d’entête ‘Variables.h’. Cette constante est déclarée uniquement dans le fichier ‘Variables.c’ car elle va permettre d’instancier les variables déclarées dans le fichier d’entête.

Dans le fichier ‘Variables.h’ nous déclarons une deuxième constante nommée ‘VARTYPE’ dont la valeur est vide si la constante ‘CREATION_VARIABLES’ existe sinon ‘VARTYPE’ prend la valeur du mot clé ‘extern’. Puis pour chaque variable globale déclarée dans le fichier ‘Variable.h’ nous ajoutons ‘VARTYPE’ devant la déclaration. Cela permet de faire disparaître ‘VARTYPE’ lors de son inclusion dans le fichier ‘Variables.c’ (ce qui a pour effet d’instancier les variables dans cette unité) et permet de déclarer les variables avec le type ‘extern’ dans tous les autres unités qui influeront le fichier ‘Variables.h’. Cela évite d’écrire deux fois le nom des variables globales et évite les erreurs liées aux fautes de frappe.

Revenons maintenant à l’initialisation de L’UART dans le fichier ‘Main.c’. Pour permettre aux fonctions de la librairie standard (fprintf par exemple) d’envoyer un flux sur la liaison série nous avons implémenté un driver tel que préconisé par Texas Instrument dans sa note d’application spra861. Les fonctions de notre driver (voir le contenu du fichier ‘gestion_uart_a.c’) sont recensé par la fonction Main qui appelle la fonction ‘add_device’.

Vue CCS Console JTAGUne fois toutes ces initialisations terminées, le programme peut enfin entrer dans sa phase utile et exploiter les fonctions de la librairie standard pour envoyer des messages à la console de CSS ou bien envoyer des messages à un terminal connecté à la liaison RS232 raccordée à l’interface SCI n°1 du DSP.

Notez que lorsque vous connectez le Kit du TMS320F28335 à un ordinateur, il est vu comme 2 interfaces séries raccordées simultanément à l’ordinateur. En effet le composant FTDI utilisé sur le Kit pour simuler l’interface JTAG de programmation du DSP possède 2 canaux de communication. Le deuxième canal est connecté à la liaison SCI n°1 du DSP qui apparait sur l’ordinateur hôte comme un port série virtuel.

Pour afficher les messages envoyés sur le port série de l’ordinateur par notre DSP, il suffit de lancer un programme d’émulation de terminal RS232 Vue IHM DSP via RS232 et PUTTY(tel que PUTTY par exemple) pour entrer en communication avec le DSP au travers du driver de l’UART qui est recensé par la fonction Main. Dans le cas de notre programme d’exemple les fonctions sont très simples. Le programme se contente d’afficher une petit menu lorsque l’utilisateur envoie le caractère ‘?’ et il affiche ensuite l’option choisie lorsque celle ci est valide. Bien entendu cela ne sert pas à grand chose, mais c’est un exemple qui pourra vous servir de base de départ pour concevoir des applications complètes.

Notez également que, toujours à titre d’exemple, le programme crée un petit fichier nommé ‘Test.txt’ dans le répertoire ‘Debug’ du projet exécuté à partir de la liaison JTAG.

Voila donc un ensemble de fonctions fort utiles mise en œuvre très simplement dans le cadre d’un petit projet simple qui, nous l’espérons, pourra vous servir pour mettre rapidement en routes de nombreuses applications basées le Kit du DSP TMS320F28335.