Un objet marqué comme const volatile
ne pourra pas être modifiée par le code (une erreur est déclenchée en raison de l' const
qualifier) - au moins par le biais de ce nom/pointeur.
L' volatile
le cadre de la phase qualificative signifie que le compilateur ne peut pas optimiser ou de réorganiser l'accès à l'objet.
Dans un système embarqué, il est généralement utilisé pour accéder à des registres matériels qui peuvent être lues et sont mis à jour par le matériel, mais n'ont pas de sens pour écrire (ou peut-être une erreur à écrire).
Un exemple pourrait être le registre de statut pour un port série. Les différents bits indique si un caractère est en attente d'être lu ou si la transmettre registre est prêt à accepter un nouveau personnage (c'est à dire., - elle est vide). Chaque lecture de ce registre d'état pourrait entraîner une valeur différente en fonction de ce que l'autre a eu lieu dans le port de série du matériel.
Il ne fait aucun sens d'écrire dans le registre d'état (selon le matériel spec), mais vous devez vous assurer que chaque lecture des résultats du registre dans un véritable lecture du matériel à l'aide d'une valeur mise en cache à partir d'une précédente lecture ne vais pas vous parler des changements dans le matériel de l'état.
Un exemple rapide:
unsigned int const volatile *status_reg; // assume these are assigned to point to the
unsigned char const volatile *recv_reg; // correct hardware addresses
#define UART_CHAR_READY 0x00000001
int get_next_char()
{
while ((*status_reg & UART_CHAR_READY) == 0) {
// do nothing but spin
}
return *recv_reg;
}
Si ces pointeurs n'ont pas été marqués comme étant en volatile
, quelques problèmes peuvent se produire:
- la boucle while test peut lire l'état s'inscrire qu'une seule fois, car le compilateur pourrait supposer que ce qu'il a souligné ne change jamais (il n'y a rien dans la boucle while test ou de la boucle elle-même qui pourrait changer). Si vous avez entré la fonction quand il n'y a pas de personnage en attente dans UART matériel, vous pourriez vous retrouver dans une boucle infinie qui ne s'est jamais arrêté, même si un caractère a été reçu.
- la lecture de ce registre pourrait être déplacé par le compilateur à l'avant de la boucle while de nouveau, car il n'y a rien dans la fonction qui indique qu'
*recv_reg
est modifié par la boucle, il n'y a aucune raison qu'il ne peut pas être lu avant d'entrer dans la boucle.
L' volatile
qualificatifs s'assure que ces optimisations ne sont pas effectuées par le compilateur.