Vous êtes sur la page 1sur 53

Programmation C pour systmes embarqus

Sylvain MONTAGNY sylvain.montagny@univ-savoie.fr Btiment chablais, bureau 13 04 79 75 86 86


Retrouver tous les documents de Cours/TD/TP sur le site www.master-electronique.com

Prsentation des cours : Sommaire


z

Cours : 10.5 h en 7 sances


z z z

1re partie : Rappel sur le langage C (exercices de base) 2me partie : La programmation en langage C avance 3me partie : Implmentation de code sur cible embarque (DSP TMS 320C5416) 4me partie : Prsentation du TP : Ralisation dun algorithme de compression de donnes.

Universit de Savoie

Prsentation TP
z TD

: 20 h en 5 sances

Le but de ce projet est d'crire un programme de compression de fichiers textes, sans perte d'information. On demande galement d'crire un dcompresseur qui devra restaurer le fichier original. Lalgorithme propos ici est l'algorithme de Huffman.

Universit de Savoie

Examen

Une note :
z

14 points : Le droulement du TP/Projet jusqu la soutenance. 6 points sur la soutenance (prsentation de votre projet et de lintgration sur le DSP)

Universit de Savoie

1re partie : Rappel sur le langage C (exercices de base)


z

Donner lexcution du code suivant :


#include <stdio.h> #include <stdlib.h> int main(void){ unsigned char i; unsigned char tab[5]={1,2,4,8,16}; for (i=0;i<5;i++) { printf("Le %d elt est %d\n",i+1,tab[i]); } return EXIT_SUCCESS; }

Universit de Savoie

1re partie : Rappel sur le langage C (exercices de base)


z

Donner lexcution du code suivant :


#include <stdio.h> int main() { int i,j; for(i=0;i<5;i++){ for(j=5-i;j<5;j++){ printf("++"); } printf("\n"); } return EXIT_SUCCESS; }

Universit de Savoie

1re partie : Rappel sur le langage C (exercices de base)


z

crire une fonction C calculant la longueur d'une chane de caractres, donne en argument. Le prototype de la fonction est le suivant :

int longueur(char *s)

Universit de Savoie

1re partie : Rappel sur le langage C (exercices de base)


z

crire une fonction C calculant la longueur d'une chane de caractres, donne en argument.
#include <stdlib.h> int longueur(char *s) { int n = 0; while (s[n] != '\0') { n++; } return n; }

Universit de Savoie

1re partie : Rappel sur le langage C (exercices de base)


Soit un texte donn par une chane de caractres. Le but est de compter le nombre d'occurrences de chaque lettre minuscule. Question 1 : Raliser les dclarations suivantes :
z

Le texte (chane de caractre constante) sera dclar dans un tableau nomm ch . Vous afficherez la chane de caractre lcran. Un tableau d'entiers statique nomm occ . pour compter les occurrences de chaque lettre de lalphabet dont la taille est fixe par une constante (correspondant au nombre de lettre de lalphabet). Un pointeur nomm p pour parcourir le texte.

Universit de Savoie

1re partie : Rappel sur le langage C (exercices de base)

Universit de Savoie

10

1re partie : Rappel sur le langage C (exercices de base)


#include <stdio.h> #define NB_LETTRE 26; void main(void) { /* dclaration d'une chane <=> tableau de caractres. */ char ch[]="ceci est une chane de test";

/* dclaration d'un pointeur sur une chane de caracteres. */ char *p = ch; /* dclaration d'un tableau de 26 cases */ int occ[NB_LETTRE]; printf("Chane en mmoire : %s\n",ch); }

Universit de Savoie

11

1re partie : Rappel sur le langage C (exercices de base)


z

Question 2 : Initialiser le tableau doccurrence zro :

Universit de Savoie

12

1re partie : Rappel sur le langage C (exercices de base)


z

Question 2 : Initialiser le tableau doccurrence zro :


/* initialisation du tableau des occurrences 0. */ int i=0; for (i=0; i<NB_LETTRE;i++) occ[i]=0;

Universit de Savoie

13

1re partie : Rappel sur le langage C (exercices de base)


z

Question 3 : Compter les occurrences jusqu la fin de la chane de caractre :

Universit de Savoie

14

1re partie : Rappel sur le langage C (exercices de base)


z

Question 3 : Compter les occurrences jusqu la fin de la chane de caractre :


/* parcours de la chane jusquau \0 */ while (*p != '\0') { if ( (*p >= 'a) && (*p <= 'z) ) { occ[*p-'a'] = occ[*p-'a'] + 1; } p++; }

Universit de Savoie

15

1re partie : Rappel sur le langage C (exercices de base)


z

Question 4 : Afficher le contenu du tableau occ

Universit de Savoie

16

1re partie : Rappel sur le langage C (exercices de base)


z

Question 4 : Afficher le contenu du tableau occ

for (i=0; i<nb_lettres; i++) { printf("Nombre de %c : %d\n", 'a'+i,occ[i]); }

Universit de Savoie

17

2me partie : La programmation en langage C avance


z z z z z z z z z z z z z z z z

Lisibilit du code, les types de variables, les typedef, occupation mmoire, port des variables, les oprateurs, manipulation de registre, les structures, les pointeurs, le main(), pointeurs, la pile, type de fonction, allocation dynamique, les options doptimisations la compilation, les erreurs classiques du C

18

Lisibilit du code C
z

Exercice : Raliser un code qui imprime les N premiers lments d'un tableau dentier A[] en insrant un espace entre les lments et en commenant une nouvelle ligne aprs chaque dixime chiffre.

Universit de Savoie

19

Lisibilit du code C
void main(void){ int A[80],N,i; scanf(%d,&N); for (i=0; i<N; i=i+1){ printf("%d", A[i]); if ((i%10) == 9) printf("\n"); else printf(" "); }

Universit de Savoie

20

Lisibilit du code C
z

Voici une deuxime faon de coder, trs pratique mais beaucoup moins lisible.
void main(void){ int A[80],N,i; scanf(%d,&N); for (i=0; i<n; i++) printf("%d%c", a[i], (i%10==9)?'\n':' '); }

Universit de Savoie

21

Lisibilit du code C
z Quelques
Op. Fonction += Addition et affectation
-= Soustraction et affectation *= Multiplication et affection /= Division et affectation %= Modulo et affectation ++ Incrmentation

quivalences parfois viter


Exemple Equivalence nombre=nombre+5

nombre += 5;
nombre -= 6; nombre *= 3; nombre /= 2; nombre %= 4; nombre++;

nombre = nombre % 4 nombre = nombre + 1; nombre = nombre - 1; y x x y = = = = x x + 1 x + 1 x


22

-- Dcrmentation nombre--; y = x++ y = ++x

Universit de Savoie

Lisibilit du code C
#include <stdio.h> main(t,_,a)char*a;{return!0<t?t<3?main(-79,-13,a+main(-87,1_,main(-86,0,a+1)+a)):1,t<_?main( t+1, _, a ):3,main( -94, 27+t, a )&&t == 2 ?_ <13 ?main ( 2, _+1, "%s %d %d\n" ):9:16:t<0?t<-72?main( _, t,"@n'+,#'/*{}w+/w#cdnr/+,{}r/*de}+,/*{*+,/w{%+,/w#q#n+ ,/#{l,+,/n{n+,/+#n+,/#;#q#n+,/+k#;*+,/'r :'d*'3,}{w+K w'K:'+}e#';dq#'l q#'+d'K#!/+k#;q#'r}eKK#}w'r}eKK{nl]'/#;#q#n'){)#}w'){){nl]'/ +#n';d}rw' i;# ){nl]!/n{n#'; r{#w'r nc{nl]'/#{l,+'K {rw' iK{;[{nl]'/w#q#n'wk nw' iwk{KK{nl]!/w{%'l##w#' i; :{nl]'/*{q#'ld;r'}{nlwb!/*de}'c ;;{nl'{}rw]'/+,}##'*}#nc,',#nw]'/+kd'+e}+;#'rdq#w! nr'/ ') }+}{rl#'{n' ')# }'+}##(!!/"):t<-50?_==*a ?putchar(31[a]):main(-65,_,a+1):main((*a == '/') + t, _, a + 1 ):0<t?main ( 2, 2 , "%s"):*a=='/'||main(0,main(-61,*a, "!ek;dc i@bK'(q)-[w]*%n+r3#l,{}:\nuwloca-O;m .vpbks,fxntdCeghiry"),a+1);}
Universit de Savoie 23

Lisibilit du code C
z Rgle
z z z

respecter :

Mettre des commentaires explicites Ne pas trop compresser le code Respecter une homognit dans votre faon de coder. Organiser la mise en page de votre code, ou respecter celle dj existante.

Universit de Savoie

24

Les types de variables


char = 1 octet (signed ou unsigned) z Int, long, double, float dpendent de la cible processeur utilise.
z

Afin de connatre la taille (en octet) dune variable, on utilise la fonction sizeof() :
z

printf( int=%d octets , sizeof(int));

Note : Il nexiste pas de type Boolen en C

Universit de Savoie

25

Les types de variables


z

Cas dune compilation pour processeur 32 bits

z z

Voir le cas dun compilateur C pour PIC16F ou PIC18F (microchip) Voir le cas dun compilateur C pour DSP TMS320 (Texas Instruments) (page suivante)

Universit de Savoie

26

Les types de variables

Universit de Savoie

27

Les types de variables


z

Donner la reprsentation binaire des nombres suivants :


z z z z

char a=64; unsigned char b=64; char c=128; unsigned char d=128;

Quel est laffichage des fonctions suivantes?


z z z z

printf(%d printf(%d printf(%u printf(%u

, , , ,

a); c); a); c+a);

Note : Une dclaration est signed par dfaut. Note : %d -> entier signed / %u -> entier unsigned
Universit de Savoie 28

Les types de variables


z

Conversion explicite :
La conversion de type consiste transformer un type de valeur en un autre, en respectant la syntaxe suivante (<type>) <expression>

Conversion implicite :
Lorsque les deux oprandes sont de type diffrent, le compilateur prvoit une conversion implicite suivant l'ordre : { char -> int -> long -> float -> double } et { signed -> unsigned }

Universit de Savoie

29

Les types de variables


Dcrivez le conversion du type, ainsi que les affectations du code suivant :
int main(void) { int n, m, l; double d; d = 5; n = (int) 3.4; n = 1; m = 5; d = 2; l = (int) (m / d); d = n / m; d = n / ((double) m); d = 'A' * 6.0 m + 0xA2CL; return 0; }

Universit de Savoie

30

Porte des variables


z

static : permet une variable locale dtre persistante et donc de conserver sa valeur pendant les appels successifs de la fonction.
#include <stdio.h> void f(void) { static int i = 0; /* i ne sera initialis quune fois*/ int j = 0; /* j sera initialis chaque fois */; i++; j++; printf("i vaut %d et j vaut %d.\n", i, j); } int main(void) { f(); f(); f(); return 0; }
Universit de Savoie 31

Porte des variables


z

static : Cas des variables globales. Une variable globale est dj persistante. Lobjectif de la nommer en static est simplement de la privatiser au fichier o elle est dclare. Cest--dire quelle ne pourra pas tre utilise depuis un autre fichier.

Universit de Savoie

32

Porte des variables


z

extern : permet de spcifier que la variable a t dclarer dans un autre fichier. Si on omet ce terme, une nouvelle variable est crer avec une nouvelle allocation mmoire.
/* File : ext.c */ #include <stdio.h> void next(void); void next1(void); int a1=1; /* definition of external (non static)*/ void main(void){ a1=2; printf("a1=%d\n",a1); next(); next1(); printf("a1=%d\n,a1); }

// a1=2

33

Porte des variables


/* File file1.c */ int b1=0; void next(void) { char a1; a1='a'; b1=77; }

/* File file2.c */ extern int a1; void next1(void) { float b1; b1=19.2; a1=13; }
34

Qualificateur de variables
z

Le C dfinit des qualificateurs pouvant influer sur une variable :


z

const : pour dfinir une variable dont la valeur ne devrait jamais changer ; volatile : dsigne une variable pouvant tre modifie notamment par une source externe indpendante du programme.

Une variable peut avoir plusieurs qualificateurs

Universit de Savoie

35

Qualificateur de variables
Qualificateur 'const'
La classe const indique au compilateur que la valeur de la variable ne doit pas changer. Il est donc impratif d'assigner une valeur la dclaration de la variable, sans quoi toute tentative de modification ultrieure entranera une erreur de la part du compilateur : tudier les codes suivants :

const int i = 0; i = 1;

Universit de Savoie

36

Qualificateur de variables
void fonction( const char * pointeur ) { pointeur[0] = 0; pointeur = "Nouvelle chane de caractres"; } char * const pointeur = "Salut tout le monde !"; pointeur = "Hello world !"; const char * const pointeur = "Salut tout le monde !"; pointeur = "Hello world !"; pointeur[0] = 0;

Universit de Savoie

37

Qualificateur de variables
Qualificateur 'volatile'
Ce mot-cl sert spcifier au compilateur que la variable peut tre modifie son insu. Cela annule toute optimisation que le compilateur pourrait faire, et l'oblige procder chaque lecture ou criture dans une telle variable tel que le programmeur l'a crit dans le code.
z

On peut combiner const et volatile dans certaines situations. Par exemple :

extern const volatile int horloge_temps_reel;


>>dclare une variable entire, qu'on ne peut modifier partir du programme, mais dont la valeur peut changer quand mme. Elle pourrait dsigner une valeur incrmente rgulirement par une horloge interne.
Universit de Savoie 38

valuation des expressions boolennes (1)


z

Le C ne possde pas de type boolen ddi. Dans ce langage, n'importe quelle valeur diffrente de zro est considre vraie, zro tant considr comme faux. Ce qui veut dire que n'importe quelle expression peut tre utilise l'intrieur des tests (entier, rels, pointeurs, tableaux, etc.). Cela peut conduire des expressions pas toujours trs claires, comme :
int a; a = une_fonction(); if (a) { /* ... */ }

On prfrera :
int a; a = une_fonction(); if (a != 0) { /* ... */ }

Attention :
int a = 0; b = 2; if (a = b) { /* Le code qui suit sera toujours excut ... */ }
Universit de Savoie 39

valuation des expressions boolennes (2)


Les oprateurs logiques de comparaisons (&& et ||, similaires smantiquement leur quivalent binaire & et |) ont une excution totalement diffrente. z Dans le cas du ET logique (&&), si l'oprande gauche s'value faux (valeur zro), on sait dj que le rsultat du ET sera faux et donc ce n'est pas la peine d'valuer l'oprande droite. De la mme manire si l'oprande gauche d'un OU logique (||) est valu vrai, le rsultat sera aussi vrai (valeur !=0) et donc l'valuation de l'oprande droite est inutile.
z

if (z != 0 && a / z < 10) { printf("Tout va bien\n"); }

Universit de Savoie

40

Les manipulations de bits (1)


z

Les manipulations de bits sont beaucoup utilises dans lembarqu. Pour contrler un priphrique matriel, on retrouve des registres de 8, 16 ou 32 bits quil faut modifier. Mettre 1 le bit 4 de a :
unsigned a = 0x000F; /* 0000 0000 0000 1111 */

Mettre zro le bit 3 de a :


unsigned a = 0x000F; /* 0000 0000 0000 1111 */

Universit de Savoie

41

Les manipulations de bits (1)


z

Les manipulations de bits sont beaucoup utilises dans lembarqu. Pour contrler un priphrique matriel, on retrouve des registres de 8, 16 ou 32 bits quil faut modifier. Mettre 1 le bit 4 de a :
unsigned a = 0x000F; /* 0000 0000 0000 1111 */ unsigned b = 0x0010; /* 0000 0000 0001 0000 */ unsigned c = a | b; /* 0000 0000 0001 1111 soit 0x001F */

Mettre zro le bit 3 de a :


unsigned a = 0x000F; /* 0000 0000 0000 1111 */ unsigned b = 0xFFF7; /* 1111 1111 1111 0111 */ unsigned c = a & b; /* 0000 0000 0000 0111 soit 0x0007 */
Universit de Savoie 42

Les manipulations de bits (2)


z

Tester si le bit 2 de a est 1 :


unsigned a = 0x000F; /* 0000 0000 0000 1111 */

Tester si le bit 3 de a est 1 et si le bit 15 est 0 :


unsigned a = 0x000F; /* 0000 0000 0000 1111 */

43

Les manipulations de bits (2)


z

Tester si le bit 2 de a est 1 :


unsigned a = 0x000F; /* 0000 0000 0000 1111 */ if (a & (1u << 2)) { printf("bit 2 = 1"); } else { printf("bit 2 = 0"); }

Tester si le bit 3 de a est 1 et si le bit 15 est 0 :


unsigned a = 0x000F; /* 0000 0000 0000 1111 */ if ( (a & (1u << 3)) && (a&(1u<<15))==0 ) { printf("bit 2 = 1 et bit 15=0"); } else { printf("bit 2 = 1 et bit 15=0 nest pas vrifi"); }
44

Le main()
z

Le main() est le point dentre dune application. Dans un systme embarque sans systme dexploitation, le point dentre du programme sera prcis dans la phase ddition de liens par linitialisation du vecteur dinterruption nomm RESET.

Universit de Savoie

45

A quoi sert un pointeur ?

Universit de Savoie

46

Les tableaux (1)


z

Un tableau est un regroupement conscutif de donne de mme type et de taille fixe.


// Tableau 2 dimensions void main(void){ int tableau[4][3]; jnt i,j; for(i=0i<4;i++){ for(j=0;j<3;j++){ tableau[i][j]=0; } } }

// Tableau 1 dimension void main(void){ int tableau[4]; int i; for(i=0i<4;i++){ tableau[i]=0; } }

Universit de Savoie

47

Les tableaux (2)

tableau[0] tableau[1] tableau[2] tableau[3]

tableau[0][0] tableau[0][1] tableau[0][2] tableau[1][0] tableau[1][1] tableau[1][2] tableau[2][0] tableau[2][1] tableau[2][2] tableau[3][0] tableau[3][1] tableau[3][2]
Universit de Savoie 48

Les tableaux (3)


z Passage

de paramtre des tableaux des fonctions : z Un tableau nest jamais pass en paramtre, cest son adresse qui est fournie.

Universit de Savoie

49

Organisation logicielle
0xFFFFFFFF stack SP (Stack Pointer)

address space

heap (dynamically allocated) data segment Data : (static and global) code segment (=program) PC (Program Counter)

0x00000000

Universit de Savoie

50

Organisation logicielle
z z

Code segment : Emplacement ou se trouve le code compil. Data segment :


z

Data : contient toutes les variables static et globales (initialises ou non) Heap : Le tas est gr dynamiquement. Cest une zone de donne qui grossi la rservation de zone mmoire (malloc) et qui se rduit lors de la libration (free).

Stack : Cest une zone de stockage de type LIFO. Elle contient les adresses de retour des fonctions et les variables locales. Cette zone mmoire est beaucoup plus rapide que lutilisation du Heap.
Universit de Savoie 51

Optimisation du code
z

Dans le contexte de lembarqu, il est important de connatre les options de compilation doptimisation. Il y a en effet un compromis trouver entre la taille de lexcutable produit et le temps dexcution.

Universit de Savoie

52

Optimisation du code
z

Option -O0 (niveau 0)


z z z z

Allocates variables to registers Performs loop rotation Eliminates unused code Simplifies expressions and statements

Option -O1 (niveau 1)


z z z

Performs all -O0 optimizations, and: Removes unused assignments Eliminates local common expressions

Option -O2 (niveau 2) (default optimization level)


z z

Performs all -O1 optimizations, and: Performs loop optimizations


Universit de Savoie 53