Pergunta

Em um ambiente incorporado (usando MSP430), tenho visto alguns dados corrompidos causados ​​por gravações parciais em memória não volátil.Isso parece ser causado pela perda de energia durante uma gravação (para FRAM ou segmentos de informação).

Estou validando os dados armazenados nesses locais com um CRC.

Minha pergunta é: qual é a maneira correta de evitar essa corrupção de “gravação parcial”?Atualmente, modifiquei meu código para gravar em dois locais FRAM separados.Portanto, se uma gravação for interrompida causando um CRC inválido, o outro local deverá permanecer válido.Isto é uma prática comum?Preciso implementar esse comportamento de gravação dupla para qualquer memória não volátil?

Foi útil?

Solução

Uma solução simples é manter dois versões dos dados (em páginas separadas para memória flash), a versão atual e a versão anterior.Cada versão possui um cabeçalho composto por um número de sequência e uma palavra que valida o número de sequência - simplesmente o complemento de 1 do número de sequência, por exemplo:

---------
|  seq  |
---------
| ~seq  |
---------
|       |
| data  |
|       |
---------

O ponto crítico é que quando os dados são gravados, o seq e ~seq palavras são escritas durar.

Na inicialização você ler os dados que possuem sequência válida mais alta número (talvez levando em conta o wrap-around - especialmente para palavras de sequência curta).Ao gravar os dados, você sobrescreve e valida os mais antigo bloquear.

A solução que você já está usando é válida desde que o CRC seja escrito por último, mas falta simplicidade e impõe uma sobrecarga de cálculo do CRC que pode não ser necessária ou desejável.

Na FRAM você não se preocupa com a resistência, mas isso é um problema para memória Flash e EEPROM.Neste caso eu utilizo um método de cache write-back, onde os dados são mantidos na RAM, e quando modificado um timer é iniciado ou reiniciado se já estiver em execução - quando o timer expira, os dados são gravados - isso evita burst-writes de sobrecarregar a memória e é útil até mesmo em FRAM, pois minimiza a sobrecarga de software nas gravações de dados.

Outras dicas

Nossa equipe de engenharia leva uma abordagem de duas frentes para esse problema: resolva-o em hardware e software!

O primeiro é um arranjo de diodo e capacitor para fornecer alguns milissegundos de energia durante um marrom. Se notarmos que perdemos poder externo, impedimos que o código digitasse qualquer gravações não violadas.

Segundo, nossos dados são particularmente críticos para operação, atualiza frequentemente e não queremos desgastar nosso armazenamento flash não violado (suporta apenas tantas gravações.) Então nós realmente armazenamos os dados 16 vezes no flash e proteja cada registro com um código CRC. Na inicialização, encontramos a mais nova gravação válida e, em seguida, inicia nossos ciclos de apagamento / gravação.

Nunca vimos corrupção de dados desde que implementando nosso sistema francamente paranóico.

update:

Eu devo notar que nosso flash é externo à nossa CPU, portanto, o CRC ajuda a validar os dados se houver uma falha de comunicação entre a CPU e o Chip Flash. Além disso, se tivermos várias falhas consecutivas, as múltiplas gravações protegerem contra a perda de dados.

Usamos algo semelhante à resposta de Clifford, mas escrito em uma operação de gravação.Você precisa de duas cópias dos dados e alternar entre elas.Use um número de sequência incremental para que efetivamente um local tenha números de sequência pares e outro ímpar.

Escreva os dados assim (em um comando de gravação, se puder):

---------
|  seq  |
---------
|       |
| data  |
|       |
---------
| seq   |
---------

Ao lê-lo, certifique-se de que ambos os números de sequência sejam iguais - se não forem, os dados serão inválidos.Na inicialização, leia os dois locais e descubra qual deles é mais recente (levando em consideração o número de sequência rolante).

Sempre armazene dados em algum tipo de protocolo, como start_byte, bytes totais para gravar, dados, byte final. Antes de escrever para a memória externa / interna, sempre verifique os registros do moniter / adc. Se de qualquer maneira você os dados corromperam, o byte final também corromperá.Portanto, essa entrada não vai vailand após a validação do protocolo inteiro. A soma de verificação não é uma boa ideia, você pode escolher o CRC16 em vez disso, se quiser incluir o CRC em seu protocolo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top