Automatización del cambio de archivo del enlazador

Estoy trabajando en un proyecto de firmware en el que tengo que hacer una verificación crc16 para la integridad del flash.

Controlador: MSP430 IDE: IAR EW 5.40 (Linker Xlink)

El crc se calcula utilizando el enlazador IAR Xlink y se mantiene al final del flash. Nuevamente, crc se calcula en tiempo de ejecución a partir del código y se compara con el valor almacenado en la memoria flash para verificar la integridad. Sin embargo, solo podemos calcular crc en el segmento de código de la memoria flash. Su tamaño puede cambiar cada vez que hacemos algunos cambios en el código. ¿Puedo automatizar este proceso que estoy haciendo manualmente en este momento?

del archivo del enlazador .xcl:

// ---------------------------------------------------------
// CRC16 Essentials: -H for fill,-J for checksum calculation
// ---------------------------------------------------------

-HFF         

-J2,crc16,,,CHECKSUM2,2=(CODE)5C00-FF7F;(CODE)10000-0x20A13

Aquí necesito cambiar el valor final del segundo segmento de código que es 0x20A13 en este momento. Obtengo este valor del archivo .map, es decir, en cuánto rango de memoria reside mi código dentro del flash. Este es el 1er cambio que hago.

Aquí necesito hacer el segundo cambio del código:

sum = fast_crc16(sum, 0x5C00, 0xFF7F-0x5C00+1);

  sum = fast_crc16(sum, 0x10000,0x20A13-0x10000+1); 

  //Check the crc16 values 
   if(sum != __checksum)
   {
    // Action to be taken if checksum doesn't match
   }

¡Por favor ayuda a automatizar este proceso!

Respuestas (2)

No conozco su enlazador, pero el enlazador gcc puede PROPORCIONAR una etiqueta, cuya dirección se puede usar en el código. Esta función se usa comúnmente para informar al código de inicio sobre el inicio y el final de los segmentos de DATOS y BSS, de modo que el BSS se pueda borrar y los DATOS (en la RAM) se puedan inicializar desde su copia en la ROM.

Fragmento de un linkerscript (LPC1343) que uso:

.text :
{
    . = ALIGN(4);
    __text_start = .;
    PROVIDE(__text_start = __text_start);

            // all text segments are listed here

    . = ALIGN(4);
    __text_end = .;
    PROVIDE(__text_end = __text_end);
} > rom 

La etiqueta __text_end estará en la dirección más allá del texto. Se puede utilizar en el código para el cálculo de CRC.

Dos comentarios:

  • Dices que revisas el segmento del código. ¿Comprueba también el segmento de DATOS (valores globales inicializados)?

  • Si me asignaran esta tarea, consideraría organizar las cosas para que las ubicaciones de flash no utilizadas se llenen con un valor conocido y organizar la suma de comprobación sobre el flash total.

Podemos definir etiquetas para ciertos segmentos en el enlazador y usarlas en el código, pero eso es útil cuando los rangos de direcciones son fijos. De hecho, estaba buscando si había alguna forma de reflejar los cambios en el rango de direcciones del código que no sea el archivo del mapa para evitar editar manualmente el archivo del vinculador.
Puede pasar un valor determinado por el enlazador (en su caso: el final del segmento de código) 'de vuelta' al código como una etiqueta. Ver fragmento en mi respuesta actualizada.
1. El segmento de datos no se está comprobando. 2. -El comando del enlazador HFF es llenar el flash no utilizado con 0xFF. El cálculo de la suma de comprobación de todo el flash funciona bien, pero requiere algo de tiempo adicional. Más de 1 segundo :( Inaceptable.
¿Por qué no comprobar el segmento de datos? ¡Creo que los valores iniciales de las variables globales son tan importantes como el código!

Estoy usando EW8051, pero también usa Xlink. Hay dos tamaños a tener en cuenta: uno es el tamaño del segmento CÓDIGO, que generalmente no cambiará; y el otro es el tamaño que ocupa su código, que variará (generalmente crecerá) a medida que actualice su programa y compile el enlace.

Por ejemplo, aquí, desde mi archivo .xcl del enlazador, puede ver que el tamaño del segmento CÓDIGO es 0x8000:

/
//    CODE
//    ----
-D_CODE0_START=0x000000
-D_CODE0_END=0x007FFF         // CC1111F32 has 32 kB code (flash)

Sin embargo, la parte de eso que realmente usa mi código se incluye en el archivo .map:

30 739 bytes of CODE  memory

Mirando la sección de cálculo de la suma de verificación de la Guía de referencia de herramientas de biblioteca y enlazador IAR , parece que normalmente le indicaría al enlazador que calcule la suma de verificación en todo el segmento de CÓDIGO (todos los 0x8000 bytes en mi caso). Este es el código de ejemplo que proporcionan:

Calculating a checksum in your source code
This source code gives an example of how the checksum can be calculated:
/* Start and end of the checksum range */
/* Must exclude the checksum itself */
unsigned long ChecksumStart = 0x8000+2;
unsigned long ChecksumEnd = 0x8FFF;

/* The checksum calculated by XLINK */
extern unsigned short __checksum;

void TestChecksum()
{
    unsigned short calc = 0;
    /* Run the checksum algorithm */
    calc = slow_crc16(0,
                      (unsigned char *) ChecksumStart,
                      (ChecksumEnd - ChecksumStart+1));
    /* Rotate out the answer */
    unsigned char zeros[2] = {0, 0};
    calc = slow_crc16(calc, zeros, 2);

   /* Test the checksum */
   if (calc != __checksum)
   {
       abort(); /* Failure */
    }
}

Las direcciones de inicio y finalización me sugieren fuertemente que la suma de verificación se calculará sobre todo el segmento.

Al documentar el indicador -J, la referencia indica " Nota : si no especifica ningún rango explícitamente, todos los bytes en la aplicación final se incluyen en el cálculo". Admito que hay cierta ambigüedad en lo que significa "todos los bytes": el segmento CÓDIGO completo, o solo la parte utilizada.

Por supuesto, la única forma en que este esquema puede funcionar sería si los bytes no utilizados en el segmento CODE se inicializaran en cero. Deberías verificar esto. :^)

En resumen: use el indicador -J para verificar la suma de todo el segmento CODE, haga lo mismo en su código y vea si funciona (después de verificar con el depurador, por ejemplo, que la parte no utilizada del segmento CODE no está lleno de basura ).

-H bandera se utiliza para el relleno. Rellena la parte del segmento de código no utilizado con 0xFF, por lo que la suma de comprobación funciona para todo el flash. Esto también tiene una sobrecarga de mayor tiempo de cálculo. Solo quería saber si podemos configurar automáticamente los rangos.