Cómo usar _crc16_update (uint16_t crc, uint8_t a) para obtener el crc de mi programa en la memoria del programa

No hay una forma portátil de hacer eso.

Si puede encontrar la dirección de inicio y la longitud de su código en la memoria, entonces ciertamente podría calcular el CRC para ello.

Puedo ver el valor de eso si le preocupa que el mecanismo de carga que coloca el programa en la memoria pueda estar roto.

Para resolver esto, necesitará saber algo sobre la forma en que el vinculador convirtió su código objeto en un solo ejecutable. Si tiene suerte, creará algún tipo de símbolo externo para el inicio y el final de la sección de código.

En Linux, por ejemplo, el enlazador crea símbolos globales como:

__bss_start, __data_start, _start, _edata y _end.

Si revisa la documentación para el formato binario ELF, podrá averiguar la dirección de inicio y finalización del código en tiempo de ejecución … y a partir de eso, podrá pasar una dirección de inicio de búfer adecuada y longitud para la función CRC de su elección para calcular el CRC de su código en la memoria.

Por supuesto, el programa tendrá que calcular esto usando el código que está dentro del programa, y ​​eso es un problema.

Si escribe algo que computa el CRC para el código, ¿cómo volverá a poner ese número en el programa para que pueda verificarlo en las siguientes ejecuciones sin CAMBIAR el código … lo que alteraría el valor del CRC?

Esto es algo que solo puede solucionarse si no verifica el área de datos preinicializada … ¡pero esto es algo complicado!

_crc16_update es una función avr. Eso significa que puede obtener el archivo .bin, obtener su tamaño y suma de comprobación. Luego escríbelo a EEPROM. Luego lea en ciclo desde 0 hasta el tamaño del firmware usando pgm_read_byte y alimente bytes a _crc16_update. Luego verifique con EEPROM.

Es decir, si no tiene un gestor de arranque. Si es así, debe obtener la dirección donde coloca el final del código, reemplazar 0 por ella y agregar esta dirección al tamaño del firmware.

La única vez que tuve un fallo de ROM fue en una unidad de cinta, en la que pusimos una rutina para calcular el CRC32 de la ROM y compararlo con el CRC32 almacenado (en la ROM). ¿La falla? La rutina de comparación cayó o agregó un poco y falló. Si no hubiéramos comprobado el CRC32 de la ROM, ese nunca habría fallado.

Desde entonces, me he negado a escribir un código de autocomprobación como ese. Es demasiado fácil para la falla estar en el código de autocomprobación, mientras que el resto de la ROM es perfecta.

¿Leíste el manual?

Respuesta clara: [CRC] Problemas con el uso de _crc16_update

¿Por qué querrías hacer eso?

No se garantiza que su código y sus datos (y otros segmentos) sean continuos, por lo que necesitaría obtener punteros a la base de cada segmento, más la longitud de cada uno, para calcular el crc completo y el acto de calcular ¡Cambiaría los datos!

¿Cuál es el propósito?