Número de serie PIC editable en archivo HEX

8

Actualmente tengo un número de serie codificado en mi firmware para un diseño con el que estoy trabajando. El firmware puede leer y reportar el número de serie. Eso funciona bien para lo que necesito. El problema es que cada nuevo número de serie me obliga a cambiar mi código y volver a compilarlo. Esto es engorroso cuando hay muchas unidades que se deben construir, tiene la posibilidad de introducir errores y es una mala práctica general. Los números de serie se me asignaron y el diseño del hardware se estableció 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, por lo que idealmente, quiero definir & localícelo una vez, luego haga referencia a esa "variable" en cualquier otra parte de mi código. ¿Alguien sabe cómo ubicar datos constantes en una ubicación de memoria direccionable específica de mi elección, usando el compilador C18? ¿Hay alguna manera mejor que alguien pueda sugerir?

    
pregunta Joel B

5 respuestas

4

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 de inicio para que

#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:

#pragma romdata serial_no_section=0x1700
const rom int mySerialNumber = 0x1234;
#pragma romdata

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). La "const rom" garantiza que el compilador sabe que se trata de un tipo de variable const, y que la variable se encuentra en la memoria "rom" y, por lo tanto, debe accederse mediante las instrucciones de lectura de la tabla.

La declaración final #pragma romdata garantiza que todas las siguientes declaraciones de variables estén vinculadas a las secciones de memoria predeterminadas, ya que el vinculador considera que los 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 comprobación para cada línea que edite. Estoy trabajando en una clase de C ++ para decodificar y codificar archivos Intel HEX, lo que debería hacer esto más fácil, pero aún no está terminado. La decodificación de archivos funciona, la codificación de nuevo todavía no está implementada. El proyecto (si está interesado) está aquí enlace

Espero que esto ayude

    
respondido por el Stuart Cording
4

He hecho el número de serie (s / n para abreviar) de una manera similar a lo que Joel está describiendo. Yo estaba usando PIC18F4620 y 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 enlazador no escribían código ejecutable en los últimos 4 bytes.

Luego tuve 2 formas alternativas para escribir s / n en unidades individuales:

  • El depurador en circuito CCS (ICD) tenía una característica que permitía manipular cualquier ubicación dentro de Flash. Fue un truco útil. Lamentablemente, en revisiones posteriores lo han eliminado.
  • PIC tenía un enlace serial a una PC. s / n fue subido a través de él. El firmware tenía una rutina que recibía el s / n y lo almacenaba en Flash.

Responder al comentario de Joel

No sé sobre C18, pero el compilador CCS viene con las funciones de biblioteca write_program_eeprom(...) y read_program_eeprom(...) . Así es como se ven en el ensamblaje.

....................    write_program_eeprom(i_ADDR, iWord);
EF84:  BSF    FD0.6
EF86:  CLRF   FF8
EF88:  MOVLW  7F
EF8A:  MOVWF  FF7
EF8C:  MOVLW  F0
EF8E:  MOVWF  FF6
EF90:  MOVLB  0
EF92:  BRA    EF24
EF94:  MOVLW  F0
EF96:  MOVWF  FF6
EF98:  MOVFF  490,FF5
EF9C:  TBLWT*+
EF9E:  MOVFF  491,FF5
EFA2:  TBLWT*
EFA4:  BCF    FA6.6
EFA6:  BSF    FA6.4
EFA8:  RCALL  EF3C
EFAA:  RCALL  EF3C
EFAC:  CLRF   FF8
EFAE:  CLRF   FF8
....................    iWord = read_program_eeprom(i_ADDR); 
EF60:  CLRF   FF8
EF62:  MOVLW  7F
EF64:  MOVWF  FF7
EF66:  MOVLW  F0
EF68:  MOVWF  FF6
EF6A:  TBLRD*+
EF6C:  MOVF   FF5,W
EF6E:  TBLRD*
EF70:  MOVFF  FF5,03
EF74:  CLRF   FF8
EF76:  MOVLB  4
EF78:  MOVWF  x90
EF7A:  MOVFF  03,491
    
respondido por el Nick Alexeev
2

He hecho esto unas cuantas 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 hace un archivo HEX serializado a partir del archivo HEX de plantilla. Estas son cosas fáciles de hacer.

En producción, ejecuta el programa serializar una vez que todas las pruebas han pasado. Hace que el archivo HEX temporal con el número de serie único, que se programa en el PIC, luego se elimine el archivo HEX temporal.

No permitiría que la ubicación fuera reubicable, entonces tengo que encontrarla. Eso puede cambiar cada compilación a medida que el enlazador 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 colocar 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 se olvide de usar CODE_PACK en lugar de solo CÓDIGO en un PIC 18, de lo contrario, estará tratando con palabras de instalación completas en lugar de bytes individuales. Por ejemplo (solo se escribe, no se ejecuta más allá del ensamblador):

.fwinfo  code_pack h'1000'     ;firmware info area at fixed known address
         db        h'FFFFFFFF' ;serial number, filled in by production program
         db        fwtype      ;type ID of this firmware
         db        fwver       ;version number
         db        fwseq       ;build sequence number
    
respondido por el Olin Lathrop
2

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 podría tomar:

  1. Defina una sección reubicable que contendrá el número de serie, use una directiva #pragma en su código para forzar el número de serie en esa sección y fuerce la dirección de esa sección dentro de la especificación del enlace.
  2. Para las partes que pueden leer la memoria de código directamente, excluya un área de memoria del área que el enlazador puede usar (es decir, dígale que la parte es, por ejemplo, cuatro bytes más pequeña de lo que realmente es), y luego lea el número de serie en código usando algo como '((unsigned long const *) 0x3FFC)'.
  3. Para las partes que no pueden leer la memoria de código directamente, es posible que pueda poner las instrucciones "RETLW" en una dirección fija, y luego convencer al vinculador de que hay funciones invocables que devuelven 'byte' en esas direcciones. Entonces uno diría, por ejemplo, "out_hex (ser_byte0 ()); out_hex (ser_byte1 ()); out_hex (ser_byte2 ()); para generar los bytes del número de serie.
respondido por el supercat
1

Haría lo contrario: compilar y vincular el código, luego averiguar dónde se almacena el valor desde el archivo enlazador. Es posible que deba ubicar la variable explícitamente en un segmento que se asigna a flash.

No pedí 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 u otro archivo) . No hace falta tener presente a mi programador. 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.

    
respondido por el Wouter van Ooijen

Lea otras preguntas en las etiquetas

Comentarios Recientes

===================== Ninguno 0xDE7D78 ================ ==================== Escanear puntos de gamepad emulados ====================== 0xDE8C00 4K NTSC - -------------------------------------------------- ------------------------ Encabezado codificado + E. 2MB RAM =================== === Ninguno 0xDE8B00 64K NTSC ------------------------------------------- -------------------------------- Tabla ASCII de carga útil DXOR (en hexadecimal) ========== =========================== 0xD86C00 4K INT-4 Base de datos de color... Lees verder