SYSTÈME A BASE DES MICROCONTROLLEURS
CHAPITRE 4: LES BONNES PRATIQUES DE LA
PROGRAMMATION EMBARQUÉS
MOHAMED MASMOUDI3ÈME ANNÉE INFO - SLE
ENSI-ECOLE NATINALE DES SCIENCES DE L’[email protected]
Mohamed MASMOUDI 2014-2015ENSI
1Mohamed MASMOUDI 2014-2015 3ème année INFO - SLE
Types utilisés
Mohamed MASMOUDI 2014-2015 3ème année INFO - SLE
2
Utilisation des types indépendant des compilateurs Les types int et double dépondent de l’environnement de
compilation (nombre de bits à utiliser)
Utilisation des types de taille fixe int16_t, uint8_t , ….typedef signed char int8_t
typedef unsigned char uint8_t
typedef signed int int16_t
typedef unsigned int uint16_t
typedef signed long int int32_t
typedef unsigned long int uint32_t
typedef signed long long int int64_t
typedef unsigned long long int uint64_t
Variables
Mohamed MASMOUDI 2014-2015 3ème année INFO - SLE
3
Globale et locale Les variables locales sont déclarées dans la fonction les
utilisant. Les variables globales en début de programme. Le linker attribue une adresse fixe et définitive au variables
globale pendant toute la durée du programme. L'utilisation de variables locales améliore considérablement
la lisibilité et la sécurité des données dans un programme en C.
Les variables locales sont par défaut "automatiques" , crées à l'entrée de la fonction qui les déclare et détruites à la sortie. Pour cela elles sont rangées dans la « pile», zone mémoire particulière, destinée primairement au stockage des données de retour des sous programmes.
Variables
Mohamed MASMOUDI 2014-2015 3ème année INFO - SLE
4
Statique Une variable globale est déjà persistante. L’objectif de la nommer en « static » est simplement de la «
privatiser » au fichier où elle est déclarée. C’est-à-dire qu’elle ne pourra pas être utilisée depuis un
autre fichier.
Externe
/* 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;}
Variables
Mohamed MASMOUDI 2014-2015 3ème année INFO - SLE
5
Qualificateur Le C définit des qualificateurs pouvant influer sur une
variable : const : pour définir une variable dont la valeur ne doit
jamais changer ;
volatile : désigne une variable dont les accès ne doivent pas être optimiser par le compilateur. Cette variable sera relue depuis son emplacement d’origine à chaque accès. En effet, cela est important lorsque d’autre sources (périphérique matériel, processus, etc…) accède à la variable en même temps ue notre programme.
Une variable peut avoir plusieurs qualificateurs
Opérateur
Mohamed MASMOUDI 2014-2015 3ème année INFO - SLE
6
Les opérateurs logiques de comparaisons (&& et ||, similaires sémantiquement à leur équivalent binaire & et |) ont une exécution totalement différente.
Dans le cas du ET logique (&&), si l'opérande gauche s'évalue à faux (valeur zéro), on sait déjà que le résultat du ET sera faux et donc ce n'est pas la peine d'évaluer l'opérande droite.
De la même manière si l'opérande gauche d'un OU logique (||) est évalué à vrai, le résultat sera aussi vrai (valeur !=0) et donc l'évaluation de l'opérande droite est inutile.
Opérateur (manipulation des bits)
Mohamed MASMOUDI 2014-2015 3ème année INFO - SLE
7
Les manipulations de bits sont beaucoup utilisées dans l’embarqué. Pour contrôler un périphérique matériel, on retrouve des registres de 8, 16 ou 32 bits qu’il faut modifier. Exemple 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 à zéro 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 */
Opérateur (manipulation des bits)
Mohamed MASMOUDI 2014-2015 3ème année INFO - SLE
8
Tester si le bit 2 de a est à 1 :
unsigned a = 0x000F; /* 0000 0000 0000 1111 */
if (a & (1 << 2))
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 & (1 << 3)!=0 && a&(1<<15)==0 )
Points d’entrées
Mohamed MASMOUDI 2014-2015 3ème année INFO - SLE
9
Le main() est le point d’entrée d’une application.
Dans un système embarquée sans système d’exploitation, le point d’entrée du programme sera précisé dans la phase d’édition de liens par l’initialisation du vecteur d’interruption.
D’autre point d’entrées définissent les appels aux autres interruptions.
Points d’entrées
Mohamed MASMOUDI 2014-2015 3ème année INFO - SLE
10
Les appels aux interruption sont définie dans le vecteur table sous forme de pointeurs sur les callbacks des interruptions.
Lors des appels des interruptions il est préférable de minimiser les traitement a fin d’éviter la superposition de plusieurs interruptions. Ceci n’est pas valable dans les interruptions à contraintes temps réel stricte: Traitement d’urgence
Bouton d’alerte Alarme
Traitement fortement temporisé Synthèse vocale Affichage vidéo
Optimisation du code
Mohamed MASMOUDI 2014-2015 3ème année INFO - SLE
11
Optimisation du code Option -O0 (niveau 0)
Allocates variables to registers Performs loop rotation Eliminates unused code Simplifies expressions and statements
Option -O1 (niveau 1) Performs all -O0 optimizations, and: Removes unused assignments Eliminates local common expressions
Option -O2 (niveau 2) (default optimization level) Performs all -O1 optimizations, and: Performs loop optimizations
Utilisation des FSM
Mohamed MASMOUDI 2014-2015 3ème année INFO - SLE
12
FSM Finit State Machine
LED_ON LED_OFF
LED_OFF_ON
LED_ON_OFF
Utilisation des FSM
Mohamed MASMOUDI 2014-2015 3ème année INFO - SLE
13
typedef enum {NO_TRANS=0,LED_ON_OFF=0x01,LED_OFF_ON=0x02
}ledTransition;
• Utilisation des énumérations pour les états et les transitions.
• Utilisation des transition en mode mask (0x01, 0x02, 0x04, 0x08, …) pour pouvoir activer plusieurs transition en même temps.
• Utilisation d’une transtion No_Transition indiquant qu’il n’y a aucune transition active.
typedef enum {LED_ON,LED_OFF
}ledState;
Codage des FSM
Mohamed MASMOUDI 2014-2015 3ème année INFO - SLE
14
switch(led->state){case LED_ON:
if(led->trans&LED_ON_OFF){led->state=LED_OFF;led->trans=NO_TRANS;GPIO_ResetBits(led->port, led->pin);
}break;case LED_OFF:
if(led->trans&LED_OFF_ON){led->state=LED_ON;led->trans=NO_TRANS;
GPIO_SetBits(led->port, led->pin);}
break;}
Codage des FSM
Mohamed MASMOUDI 2014-2015 3ème année INFO - SLE
15
void LED_MsRoutine(ledStruct * led){if(led->timeout){
led->timeout--;if(led->timeout==led->duty)
led->trans=LED_OFF_ON;}else{
led->timeout=led->period;led->trans=LED_ON_OFF;
}}
Codage des FSM
Mohamed MASMOUDI 2014-2015 3ème année INFO - SLE
16
Interruption 1 msvoid Decrement_Delay(){LED_MsRoutine(&leds[0]);
}
Routine pricipaleint main(void){
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);SysTick_Config(SystemCoreClock / 1000);LED_Init(&leds[0],GPIOD,GPIO_Pin_12,500,350);while (1){
LED_Routine(&leds[0]);}
}
Utilisation des librairies
Mohamed MASMOUDI 2014-2015 3ème année INFO - SLE
17
Chaque librairies comporte deux fichiers:
Un fichier *.c pour les traitements.
Déclaration des Variables.
Déclaration des fonctions.
Un fichier *.h pour les déclaration.
Déclaration des types.
Déclaration des entêtes des fonctions
Utilisation des librairies
Mohamed MASMOUDI 2014-2015 3ème année INFO - SLE
18
Chaque librairie manipule un objet de type structure.
typedef struct{ledState state;ledTransition trans;GPIO_TypeDef* port;uint16_t pin;uint16_t period;uint16_t duty;__IO uint16_t timeout;
}ledStruct;
void LED_Init(ledStruct * led,GPIO_TypeDef* port,uint16_t pin,uint16_t period,uint16_t duty);
void LED_Routine(ledStruct * led);
void LED_MsRoutine(ledStruct * led);