Projet

Général

Profil

Wiki » Historique » Version 157

Patrice Nadeau, 2024-01-20 21:20

1 1 Patrice Nadeau
# Règles de codage C
2
3 68 Patrice Nadeau
Le langage C, version [C99] (https://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf) utilisé avec le compilateur [GCC](https://gcc.gnu.org/).
4 1 Patrice Nadeau
> `gcc` n'est pas entièrement compatible avec le standard C99 (<https://gcc.gnu.org/c99status.html>).
5
6
---
7 73 Patrice Nadeau
8
{{>toc}}
9 148 Patrice Nadeau
10
---
11 1 Patrice Nadeau
12 154 Patrice Nadeau
[[Style]]
13 20 Patrice Nadeau
14 155 Patrice Nadeau
[[Commentaires Doxygen]]
15 90 Patrice Nadeau
16 156 Patrice Nadeau
[[Fichiers]]
17 104 Patrice Nadeau
18 98 Patrice Nadeau
19 85 Patrice Nadeau
---
20 82 Patrice Nadeau
21 157 Patrice Nadeau
[[Objets et macros]]
22 1 Patrice Nadeau
23 11 Patrice Nadeau
24 1 Patrice Nadeau
## Préprocesseur
25
Directives du préprocesseur gcc.
26
27
### #include
28 43 Patrice Nadeau
29 1 Patrice Nadeau
Pour inclure d’autres fichier comme les fichiers entête.
30
31
### #ifdef / ifndef
32 76 Patrice Nadeau
33 1 Patrice Nadeau
Surtout utilisé pour des options de compilation sur différentes plateforme.
34
Utiliser une forme évitant les répétitions.
35
36
> N’est pas documenté dans Doxygen.
37
38
Exemple :
39
```c
40
const char BLUE =
41
  #if ENABLED(FEATURE_ONE)
42
    '1'
43
  #else
44
    '0'
45
  #endif
46
;
47
```
48
49
### Diagnostiques
50 78 Patrice Nadeau
51 1 Patrice Nadeau
Les macros `#warning` et `#error` sont utilisées pour afficher des avertissements ou des erreurs lors de la compilation.
52
53
> Ne sont pas documentées dans Doxygen.
54
55
Exemple :
56
``` c
57
#ifndef usart_AVR
58
    #error "__FILE_NAME__ is not supported on this AVR !"
59
#endif
60
61
#ifndef __test__
62
    #warning "test is not defined !"
63
#endif
64
```
65
66
### Définitions
67
68
Un `#define` est utilisé pour remplacer une valeur au moment de la compilation
69
> Pour la définition d'une valeur « integer », un `enum` DOIT être utilisé.
70
71
Exemple :
72
``` c
73 76 Patrice Nadeau
/**
74 1 Patrice Nadeau
* @name Nom des registres
75
*/
76
/** @{ */ 
77
/** @brief USART1 */
78
#define USART1 REG1
79
/** @brief USART2 */
80
#define USART2 REG2
81
/** @} */
82
83
USART1 = 0x0F;
84
```
85
86
## Atmel AVR
87
88
Particularités pour les microcontrôleurs 8 bits AVR d’Atmel.
89
90
[Atmel AVR4027: Tips and Tricks to Optimize Your C Code for 8-bit AVR Microcontrollers](https://ww1.microchip.com/downloads/en/AppNotes/doc8453.pdf)
91
92
### Fichier d’en-têtes
93 25 Patrice Nadeau
94
Vérification du modèle de microcontrôleur
95
    > Via l'option `-m` de [gcc](https://github.com/embecosm/avr-gcc/blob/avr-gcc-mainline/gcc/config/avr/avr-mcus.def)
96 1 Patrice Nadeau
97 25 Patrice Nadeau
```c
98
#ifndef defined (__AVR_ATmega48__) || (__AVR_ATmega48P__) || \
99
	(__AVR_ATmega88P__) || defined (__AVR_ATmega88__) || \
100
	(__AVR_ATmega168__) || defined (__AVR_ATmega168P__) || \
101
	(__AVR_ATmega328__) || defined (__AVR_ATmega328P__)
102
#warning "Cette librairie n'as pas été testée sur cette famille de microcontrôleur."
103 1 Patrice Nadeau
#endif
104
```
105
106 45 Patrice Nadeau
### Macros
107
108
Définis dans le fichier `config.h`
109
110 1 Patrice Nadeau
Liste : 
111
* `F_CPU` : La fréquence utilisée par l'horloge (interne ou externe) du microcontrôleur
112
113
    > Les « fuses » doivent correspondent à la bonne source de l'horloge.
114
115
### Types
116
117
De nouveau type d'entier sont fournis avec la librairie `<stdint.h>`.
118
119
L'utilisation de ces types DOIT être utilisé afin d'exprimer le nombre de bit d'un objet.
120
121 44 Patrice Nadeau
### Progmem
122
123
<https://www.avrfreaks.net/s/topic/a5C3l000000U5SFEA0/t034767>
124 1 Patrice Nadeau
125
Pour mettre des variables en lecture seule dans la section FLASH au lieu de SRAM avec `<avr/pgmspace.h>`.
126
> L’accès à ces variables est faite via les macros de la librairie.
127
128
Le nom de la variable DOIT être suivie de **_P**
129
130
Exemple :
131
```c
132
#include <avr/pgmspace.h>
133
...
134
/** @brief Variable en FLASH */
135
const int Variable1_P PROGMEM = 42;
136
```
137
138
### Fonction main
139
Un microcontrôleur AVR ne termine jamais la fonction `main`.
140
141
* Déclarer la fonction main avec l’attribut `noreturn`
142
* La boucle sans fin la plus optimisé est le `for (;;)`
143
144
Justification : [AVR035](https://ww1.microchip.com/downloads/en/AppNotes/doc1497.pdf)
145
146
Exemple :
147 26 Patrice Nadeau
```c
148
#include <avr/io.h>
149 1 Patrice Nadeau
150
/** 
151
 * @brief Never ending loop
152 83 Patrice Nadeau
*/
153 1 Patrice Nadeau
void main(void) __attribute__((noreturn));
154
155 9 Patrice Nadeau
/* main function definition */
156 1 Patrice Nadeau
void main(void) {
157
    ...
158
    /* never return */
159
    for (;;) {
160
    };
161
};
162
```
163 70 Patrice Nadeau
164 113 Patrice Nadeau
### Opérations « atomiques »
165 1 Patrice Nadeau
Opérations ne devant pas être interrompus (Ex. : charger un registre de 16 bits avec un registre de 8 bits).
166
167
La librairie `avr-libc` (util/atomic.h) fournit des macros permettant la gestion entre autre des interruptions.
168
169
Les instructions critiques sont insérées dans un `ATOMIC_BLOCK`.
170
171
Exemple :
172 72 Patrice Nadeau
```c
173 1 Patrice Nadeau
#include <util/atomic.h>
174
...
175
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
176
    ...
177
}
178
...
179
```