Ecole Nationale des Sciences Appliquées Oujda
Polycopié de Travaux Pratiques DSP
Filière Génie Electrique S. E. NAIMI
Option Microélectronique
Généralités
L’ensemble C6713 DSK (Development System Kit) est un outil de développement qui permet à des utilisateurs de mettre au point et de tester des applications utilisant le processeur de traitement de signal Texas Instruments (TI) TMS320C6713. Autour de ce DSP sont connectés une grande variété de périphériques permettant une large gamme d’applications en traitement numérique du signal. Ainsi, la configuration réalisée est une référence qui, dans beaucoup de cas standards, peut éviter le temps de développement du « hardware ».
La carte
TMS320C6713 : DSP de la gamme TI travaillant à 225 MHz. Il est connecté à ses périphériques par un bus de 32 bits. Un « codec » stéréo AIC23 dédié à l’interfaçage pour les applications « audio ». Il comprend les convertisseurs CAN pour la capture de signaux (LINE IN, MIC IN) et les convertisseurs CNA pour l’exportation de signaux (LINE OUT, HP OUT). Le dialogue entre le processeur et le codec est réalisé par un multiplexeur McBSP (Multi-channel Buffered Serial Port), c'est-à-dire un multiplexeur à port série. En réalité, intégrés avec le processeur, il y a deux multiplexeurs : McBSP0 qui est prévu pour le
Page 2 sur 24
contrôle du codec (programmation de fonctions et des tâches) et McBSP1 qui est chargé de l’échange des données collectées ou à transmettre. Une CPLD : composant de logique programmable qui contient entre autre la logique de connexion des divers composants entre eux. Elle contient aussi des registres accessibles à l’utilisateur permettant de configurer la carte ou d’accéder à la configuration en place. Une SDRAM synchrone de 8 Méga-octets. Une mémoire Flash de 512 Kilo-octets. 4 LEDs et 4 interrupteurs (DIP) accessibles par les registres de la CPLD et permettant un dialogue simple entre la carte et l’utilisateur. Des options d’initialisation configurables (SW3). Une possibilité d’extension standard vers une autre carte (Peripheral Expand). Une émulation JTAG autorisant le dialogue avec un hôte extérieur via une connexion USB. Une seule alimentation est requise en +5V.
Le logiciel : Code composer studio (CCs) Fourni avec le kit de développement, le CCS contient tous les outils logiciels nécessaires pour la réalisation d’applications avec la carte précédente. Le cœur de ce système est un IDE (Integrated Development Environment) qui permet de travailler sur l’ordinateur hôte à partir d’une seule fenêtre d’application. Les utilitaires sont ainsi accessibles par menus déroulants et boîtes de dialogue. Cela comprend :
La configuration de CCS. L’édition de programmes d’application en C ou C++. La génération de code (compilation, édition des liens, assembleur). La visualisation et (ou) modification du code assembleur. Ceci permet une optimisation du code. Chargement de l’application dans la mémoire de la carte cible. Une aide au développement autour d’un noyau temps réel qui permet : une planification des tâches, une capture et analyse (liste, graphes) en temps réel des données manipulées.
CCS est un environnement IDE qui incorpore les outils logiciel nécessaires au développement. Il inclut les outils pour la génération du code tel qu’un compilateur C, un assembleur et un linker. Il support le « debugging » temps réel. Le processus (simplifié) permettant d’aboutir à un fichier exécutable à partir d’un programme écrit en langage C, est le suivant :
Page 3 sur 24
•
•
programme source écrit en C extension : .c
Compilateur C
•
•
fichier source assemblé extension : .asm
Assembleur
•
•
fichier objet, fichier en langage machine extension : .obj
Linker
•
•
•
•
combinaison des fichiers objets et les librairies produit un exécutable extension : .out Ce fichier exécutable est sous le format COFF (common object file format)
Le fichier .out est alors chargé, exécuté sur le processeur C6713
Page 4 sur 24
Types de fichiers et Extensions Vous travaillerez avec plusieurs fichiers avec des extensions différentes. 1. Fichier.pjt : pour créer et construire un projet nommés Fichier 2. Fichier.c : programme source en langage C 3. Fichier.asm : programme source assemblé créé par l'utilisateur, par le compilateur C ou par l'optimiseur linéaire (linear optimizer) 4. Fichier.sa : programme source de l’assembleur linéaire. L'optimiseur linéaire peut produire à partir de ce fichier un programme assemblé Fichier.asm 5. Fichier.h : fichier de support (d'entête) 6. Fichier.lib : fichier bibliothèque 7. Fichier.cmd : fichier de commande du Linker (mappage des sections vers la mémoire) 8. Fichier.obj : fichier objet créé par l ’assembleur 9. Fichier.out : fichier exécutable créé par le linker devant être chargé et exécuté par le processeur C6713 10. Fichier.cdb : fichier de configuration quand le DSP/BIOS est utilisé Instalation de Code Composer Studio 1. Vérifiez que vous avez les privilèges d’un administrateur sur votre PC, que les anti-virus sont désactivés et que la carte n’est pas connectée au PC 2. Mettez le CD (CCS) dans le lecteur de CD, attendez l’apparition du menu 3. Sélectionnez « Install Product » 4. Installez les trois produits : C6000 Code Composer Studio, FlashBurn, et DSK6713 Drivers & Target Content (Dans le dossier C:\C6713) 5. Des icones apparaissent dans le bureau de votre PC : C6713 DSK CCStudio v3.1 et 6713 DSK Diagnostics Utility v3.1 6. Laissez le CD dans le lecteur pour une prochaine étape (l’installation des Drivers) Connexion de la carte DSK 1. Connectez le câble USB à votre PC (une extrémité du câble seulement) 2. Branchez, s’il y a lieu, les connexions audio (microphone, haut parleur,…). La tension à l’entrée audio ne doit en aucune manière dépasser 2 Volts crête à crête (2Vpp) 3. Connectez l’adaptateur à la prise murale 4. Connectez l’adaptateur à la carte DSK, et attendez le cycle des diodes 10-15 secondes. En fin de cycle deux diodes restent allumées 5. Connectez l’extrémité restante du câble USB à la carte DSK 6. Laissez Windows trouver les drivers USB (automatique dans XP) Test de la connexion 1. Double cliquez sur l’icône 6713 Diagnostic 2. Appuyez sur « Start » et attendez les feus verts a. Si une erreur se produit à l’étape « Codec diagnostics », déconnectez toutes les entées sorties de AIC23 (MIC IN, LINE IN, …) 3. Appuyez sur « Stop » et quittez (fermez la fenêtre) Page 5 sur 24
Test d’un programme exemple
1. 2. 3. 4.
Décompressez le fichier zippé « test.zip » dans le dossier : C:\CCStudio_v3.1\MyProjects Lancez CCS (double cliquez sur l’icône du bureau, 6713 DSK CCStudio 3.1) Appuyez sur Alt-C pour connecter le logiciel à l a carte DSK ou Debug Connect File Load Program : a. Charger le programme : C:\CCStudio_v3.1\MyProjects\Sine8_LED\Debug\ Sine8_LED.out 5. Debug Run 6. Appuyez maintenant sur le bouton Switch #0 de la carte DSK, la diode #0 doit s’allumer, un signal de 1kHz est présent à la sortie audio de la carte (ceci génère un son audible si des hauts parleurs sont connectés à la carte), visualisez le signal de sortie à l’oscilloscope 7. Debug Halt
TP1 – Programmation d’exemples de test pour la DSK Trois programmes sont introduits pour illustrer quelques- uns des traits de l’outil CCS et de la carte DSK. L’objectif est de vous familiariser avec l’environnement logiciel et matériel.
Manipulation N°1 Cet exemple produit une sinusoïde à partir d’une table de données, il illustre quelques traits de CCS : édition, construction d’un projet, accès aux outils de génération de code, et exécution d’un programme sur le processeur C6713. Le code source en C, programme sine8_LED.c, ci-dessous sera étudié et implémenté.
Le programme Le programme est disponible dans le dossier TP1 sous l e nom Sine8_LED.c //Sine8_LED.c génération d’une fonction Sinus en appuyant sur un switch de //contrôle DIP #include "dsk6713_aic23.h" //fichier entête pour le codec,DSK Uint32 fs = DSK6713_AIC23_FREQ_8KHZ; //fixe la fréquence d’échantillonnage short loop = 0; //indice de la table
Page 6 sur 24
short gain = 10;
//facteur de gain
//valeurs de la sinusoïde short sine_table[8]={0,707,1000,707,0,-707,-1000,-707}; void main() { comm_poll(); DSK6713_LED_init(); DSK6713_DIP_init();
//initialisation de la DSK, du codec, et du McBSP //initialisation des LED à partir de BSL //initialisation des switch DIP à partir de BSL //BSL : Board Support Library (fonctions //incluses dans CCS sous forme de librairies //dsk6713bsl.lib //boucle infinie
while(1) { if(DSK6713_DIP_get(0)==0) { DSK6713_LED_on(0); output_sample(sine_table[loop]*gain); if (++loop > 7) loop = 0; } else DSK6713_LED_off(0); } }
//=0 si le switch #0 est enfoncé //la LED #0 et à l’état ON (allumée) //output chaque Ts (SW0 on) //vérification de fin de table //LED #0 off //fin de la boucle while(1) //end of main
Analyse du programme Une table sine_table est créé et rempli avec huit points qui représentent 1000 x sin(t), où t = 0, 45, 90, 135, 180, 225, 270 et 315 degrés. Dans la fonction principale main, une autre fonction, comm_poll , est appelée. Cette fonction est localisée dans le fichier support à la communication et à l'initialisation, « c6713dskinit.c ». Elle initialise la DSK, le codec AIC23 interne de la DSK, ainsi que les deux McBSPs sur le processeur C6713. La fonction fille DSK6713_init du fichier c6713dskinit.c initialise le fichier BSL « Board Support Library (dsk6713bsl.lib) » qui doit être appelé avant les deux subséquentes fonctions BSL, DSK6713_LED_init et DSK6713_DIP_init. Ces deux dernières fonctions sont invoquées pour initialiser les quatre LED et les quatre Switch. La déclaration while(1) dans la fonction principale crée une boucle infinie. Quand le switch #0 est pressé, la LED #0 est mise à l’état ON et une sinusoïde est produite. Autrement, DSK6713_DIP_get (0) sera faux (vrai si le switch est pressé) et la LED #0 est à l’état OFF. La fonction output_sample , situé dans le fichier de support à la communication, « C6713dskinit.c », est appelé pour mettre en sortie une donnée de la table sine_table[loop] (avec le gain). L'indice de la boucle est incrémenté jusqu'à la fin de la table puis réinitialisé. Chaque période de l'échantillonnage Ts = 1/fs = 1/8000 = 0.125ms, le switch #0 est testé, et la donnée subséquente de table sinus est envoyée (avec une mise à échelle, gain=10) à la sortie. Page 7 sur 24
Dans une période, huit valeurs des données (séparées de 0.125ms) sont produits pour générer la sinusoïde. La période du signal produit est T = 8 x 0.125ms = 1ms, elle correspond à une fréquence de f = 1/T = 1kHz.
Création du projet Dans cette section nous illustrons comment créer un projet, en ajoutant les fichiers nécessaires pour construire le projet sine8_LED. Le dossier TP1\Sin8_LED fournie par l’enseignant, contient trois fichiers : sin8_LED.c , gain.gel et sin8_LED.out .
Créer dans un premier temps le dossier C:\c6713\MyProjects\GE5\sine8_LED\ (ou C:\CCStudio_v3.1\MyProjects\GE5\sine8_LED\) Copier les fichiers sin8_LED.c et gain.gel et le dossier ‘‘Support’’ dans le dossier C:\...\GE5\sine8_LED
1. Pour créer le projet sine8_LED.pjt : Allez à Project New Entrez le nom du projet : sine8_LED Enregistrez le fichier dans le dossier : C:\c6713\MyProjects\GE5\sine8_LED\ Sélectionnez pour Target : TMS320C67XX Le fichier .pjt contient les informations sur la construction du projet, les noms des fichiers sources et les liens 2. Pour ajouter des fichiers au projet : Sélectionnez : Projet Add Files to Project Regardez dans le dossier TP1\support , choisissez le filtre de fichier : fichiers source de type C Cliquez deux fois sur le fichier source (en C) c6713dskinit.c pour l'ajouter au projet. Cliquez sur le symbole "+" du dossier Source dans la fenêtre Project File de CCS, et vérifiez que le fichier source en C est a été ajouté au projet De même que précédemment ajouter le fichier sin8_LED.c au projet 3. Répétez l’étape 2, pour ajouter les fichiers vectors_poll.asm et C6713dsk.cmd 4. Pour ajouter les fichiers librairies au projet, répétez l’étape antérieure : Ajoutez le fichier « run time » : C:\c6713\c6000\cgtools\lib\rts6700.lib au projet Ajoutez le fichier « BSL » :
C:\c6713\c6000\dsk6713\lib\dsk6713bsl.lib
Ajoutez le fichier « CSL : chip support library » :
C:\c6713\c6000\bios\lib\csl6713.lib ou C:\c6713\c6000\csl\lib\csl6713.lib 5. Vérifiez dans l’explorateur de fichier de CCS (CCS Project Windows) que : Le fichier projet (.pjt) Le fichier linker (.cmd) Les trois fichiers bibliothèque (.lib) Page 8 sur 24
Les deux fichiers source C (.c) Et le fichier assemblé (.asm) ; ont été ajoutés au projet. Le fichier GEL dsk6713.gel est ajouté automatiquement quand vous créez le projet. Ce fichier initialise la C6713 DSK en invoquant le BSL pour utiliser la boucle à verrouillage de phase (PLL) et fixer la fréquence de l’horloge du CPU (central processing unit) à 225MHz (autrement, la C6713 fonctionne à 50 MHz par défaut). 6. Notez qu'il n’y a encore, aucun fichier d’entête inclus « include » Sélectionnez : Project Scan All File Dependencies, ceci ajoute/inclus le s fichiers entête : c6713dskinit.h, dsk6713.h, dsk6713_aic23.h
La fenêtre de fichier CCS devrait apparaitre comme dans la figure ci-dessous. Tous les fichiers (excepté les fichiers bibliothèque) de la fenêtre peuvent être affichés en cliquant dessus. Vous ne devez pas ajouter de fichiers en-tête ou « include », ils sont ajoutés automatiquement au projet quand vous sélectionnez : Scan All File Dependencies (ils sont aussi ajoutés quand vous construisez (build) le projet) Il est aussi possible d'ajouter simplement les fichiers à un projet en sélectionnant ceux-ci et en les déposants dans la fenêtre projet de CCS.
Génération du code, les options Plusieurs options sont associées aux outils de génération de code (le compilateur C et le linker) pour construire un projet.
Les options du compilateur Page 9 sur 24
1. Sélectionnez : Project Build Options Onglet « Compiler » 2. Sélectionnez « Basic » sous « Category » puis les options suivantes : « c671x {- mv6710} » pour « Target Version » « Full Symbolic Debug (-g) » pour « Generate Debug Info » « Speed Most Critical » pour « Opt Speed vs Size » « None » pour « Opt Level » « None » pour « Program Level Opt » 3. Sélectionnez « Preprocessor » sous « Category » puis : Entrez « CHIP_6713 » pour « Pre-Define Symbols (-d) : » Entrez le chemin « C:\...\C6000\dsk6713\include 4. Sélectionnez « Feedback » sous « Category » puis : Sélectionnez « None » pour « Interlisting » 5. Sélectionnez « Advanced » sous « Category » puis : Sélectionnez « Far (-mem_model:data=far) » pour « Memory Models » Les options du compilateur sont finalement : -g -s L’option -g est utilisée pour avoir accès aux informations symbolique durant le débogage, ceci est très utile pendant le processus de débogage. Cette option est utilisée conjointement avec l'option -s pour « interlister » le fichier source en C avec le fichier assemblé Sine8_LED.asm généré (une option supplémentaire, -k, peut être utilisé pour retenir le fichier source assemblé). L’option -g désactive l’optimisation du code pour faciliter le processus du débogage. 6. Appuyez sur OK. La sélection de « C621x » ou « C64xx » pour « Target Version » invoque la mise en œuvre de l’option de calcul en virgule fixe. La DSK à base du C6713 peut faire le traitement en virgule fixe ou flottante. La sélection de « C671x » comme Version de la Cible invoque une mise en œuvre du calcul en virgule flottante. Si « No Debug » est sélectionné pour « Generate Debug Info » et « -o3 : File » est sélectionné pour « Opt Level », l'option du compilateur est automatiquement changée en : -s -o3. L’option -o3 invoque le plus haut niveau d'optimisation des performances ou de la vitesse d’exécution. Pour le moment, la vitesse n'est pas critique. Utilisez les options -g -s du compilateur (que vous pouvez taper directement dans la fenêtre commande en ligne du compilateur). Dans un premier temps le concepteur n'optimiserait pas la vitesse d’exécution mais la facilité de débogage. Plusieurs options du compilateur sont décrites dans la documentation « TMS320C6000 Optimizing C Compiler User’s Guide ».
Les options du Linker
1. Sélectionnez : Project Build Options Onglet « Linker » Page 10 sur 24
2. Sélectionnez « Basic » sous « Category » puis les options suivantes : « .\Debug\Sine8_LED.out» pour « Output Filename (-o) » « .\Debug\Sine8_LED.map» pour « Map Filename (-m) » « Run-Time Autoinitialization (-c) » pour « Autoinit Model » Décauchez () l’option « Suppress Banner (-q) » Cauchez () l’option « Exhaustively Read Libraries (-x) » 3. Sélectionnez « Advanced » sous « Category » et vérifiez qu’aucune case n’est cochée ou remplie. Le fichier Sine8_LED.map peut fournir des informations utiles pour déboguer le programme (emplacements des fonctions dans la mémoire, etc.). L’option -c est utilisée pour initialiser les variables, et l’option -o est utilisée pour nommer le fichier de sortie exécutable sine8_LED.out. Notez que vous pouvez/devez choisir d’entreposer le fichier exécutable dans le sous dossier \Debug au lieu du dossier \sine8_LED, surtout pendant l'étape du dé bogage d’un projet.
Construction et exécution du projet (Building and Runnig) Le projet sine8_LED peut maintenant être construit et exécuté. 1. Construisez le projet sine8_LED : Sélectionnez : Project Rebuild All ou appuyez sur l’icône i. Ceci compile et assemble tous les fichiers C en utilisant cl6x ii. Assemble le fichier assemblé vectors_poll.asm en utilisant asm6x iii. Le fichier objet résultant est lié avec les fichiers bibliothèque en utilisant lnk6x iv. Cela crée un fichier exécutable sine8_LED.out qui peut être chargé dans le processeur C6713 et exécuté. v. Un fichier log (cc_build_Debug.log ) est crée, il montre les détailles des étapes de compilation et d’assemblage 2. Sélectionnez : File Load Program Chargez l’exécutable : C:\...\sin8_LED\Debug\sine_LED.out
3. Sélectionnez : Debug Run ou appuyez sur l’icône 4. Connectez un haut parleur ou des écouteurs ou à défaut l’oscilloscope à la sortie LINE OUT de la DSK 5. Appuyez sur le switch #0 La diode #0 doit s’allumer Vous devez entendre au même temps un son (si vous disposé du matériel nécessaire) Vous devez voir à l’oscilloscope un signal sinusoïdal (Relevez la fréquence et l’amplitude de ce signal) Comme la fréquence d'échantillonnage Fs du codec est fixée à 8kHz. La fréquence du signal produit est f = Fs / (nombre de points) = 8 kHz/8 = 1kHz. L’amplitude approximative est de 0.8 V p-p (peak to peak). Page 11 sur 24
Correction des Erreurs 1. Effacez le point-virgule ‘‘ ; ‘’ de la ligne short gain = 10 du programme
sin8_LED.c 2. Sélectionnez : Project Build ou appuyez sur l’icône (incremental build) a. On choisi la construction incrémentale car seul le fichier sin8_LED.c est compilé 3. Un message d’erreur déclarant qu'un " ;" est attendu, devrez apparaître dans la fenêtre en bas à gauche de la fenêtre principale de CCS. 4. Cliquez deux fois sur la ligne du message d'erreur (en rouge). Cela devrait mettre le curseur à la section de code où l'erreur a lieu 5. Faite la correction appropriée, Construisez encore, chargez et exécutez le programme pour vérifier vos résultats antérieurs.
Monitoring de la fenêtre Watch Vérifiez que le programme est en court d’exécution dans le processeur, notez l’indicateur « DSP RUNNING » en bas à gauche de la fenêtre de CCS (faite un test du switch #0). La fenêtre Watch permet de changer la valeur d'un paramètre ou le monitorat d’une variable : 1. Sélectionnez : View Watch Window, une fenêtre doit apparaître en bas de CCS 2. Sélectionnez : View Quick Watch Tapez ‘‘gain’’ et cliquez sur ‘‘Add to Watch’’, la valeur du gain égale à 10 doit apparaître dans la fenêtre Watch 3. Changez le gain de 10 à 30 dans la f enêtre Watch. Appuyez sur ‘‘Enter’’ Vérifiez que l’amplitude de la sinusoïde a augmentée (avec le processeur toujours en exécution et le switch #0 enfoncé) L’amplitude du signal doit augmenter de 0.8V p-p à 2.5V p-p 4. Changez le gain à 33 (comme dans l ’étape 3). 5. Vérifiez que la fréquence du signal à augmentée. Ceci implique que la fréquence de la sinusoïde a changée juste en changeant son amplitude ! Ce n'est pas le cas. Vous avez dépassé la gamme du codec AIC23. Puisque les valeurs dans la table sont multipliées par 33, la gamme de ces valeurs est maintenant entre ±33,000. La gamme de valeurs 15 15 de la sortie est limitée entre -32 768 à +32 767 (ou de -2 à (2 - 1)). Puisque l'AIC23 est un codec stéréo, nous pouvons envoyer les données aux deux canaux à 16 bit à chaque période de l'échantillonnage (voir TP d'expérimentation des effets stéréo).
Application du fichier Slider Gel Page 12 sur 24
Le langage GEL (General Extension Language) est un langage interprété semblable à (un sous-ensemble de) C. Il vous permet de changer une variable telle que ‘‘gain’’ pendant que le processeur fonctionne. Toutes les variables doivent être au préalable être définies dans le programme source. 1. Sélectionnez : File Load GEL Ouvrez le fichier …\sine8_LED\gain.gel 2. Double-cliquez sur le fichier gain.gel pour le visualiser dans la fenêtre de CCS (le fichier est ci-dessous)
/*gain.gel Crée un bouton glisseur (slider) pour faire varier l’amplitude (gain) de la sinusoïde*/ menuitem "Sine Gain" slider Gain(10,35,5,1,gain_parameter) /*incr par 5, jusqu’à 35*/ { gain = gain_parameter; /*varier le gain de la sinusoïde*/ }
Le gain commence avec une valeur initiale de 10 (première valeur de ‘‘Slider Gain’’) jusqu'à une valeur de 35 (seconde valeur), incrémenté par 5 (troisièmement valeur). 3. Sélectionnez : GEL Sine Gain Gain Cela devrait faire apparaître la fenêtre du gli sseur (ci-dessus) 4. Faite déplacer le curseur augmenter la valeur du gain de 10 à 15 Vérifiez que l’amplitude de la sinusoïde produite a augmenté 5. Augmentez le gain jusqu’à 30, 31 puis 33 Vérifiez que l’amplitude de la sinusoïde produite est de l’ordre de 2.5V p-p et que la fréquence est de 1kHz 6. Augmentez le gain à 33, vérifiez la fréquence n’est plus égale à 1kHz
Changement de la fréquence de la sinusoïde générée
1. Changez la fréquence d’échantillonnage de 8 à 16kHz Page 13 sur 24
Affectez à fs la commande « DSK6713_AIC23_FREQ_16KHZ » (dans le fichier source en C) 2. Recompilez le projet (utilisez la construction incrémentale ; ‘‘Project Build’’ ou
) 3. Chargez et exécutez le nouveau fichier exécutable et vérifiez que la fréquence de la sinusoïde générée est de 2kHz. Pour rappel, les fréquences d’échantillonnage supportées par le codec AIC23 sont 8, 16, 24, 32, 44.1, 48 et 96 kHz 4. Changez le nombre de points dans la table (sine_table ) à quatre points au lieu de huit points, par exemple {0, 1000, 0, -1000}. La dimension de la table ‘‘sine_table ’’ et de l'indice de la boucle doivent aussi être changé Vérifiez que la fréquence de la sinusoïde générée est f = Fs/(nombre de points). 5. Si un changement de switch est désiré (switch #3 au lieu #0), les fonctions BSL DSK6713_DIP_get(3) , DSK6713_LED_on(3) , et DSK6713_LED_off(3) peuvent être substituées dans le programme source sine8_LED.c .
Travail personnel demandé Deux glisseurs peuvent être utilisés aisément, un pour changer le gain et l'autre pour le changement de la fréquence. Une fréquence différente du signal peut être produite en changeant l’indice de la boucle dans le programme C (par exemple en effectuant un saut par deux valeurs dans la table). Réalisez les modifications nécessaires au projet pour mettre en pratique l’idée des deux glisseurs (un pour la modification du gain et l’autre pour la modification de la fréquence du signal)
Page 14 sur 24
Manipulation N°2 Cet exemple produit une sinusoïde avec huit points, comme dans la manipulation N°1. Il illustre les capacités de CCS pour tracer des courbes dans les domaines temporel et fréquentiel. Le programme sine8_buf.c (ci-dessous) implémente ce projet. Ce programme crée une mémoire ‘‘tampon ’’ pour entreposer les données produites. 1. Créez ce projet « sine8_buf.pjt »
Ajoutez les fichiers nécessaires au projet, comme dans la manipulation N°1 (utilisez le programme source en C « sine8_buf.c » au lieu de « sine8_LED.c »).
//sine8_buf génération d’une sinus. Sortie bufférisée tracée avec CCS #include "dsk6713_aic23.h" Uint32 fs=DSK6713_AIC23_FREQ_8KHZ; int loop = 0; short gain = 10;
//fichier support codec-DSK // fixe la fréq. d’échantill. //indice de la table //facteur de gain
//valeurs de la sinusoïde short sine_table[8]={0,707,1000,707,0,-707,-1000,-707}; short out_buffer[256]; const short BUFFERLENGTH = 256; int i = 0;
//sortie buffer //taille de la sortie du buffer //pour le comptage du buffer
interrupt void c_int11() //interrupt service routine { //valeurs de la sinus vers la sortie output_sample(sine_table[loop]*gain); //valeurs de la sortie vers le buffer out_buffer[i] = sine_table[loop]*gain; i++;
//incrémentation du compteur buffer
//si compteur en fin buffer, réinitialise le compteur if(i==BUFFERLENGTH) i=0; if (++loop > 7) loop = 0; return;
//vérification si fin de table //retour de interrupt
} void main() { comm_intr();
//initialise DSK, codec, McBSP Page 15 sur 24
while(1);
//boucle infinie
} Les fichiers support pour ce projet, « c6713dskinit.c », « vectors_intr.asm » et « C6713dsk.cmd », sont dans le dossier …\TP1\support , et les trois fichiers librairie peuvent être ajoutés comme suit : 1. Sélectionnez : Projet Build Options 2. Sélectionnez Linker, puis dans l’option « Include Libraries » tapez les noms des trois fichiers librairies séparés par une vi rgule.
Notez que puisque ce programme gère des interruptions, le fichier « vectors_intr.asm » est ajouté au projet au lieu de « vectors_poll.asm ». Dans la fonction principale main, la fonction Comm_intr est appelée (au lieu de comm_poll dans la manip N°1). Cette fonction réside dans le fichier c6713dskinit.c pour supporter les programmes avec interruptions. La déclaration while(1) dans la fonction principale main crée une boucle infinie dans l’attendre d’une interruption. Sur interruption, l'exécution continue sur la routine c_int11 (Interrupt Service Routine (ISR)). Cette adresse ISR est spécifiée dans le fichier vectors_intr.asm avec une instruction de branchement à cette adresse, utilisant l'interruption INT11 (Les interruptions seront étudiées plus en détail dans les prochains TP). Dans l'ISR, la fonction output_sample , situé dans le fichier de communication & initialisation, c6713dskinit.c , est appelé pour mettre à la sortie les premières données de la table sine_table . L'indice de la boucle est incrémenté jusqu'à ce que la fin de la table soit atteinte; après cela, il est réinitialisé à zéro. Une sortie tampon est créée pour capturer un total de 256 (spécifié par BUFFERLENGTH) valeurs des données de la sinusoïde. L'exécution revient de l'ISR à la boucle infinie while(1) pour attendre chaque interruption subséquente. 1. Construisez ce projet sous le nom sine8_buf 2. Chargez et exécutez le fichier exécutable sine8_buf.out et vérifie qu'une sinusoïde de 1kHz est générée (à l’oscilloscope)
Le traçage avec CCS La sortie tampon est mise à jour chaque 256 points de façon continue (vous pouvez aisément changer la dimension du buffer). Utilisez CCS pour tracer les données à la sortie en cours de production entreposé dans le buffer out_buffer . 1. Sélectionnez : View Graph Time/Frequency 2. Changez les informations de la fenêtre ‘‘Graph Property Dialog’’ comme suit pour ‘‘Time-Domaine’’ : Page 16 sur 24
Graph Property Dialog Display Type Graph Title Start Address Acquisition Buffer Size Index Increment Display Data Size DSP Data Type Q-value Sampling Rate (Hz) Plot Data From Left-shifted Data Display Autoscale DC Value Axes Display Time Display Unit Status bar Display …..
Single Time Graphical Display out_buffer 256 1 64 16-bit signed integer 0 8000 Left to Right Yes On 0 On S On Laissez les valeurs par défaut pour le reste
L’adresse de départ du buffer de sortie est out_buffer , le reste des paramètres peuvent être pris par défaut 3. Changez les informations de la fenêtre ‘‘Graph Property Dialog’’ comme suit pour ‘‘Frequency-Domaine’’ :
Graph Property Dialog Display Type Graph Title Signal Type Start Address Acquisition Buffer Size Index Increment FFT Framesize FFT Order FFT Windowing Function Display Peak and Hold DSP Data Type Q-value Sampling Rate (Hz) Plot Data From Left-shifted Data Display Autoscale …..
FFT Magnitude Graphical Display Real out_buffer 256 1 256 8 Rectangle Off 16-bit signed integer 0 8000 Left to Right Yes On Laissez les valeurs par défaut pour le reste Page 17 sur 24
Choisissez pour « FFT Order » un ordre tel que la valeur donnée à « FFT ordre Framesize » soit 2 Appuyez sur OK Vérifiez que la FFT présente un pic à 1000Hz (fréquence de la sinusoïde générée)
Visualisation et sauvegarde des données de la mémoire vers un fichier Pour visualiser le contenu de la mémoire tampon (buffer), procédez comme suit : 1. Sélectionnez : View Memory Spécifiez out_buffer pour ‘‘address ’’ Sélectionnez ‘‘16-bit signed integer ’’ pour ‘‘format ’’ Pour sauvegardez le contenu de la mémoire tampon (buffer) dans un fichier, procédez comme suit : 1. Sélectionnez : File Data Save Sauvegardez le fichier comme ‘‘sine8_buf.dat ’’ (type hex, par exemple) dans le dossier « sine8_buf » Dans la fenêtre de sauvegarde de la mémoire (Storing Memory window), utilisez out_buffer comme addresse du buffer avec une taille de 256 (Vous pouvez tracer ces données (avec matlab) et vérifier que vous avez une sinusoïde de 1kHz (pour un échantillonnage de 8kHz))
Manipulation N°3 Les opérations telles qu'addition/soustraction et multiplication sont les opérations clés dans un DSP. Une opération très importante est la multiplication/accumulation, laquelle est utile un grand nombre d'applications qui exigent un filtrage numérique, la corrélation et l’analyse spectrale. Puisque l'opération de multiplication est essentielle pour la plupart des algorithmes DSP, l’exécution doit ce faire en un seul cycle. Avec le C6713 nous pouvons exécuter réellement deux opérations de multiplication/accumulation dans un seul cycle. Cet exemple illustre des utilités supplémentaires de CCS, tel que le débogage étape par étape, la configuration des points d’arrêt (setting breakpoints)… . L’objectif est se familiariser avec les outils de CCS. Nous invoquerons l'optimisation de compilateur C pour voir comment les performances ou la vitesse d'exécution peuvent être augmentées considérablement. //Dotp4.c Multiplication de deux vecteurs de 4 nombres chacun int dotp(short *a,short *b,int ncount); //fonction prototype #include //pour printf #include "dotp4.h" //fichier entête avec les données #define taille 4 //# donnée dans chaque vecteur
Page 18 sur 24
short x[taille] = {x_elements}; short y[taille] = {y_elements};
//déclaration du 1ier vecteur //déclaration du 2ème Vecteur
main() { int resultat = 0; //résultat la somme des produits resultat = dotp(x, y, taille); //appel de la fonction dotp printf("resultat = %d (decimal) \n", resultat); //affichage du resultat } int dotp(short *a,short *b,int ntaille) { int somme = 0; int i; for (i = 0; i < ntaille; i++) somme += a[i] * b[i]; return(somme); }
//la fonction produit //initialisation de la somme
//somme des produits //retourne somme comme résultat
//dotp4.h fichier entête avec deux vecteurs de nombre #define x_elements 1,2,3,4 #define y_elements 0,2,4,6
Le fichier source « dotp4.c » ci-dessus calcul la somme de produit de deux vecteur, chacun des vecteurs comporte quatre nombres, le contenu des deux vecteurs est dans le fichier d'en-tête « dotp4.h ». Le premier vecteur contient les quatre nombres 1, 2, 3 et 4, et le deuxième vecteur contient les quatre nombres 0, 2, 4 et 6. La somme des produits est (1 x 0) + (2 x 2) + (3 x 4) + (4 x 6) = 40. Le programme peut être modifié aisément pour manier un plus grand nombre de données. Aucune implémentation temps-réel n’est mise en œuvre dans cet exemple, et aucun fichier de support d’entré-sortie (I/O) en temps-réel n'est nécessaire. Les fonctions de support pour les interruptions ne sont pas exigées ici. Créez ce projet comme dotp4 et ajoutez les fichiers suivants au projet (voyez la manipe N°1): 1. Créez le projet comme ‘‘dotp4’’ 2. Ajoutez les fichiers suivants au projet : dotp4.c (fichier source en C) vectors_poll.asm (fichier vecteur qui définit l'adresse de l'entrée
c_int00 C6713dsk.cmd (fichier de commande du linker générique) rts6700.lib (fichier librairie) N’ajoutez aucun fichier ‘‘include’’ en utilisant « Add Files to Project » puisqu’ils sont ajoutés en sélectionnant Projet Scan All File Dependencies.
Le fichier d’en-tête stdio.h est nécessaire vue la déclaration printf dans le programme dotp4.c (pour imprimer le résultat). Page 19 sur 24
Implémentation de ‘‘Variable Watch’’ 1. Sélectionnez comme option du projet -gs comme option du compilateur Les options par défaut pour le Linker (aucune optimisation) Créez le projet comme ‘‘dotp4 ’’ 2. Appuyez sur (ou sélectionnez Project Rebuild All) Chargez le fichier exécutable dotp4.out (…\dotp4\Debug) 3. Sélectionnez : View Quik Watch Entrez somme et cliquez sur ‘‘Add to Watch ’’ Le message ‘‘identifier not found ’’ associé avec la variable somme est affiché car cette variable locale n’existe pas encore 4. Mettez un point d'arrêt (Breakpoint) à la ligne : somme + = a[i] * b[i]; du code Placez le curseur de la souris sur cette ligne et cliquer Appuyez sur le bouton droit de la sourie et sélectionnez l’interrupteur « Toggle Software Breakpoint » Ou bien, de préférence, avec le curseur à l’extrême gauche de la ligne du code, double-cliquez, un cercle rouge à gauche de cette ligne doit apparaître (Note : si vous placez le curseur sur la ligne du code avec un Breakpoint et si vous double-cliquez le breakpoint doit disparaître) 5. Sélectionnez : Debug Run (ou ) Le programme s’exécute jusqu'à (à l'exclusion de) la ligne de code avec le Breakpoint Une flèche jaune pointera aussi à cette ligne du code 6. Appuyez sur F8, pour une exécution pas-à-pas 7. Répétez ou continuez l’exécution pas-à-pas (appuyez sur ) et observez (Watch) le changement de valeur, de la variable somme dans de la fenêtre Watch, de 0, 4, 16, 40. 8. Sélectionnez : Debug Run Vérifie que la valeur de somme est imprimée comme : somme = 40
(décimal)(sélectionnez l’onglet Stdout en bas à gauche de CCS) Notez la déclaration printf dans le programme C ‘‘dotp4.c ’’ qui sert à imprimer le résultat. Cette déclaration (bien qu’excellente pour le débogage) devrait être évitée après le débogage, puisqu’elle prend 6000 cycles pour s’exécuter.
Animation 1. Sélectionnez : File Reload Program, pour rechargez le fichier exécutable dotp4.out. Ou, de préférence, choisissez : Debug Restart.
Page 20 sur 24
Notez qu’après le chargement du fichier exécutable, l’adresse d’entré pour l’exécution est c_int00, comme il est possible de vérifier avec le fichier dé-assemblée 2. Le même breakpoint devrait déjà être mis comme indiqué auparavant à la même ligne de code
Sélectionnez : Debug Animate (ou ) Observez le changement de la variable somme La vitesse d'animation peut être commandée en sélectionnant Option Customize Debug Properties Animate Speed (la vitesse maximale est mise par défaut à 0 seconde). Pour revoir l’animation il faut sélectionner Debug le fichier exécutable dotp4.out
Restart, pour rechargez
Benchmarking (profiling) sans Optimisation Dans cette section nous illustrons comment faire un Benchmarking (repérage) d’une section de code (dans ce cas, la fonction dotp).
Vérifiez que les options pour le compilateur (- g) et le Linker (- c - o dotp4.out) sont actifs Pour profiler (découper) le code, vous devez utiliser l'option du compilateur - g pour avoir les informations symbolique de débogage Enlevez tout les ‘‘breakpoint’’ En cliquant deux fois sur la ligne de code avec le ‘‘breakpoint’’ Ou bien en cliquant sur le bouton droit de la sourie et en sélectionnant l'interrupteur du breakpoint).
1. Sélectionnez : Debug Restart 2. Sélectionnez : Profile Setup (une fenêtre plus ou moins semblable à la fenêtre ci-dessous doit s’incruster dans CCStudio)
Page 21 sur 24
3. Cliquer sur les trois icones encerclées en rouge si-elles ne sont pas actives 4. Cliquez sur l’onglet « Custom » en bas de la fenêtre et cochez la case « Cycles » 5. Dans un premier temps la fonction « printf » ne doit pas apparaître dans votre fenêtre (sous l’onglet « Ranges »). Pour l’ajouter, procédez comme suit : Cliquez sur le bouton de droit de la sourie puis sur « Create Profile Item… »
La fenêtre « Add Profile Item » apparaît, elle permet de « profiler » : Page 22 sur 24
i. Les différentes fonctions d’un programme (Type = Function) ii. Les boucles (Type = Outer Loops ou bien All Loops) iii. Une suite d’instructions (Type = Range) Pour chaque cas il faut spécifier : i. Le nom de la fonction (avec Symbol Name active) ii. Les adresses de début et de fin (avec DSP Address active) iii. Les linges de début et de fin (avec Source Lines active
Pour l’instant nous voulons visualiser les informations relatives à la fonction printf (nombre de cycle), indiquez les informations présents dans la fenêtre précédente et cliquez sur OK 6. Sélectionnez : Profile Viewer (une fenêtre plus ou moins semblable à la fenêtre ci-dessous doit s’incruster dans CCStudio)
Si la fenêtre est vide Allez à Debug Restart puis exécutez le programme à nouveau (Debug Run) Si une ligne manque cliquez sur l’icône encerclée « Show all Profile Items »
7. Sélectionnez : Profile Clock Enable 8. Sélectionnez : Profile Clock View 9. Sélectionnez : Debug Restart, puis Debug
Run (ou bien appuyez sur
)
Page 23 sur 24
Vous devez à cet instant retrouver une fenêtre avec des données identiques à celles de la fenêtre précédente
Ainsi la fonction main() s’exécute en 6099 cycles, ceci est essentiellement dû à la fonction printf qui demande 5798 cycles pour son exécution. La fonction dotp() quant à elle nécessite 209 cycles (sans aucune optimisation).
Benchmarking (profiling) avec Optimisation Dans cette section nous illustrons comment optimiser le programme en utilisant une option d’optimisation, -o3 (voir page 10). La vitesse d’exécution du programme peut être augmentée en optimisant le compilateur C. 1. Changez l'option du compilateur (Projet Build Options) en : -g –o2 Utilisez les mêmes options du Linker que précédemment (vous pouvez taper ces options directement 2. 3. 4. 5. 6.
Rebuild All (ou ) Chargez le fichier exécutable dotp4.out (ou sélectionnez File Reload Program) Recréez le « Profiler » comme dans la figure précédente Sélectionnez Debug Run Vérifiez que le nombre de cycle pour exécuter la fonction dotp, est passé de 209 à 118 (c’est une amélioration considérable de 43,5%) 7. D’autres techniques d’optimisation peuvent être utilisées, comme l’optimisation du code (ces techniques seront étudiées ultérieurement) Les options –o2 et -o3 invoquent les plus haut niveaux d'optimisation du compilateur.
Profilling Printf 1. Sélectionnez encore une foi : Debug Restart 2. Cliquez sur l'icône ‘‘Ranges’’ 3. Sélectionnez printf du programme source C, traînez-la (printf ) à la fenêtre ‘‘Profile Area’’ et relâchez le curseur de la sourie 4. Vérifiez que la taille du code de printf est 32 et qu'elle prend 6316 cycles pour exécuter, comme montre la figure 5. Notez qu'au lieu d'utiliser la figure XX pour analyser la fonction dotp, vous pouvez la sélectionner la traîner jusqu’à la région ‘‘Profile Area’’
Page 24 sur 24