Mohamed MASMOUDI 2014-2015 3ème année INFO - SLE
1
SYSTÈME A BASE DES
MICROCONTROLLEURS
CHAPITRE 4: LES BONNES
PRATIQUES DE LA
PROGRAMMATION
EMBARQUÉS
MOHAMED MASMOUDI
3ÈME ANNÉE INFO - SLE
ENSI-ECOLE NATINALE DES SCIENCES DE L’INFORMATIQUES
Mohamed MASMOUDI
ENSI
2014-2015
Types utilisés
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
typedef unsigned char
typedef signed int
typedef unsigned int
typedef signed long int
typedef unsigned long int
typedef signed long long int
typedef unsigned long long int
int8_t
uint8_t
int16_t
uint16_t
int32_t
uint32_t
int64_t
uint64_t
Mohamed MASMOUDI 2014-2015 3ème année INFO - SLE
Variables
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.
Mohamed MASMOUDI 2014-2015 3ème année INFO - SLE
Variables
Publicité
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;
}
Mohamed MASMOUDI 2014-2015 3ème année INFO - SLE
Variables
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
Mohamed MASMOUDI 2014-2015 3ème année INFO - SLE
Opérateur
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.
Mohamed MASMOUDI 2014-2015 3ème année INFO - SLE
Opérateur (manipulation des bits)
7
Les manipulations de bits sont beaucoup utilisées dans
Publicité
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 /
Mohamed MASMOUDI 2014-2015 3ème année INFO - SLE
Opérateur (manipulation des bits)
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 )
Mohamed MASMOUDI 2014-2015 3ème année INFO - SLE
Points d’entrées
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.
Mohamed MASMOUDI 2014-2015 3ème année INFO - SLE
Points d’entrées
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
Mohamed MASMOUDI 2014-2015 3ème année INFO - SLE
Optimisation du code
11
Optimisation du code
Option -O0 (niveau 0)
Allocates variables to registers
Performs loop rotation
Eliminates unused code
Simplifies expressions and statements
Publicité
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
Mohamed MASMOUDI 2014-2015 3ème année INFO - SLE
Utilisation des FSM
12
FSM Finit State Machine
LED_ON_OFF
LED_ON
LED_OFF
LED_OFF_ON
Mohamed MASMOUDI 2014-2015 3ème année INFO - SLE
Utilisation des FSM
13
• 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 {
typedef enum {
LED_ON,
LED_OFF
}ledState;
NO_TRANS=0,
LED_ON_OFF=0x01,
LED_OFF_ON=0x02
}ledTransition;
Mohamed MASMOUDI 2014-2015 3ème année INFO - SLE
Codage des FSM
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);
if(led->trans&LED_OFF_ON){
led->state=LED_ON;
led->trans=NO_TRANS;
GPIO_SetBits(led->port, led->pin);
}
break;
case LED_OFF:
}
break;
}
Mohamed MASMOUDI 2014-2015 3ème année INFO - SLE
Codage des FSM
15
void LED_MsRoutine(ledStruct * led){
Publicité
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;
}
}
Mohamed MASMOUDI 2014-2015 3ème année INFO - SLE
Codage des FSM
16
Interruption 1 ms
void Decrement_Delay(){
LED_MsRoutine(&leds[0]);
}
Routine pricipale
int 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]);
}
}
Mohamed MASMOUDI 2014-2015 3ème année INFO - SLE
Utilisation des librairies
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
Mohamed MASMOUDI 2014-2015 3ème année INFO - SLE
Utilisation des librairies
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);
Mohamed MASMOUDI 2014-2015 3ème année INFO - SLE