Ejecutar código una vez en la vida de un programa C incorporado

8

¿Cómo puedo hacer que un fragmento de código se ejecute solo una vez en la vida de un programa? Se puede apagar y encender muchas veces. La única opción para volver a ejecutar el fragmento de código debe ser flashear nuevamente el tablero.

El código es una sección de calibración que no quiero volver a ejecutar. Si utilizo EEPROM o Flash, estableceremos un indicador en verdadero o falso. Entonces, cuando leemos por primera vez esa ubicación de memoria, ¿cuál sería el valor aleatorio en esa área de memoria?

¿Cuál es el mejor método para implementar esto en C incrustada?

    
pregunta ganeshredcobra

4 respuestas

18

Es posible que su microcontrolador tenga algunos EEPROM, memoria OTP, bits de fusible de usuario, donde puede establecer una bandera.

No hay un "mejor método en C incrustado", escribir memoria no volátil es diferente en cada microcontrolador.

edit:

FLASH

Los contenidos de la memoria flash se borran al programar el dispositivo. Después de la programación, todos los bytes que no fueron escritos contienen 0xFF. Consulte la hoja de datos para encontrar un área que pueda programarse de manera segura desde el firmware en ejecución.

EEPROM

Aunque no está garantizado en las hojas de datos, todas las EEPROM que he visto hasta ahora contenían 0xFF: s cuando se envían desde la fábrica (excepto las preprogramadas con una dirección MAC única, pero eso está explícitamente documentado). Algunos dispositivos / software de programación también pueden borrar o programar contenidos EEPROM. Algunos pueden estar protegidos contra escritura, de forma permanente o reversible.

OTP

La memoria programable de una sola vez siempre contiene valores iniciales bien definidos, documentados en la hoja de datos.

Siempre es una buena idea incluir una buena suma de comprobación como CRC32 con los datos escritos, para proteger contra la corrupción de datos causada por piezas defectuosas, errores de transmisión, rayos cósmicos, lo que sea.

    
respondido por el berendi
13

Has dicho:

  

La única opción para ejecutar ese código debe destellar el tablero nuevamente.

Otros han dicho que usan EEPROM para almacenar una bandera para indicar cuándo se ha ejecutado la función run_once (). Sin embargo, esto tiene un retroceso que es que si vuelve a flashear el microcontrolador, el indicador ran_it_once en EEPROM ya se ha establecido y la función run_once () no se ejecutará. Si su microcontrolador tiene EEPROM incrustada, entonces es posible borrar el indicador ran_it_once cuando vuelva a encender el microcontrolador, si el programador lo admite.

Una mejor manera es tener números de versión tanto en EEPROM como en el código. Cuando el código se ejecuta desde el encendido, debe leer el número de versión de EEPROM y compararlo con el número de versión almacenado en el código. Si no coinciden, se llama a la función run_once (), y el acto final del código run_once () es escribir el número de versión del firmware en EEPROM. Cada vez que modifique el código fuente del firmware, deberá incrementar el número de versión incorporado en él.

    
respondido por el Steve G
8

Elija un microcontrolador que pueda escribir / borrar su propia memoria de programa. Después de ejecutar el código en cuestión, haga que la última parte de dicho código reemplace la primera instrucción con un salto que lo omita. Opcionalmente, también puede borrar el resto (tal vez reemplazar con nop), de modo que no haya ninguna posibilidad de que se vuelva a ejecutar.

Este mensaje se autodestruirá en 5..4 ...

    
respondido por el apalopohapa
5

Mientras está utilizando este código para la calibración, mi sugerencia sería crear un proceso explosivo que ejecute el código de calibración como una primera etapa y ni siquiera lo tenga en la versión de producción terminada de la placa. Esto es similar a la respuesta de apalopohapa, excepto que es diferente en el sentido de que tendría dos cargas de programa separadas: tiene un proceso explosivo que destella la primera carga del programa que ejecuta todas las calibraciones y escupe los datos de eso. Luego tome esos datos e incorpórelos a los datos de la segunda carga del programa.

Una de las ventajas de este enfoque es que minimiza absolutamente la cantidad de espacio de almacenamiento que necesita: no necesita almacenar su código de una sola vez, solo los datos que genera. Al tener un proceso explosivo que carga dos programas separados, también se aísla un poco de los errores en el código de inicialización que, de lo contrario, podrían persistir. También tiene cierta flexibilidad adicional si desea volver a ejecutar su código de calibración: en lugar de tener que escribir un código adicional para borrar cualquier bit que indique que su código ha sido ejecutado (lo que podría ser borrado accidentalmente) simplemente vuelva a ejecutar su proceso de explosión.

    
respondido por el Michael

Lea otras preguntas en las etiquetas