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 usados
Aí 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 onde temp
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 de temp
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 declarado volatile
, 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 for const int temp
declarado voltaile
, a mudança de ID terá efeito imediato.
const volatile int temp;
no escopo do bloco (ou seja, dentro{ }
), não tem uso lá.