Actualmente tengo un número de serie codificado en mi firmware para un diseño con el que estoy trabajando. El firmware puede leer e informar el número de serie. Eso funciona bien para lo que necesito. El problema es que cada nuevo número de serie requiere que cambie mi código y recompile. Esto es engorroso cuando hay muchas unidades que construir, tiene la posibilidad de introducir errores y es una mala práctica general. Me dan los números de serie y el diseño del hardware está escrito en piedra, por lo que no puedo agregar ninguna característica en el hardware para serializar las unidades (EEPROM / Silicon ID Chip / Pull-Ups). Lo que me gustaría hacer es ubicar el número de serie en una dirección fija, compilar el código una vez y luego editar esa dirección en el archivo HEX compilado para cada nuevo número de serie. El número está referenciado en varios lugares, así que idealmente, quiero definirlo y ubicarlo una vez, luego haga referencia a esa "variable" en todas partes en mi código. ¿Alguien sabe cómo ubicar datos constantes en una ubicación específica de memoria direccionable de mi elección, utilizando el compilador C18? ¿Hay alguna forma mejor de que alguien pueda sugerir?
fuente
Respuestas:
Específicamente para resolver la cuestión de vincular variables a direcciones específicas en la memoria flash en el PIC18 con el compilador C18, consulte la sección "Pragmas" en hlpC18ug.chm en el directorio doc donde está instalado el compilador.
Para hacer esto, debe definir una nueva "sección" en la memoria y vincularla a una dirección inicial.
#pragma romdata serial_no_section=0x1700
Esto crea una nueva sección llamada "serial_no_section" que comienza en la dirección 0x1700 en la memoria flash (programa) (porque definimos "romdata" en el #pragma).
Directamente después de la línea #pragma, defina sus variables para:
Ahora tiene 0x12 en la dirección 0x1700 y 0x34 en la dirección 0x1701 en la memoria (porque PIC18 usa el modelo little-endian). El "const rom" asegura que el compilador sepa que este es un tipo de variable const, y que la variable se encuentra en la memoria "rom" y, por lo tanto, debe accederse a través de instrucciones de lectura de la tabla.
La
#pragma romdata
declaración final asegura que las siguientes declaraciones de variables estén vinculadas a las secciones de memoria predeterminadas, ya que el enlazador ve ajustes en lugar de seguir en la sección "serial_no_section".Ahora todo el código puede simplemente hacer referencia a la variable "mySerialNumber", y usted sabe exactamente en qué dirección se puede encontrar el número de serie en la memoria.
Editar el código HEX puede ser un poco desafiante ya que necesita calcular la suma de verificación para cada línea que edita. Estoy trabajando en una clase de C ++ para decodificar y codificar archivos Intel HEX, lo que debería facilitarlo, pero aún no está terminado. La decodificación de archivos funciona, la codificación de nuevo aún no está implementada. El proyecto (si está interesado) está aquí https://github.com/codinghead/Intel-HEX-Class
Espero que esto ayude
fuente
He hecho el número de serie (s / n para abreviar) de una manera similar a lo que describe Joel. Estaba usando PIC18F4620 y el compilador CCS. La ubicación de s / n en la memoria Flash fue forzada a los últimos 4 bytes. Como estaba usando solo el 80% de Flash, mi compilador y el enlazador no escribían código ejecutable en los últimos 4 bytes.
Luego tuve 2 formas alternativas de escribir s / n en unidades individuales:
Responder al comentario de Joel
No sé acerca de C18, pero el compilador CCS viene con funciones de biblioteca
write_program_eeprom(...)
yread_program_eeprom(...)
. Así es como se ven en la asamblea.fuente
write_program_eeprom(...)
yread_program_eeprom(...)
. ¡La EEPROM y Flash son dos cosas diferentes!He hecho esto algunas veces. Por lo general, defino un área de información de firmware en una ubicación fija en la memoria del programa, luego escribo un programa que crea un archivo HEX serializado a partir del archivo HEX de plantilla. Todas estas son cosas fáciles de hacer.
En producción, ejecuta el programa de serialización una vez después de que todas las pruebas hayan pasado. Crea el archivo HEX temporal con el número de serie único, que se programa en el PIC, luego se elimina el archivo HEX temporal.
No permitiría que la ubicación fuera reubicable, luego tendría que encontrarla. Eso puede cambiar cada construcción a medida que el vinculador mueve las cosas. Lo he hecho para PIC muy pequeños como la serie 10F, donde estas constantes son parte de las instrucciones MOVLW. En esos casos, tengo que leer el archivo MAP sobre la marcha para determinar dónde están esas ubicaciones. Tengo el código de análisis de archivos MPLINK MAP en una biblioteca solo para ese propósito.
Para poner algo en una ubicación fija, defina un segmento en una dirección fija. El enlazador colocará dichos segmentos absolutos primero, luego los reubicables a su alrededor. No olvides usar CODE_PACK en lugar de solo CODE en un PIC 18, de lo contrario estarás lidiando con palabras de instrucción completas en lugar de bytes individuales. Por ejemplo (simplemente escrito, no se ejecuta más allá del ensamblador):
fuente
Sugeriría almacenar el número de serie en una dirección fija. Dependiendo de su compilador / enlazador y la parte en cuestión, hay algunos enfoques que puede tomar:
fuente
retlw
enfoque suele ser mucho más rápido (en los PIC de 18 bits, uncall
a aretlw
tomará cuatro ciclos en total; el usoclrf TBLPTRU/movlw xx/movwf TBLPTRH/movlw xx/movwf TBLPTRL/tblrd *+/movf TABLAT,w
tomaría ocho).Yo haría lo contrario: compilar y vincular el código, luego averiguar dónde está almacenado el valor del archivo vinculador. Es posible que deba ubicar la variable explícitamente en un segmento que está asignado a flash.
No solicite esto, pero el software para PC que proporciono para mi programador Wisp648 tiene la capacidad de leer un archivo .hex, modificar una ubicación específica y volver a escribir el archivo .hex (en el mismo archivo o en otro). No es necesario que mi programador esté presente. La fuente está disponible (en Python), la licencia permite todo uso: www.voti.nl/xwisp Puede ser útil una vez que haya resuelto su problema principal.
fuente