Se declararmos uma variável como volatile
sempre que o valor fresco for atualizado
Se declararmos uma variável como const
então o valor dessa variável não será alterado
Então, const volatile int temp;
qual é a utilidade de declarar a variável temp
como acima?
O que acontece se declararmos como const int temp
?
const volatile int temp;
no escopo do bloco (ou seja, dentro{ }
), não tem uso lá.Respostas:
Um objeto marcado como
const volatile
não terá permissão para ser alterado pelo código (um erro será gerado devido aoconst
qualificador) - pelo menos por meio desse nome / ponteiro específico.A
volatile
parte do qualificador significa que o compilador não pode otimizar ou reordenar o acesso ao objeto.Em um sistema embarcado, isso é normalmente usado para acessar registros de hardware que podem ser lidos e atualizados pelo hardware, mas não fazem sentido para gravar (ou pode ser um erro para gravar).
Um exemplo pode ser o registro de status para uma porta serial. Vários bits irão indicar se um caractere está esperando para ser lido ou se o registrador de transmissão está pronto para aceitar um novo caractere (isto é, - está vazio). Cada leitura desse registro de status pode resultar em um valor diferente dependendo do que mais ocorreu no hardware da porta serial.
Não faz sentido escrever no registro de status (dependendo da especificação de hardware em particular), mas você precisa se certificar de que cada leitura do registro resulta em uma leitura real do hardware - usando um valor em cache de uma leitura anterior. t informá-lo sobre as mudanças no estado do hardware.
Um exemplo rápido:
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; }
Se esses ponteiros não foram marcados como sendo
volatile
, alguns problemas podem ocorrer:*recv_reg
é alterado pelo loop, não há razão para que não possa ser lido antes de entrar no loop.Os
volatile
qualificadores garantem que essas otimizações não sejam realizadas pelo compilador.fonte
volatile
dirá ao compilador para não otimizar o código relacionado à variável, geralmente quando sabemos que ela pode ser alterada "de fora", por exemplo, por outro thread.const
dirá ao compilador que é proibido para o programa modificar o valor da variável.const volatile
é uma coisa muito especial que você provavelmente verá usado exatamente 0 vezes em sua vida (tm). Como era de se esperar, isso significa que o programa não pode modificar o valor da variável, mas o valor pode ser modificado de fora, portanto, nenhuma otimização será realizada na variável.fonte
volatile
variáveis geralmente são o que acontece quando você começa a mexer com o hardware, não com outros threads. Eu vi oconst volatile
uso em coisas como registradores de status mapeados em memória ou semelhantes.Não é porque a variável é const que ela pode não ter mudado entre dois pontos de sequência.
Constância é uma promessa que você faz de não alterar o valor, não de que o valor não será alterado.
fonte
const
dados não são "constantes".Precisei usar isso em um aplicativo incorporado onde algumas variáveis de configuração estão localizadas em uma área da memória flash que pode ser atualizada por um carregador de boot. Essas variáveis de configuração são 'constantes' durante o tempo de execução, mas sem o qualificador volátil, o compilador otimizaria algo assim ...
cantx.id = 0x10<<24 | CANID<<12 | 0;
... pré-computando o valor da constante e usando uma instrução de montagem imediata ou carregando a constante de um local próximo, de modo que quaisquer atualizações do valor CANID original na área de configuração do flash sejam ignoradas. CANID tem que ser constantemente volátil.
fonte
Em C,
const
evolatile
são qualificadores de tipo e esses dois são independentes.Basicamente,
const
significa que o valor não pode ser modificado pelo programa.E
volatile
significa que o valor está sujeito a alterações repentinas (possivelmente de fora do programa).Na verdade, o Padrão C dá um exemplo de uma declaração válida que é
const
evolatile
. O exemplo é:extern const volatile int real_time_clock;
onde
real_time_clock
pode ser modificável pelo hardware, mas não pode ser atribuído, incrementado ou decrementado.Portanto, já devemos tratar
const
evolatile
separadamente. Estes qualificadores tipo pode ser aplicado astruct
,union
,enum
etypedef
como bem.fonte
const
significa que a variável não pode ser modificada pelo código c, não que ela não pode ser alterada. Isso significa que nenhuma instrução pode escrever na variável, mas seu valor ainda pode mudar.volatile
significa que a variável pode mudar a qualquer momento e, portanto, nenhum valor armazenado em cache pode ser usado; cada acesso à variável deve ser executado em seu endereço de memória.Uma vez que a pergunta está marcada como "incorporada" e supondo que
temp
seja uma variável declarada pelo usuário, não um registro relacionado ao hardware (já que geralmente são tratados em um arquivo .h separado), considere:Um processador embutido que tem memória de dados de leitura e gravação volátil (RAM) e memória de dados somente leitura não volátil, por exemplo, memória FLASH na arquitetura de von-Neumann, onde dados e espaço de programa compartilham um barramento de dados e endereço comum.
Se você declarar
const temp
ter um valor (pelo menos se diferente de 0), o compilador irá atribuir a variável a um endereço no espaço FLASH, pois mesmo que tenha sido atribuído a um endereço RAM, ainda precisa de memória FLASH para armazenar o valor inicial da variável, tornando o endereço de RAM uma perda de espaço, uma vez que todas as operações são somente leitura.Em consequência:
int temp;
é uma variável armazenada na RAM, inicializada em 0 na inicialização (cstart), os valores em cache podem ser usados.const int temp;
é uma variável armazenada em (somente leitura) FLASH, inicializada em 0 no momento do compilador, os valores em cache podem ser usados.volatile int temp;
é uma variável armazenada na RAM, inicializada em 0 na inicialização (cstart), os valores em cache NÃO serão usados.const volatile int temp;
é uma variável armazenada em (somente leitura) FLASH, inicializada em 0 no momento do compilador, os valores em cache NÃO serão usadosAí vem a parte útil:
Atualmente, a maioria dos processadores Embedded tem a capacidade de fazer alterações em sua memória não volátil somente leitura por meio de um módulo de função especial, que
const int temp
pode ser alterado em tempo de execução, embora não diretamente. Dito de outra forma, uma função pode modificar o valor no endereço ondetemp
está armazenado.Um exemplo prático seria usar
temp
o número de série do dispositivo. A primeira vez que o processador embutido rodar,temp
será igual a 0 (ou o valor declarado) e uma função pode usar este fato para rodar um teste durante a produção e se for bem sucedido, pedir para ser atribuído um número de série e modificar o valor detemp
por meio de uma função especial. Alguns processadores têm uma faixa de endereço especial com memória OTP (programável de uma só vez) apenas para isso.Mas aí vem a diferença:
Se
const int temp
for um ID modificável em vez de um número de série programável uma vez e NÃO for declaradovolatile
, um valor em cache pode ser usado até a próxima inicialização, o que significa que o novo ID pode não ser válido até a próxima reinicialização ou, pior ainda, algumas funções pode usar o novo valor enquanto outros podem usar um valor armazenado em cache mais antigo até a reinicialização. Se forconst int temp
declaradovoltaile
, a mudança de ID terá efeito imediato.fonte
Você pode usar
const
evolatile
juntos. Por exemplo, se0x30
for considerado o valor de uma porta que é alterada apenas por condições externas, a seguinte declaração evitaria qualquer possibilidade de efeitos colaterais acidentais:const volatile char *port = (const volatile char *)0x30;
fonte
Este artigo discute os cenários em que você deseja combinar qualificadores const e volatile.
http://embeddedgurus.com/barr-code/2012/01/combining-cs-volatile-and-const-keywords/
fonte
Em termos simples, o valor na variável 'const volatile' não pode ser modificado programaticamente, mas pode ser modificado pelo hardware. Volátil aqui é para evitar qualquer otimização do compilador.
fonte
Usamos a palavra-chave 'const' para uma variável quando não queremos que o programa a altere. Ao passo que, quando declaramos uma variável 'const volatile', estamos dizendo ao programa para não alterá-la e ao compilador que essa variável pode ser alterada inesperadamente a partir de entradas vindas do mundo externo.
fonte