Automatizando el cambio del archivo del enlazador

4

Estoy trabajando en un proyecto de firmware en el que tengo que hacer una comprobación de crc16 para verificar 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 siempre que realicemos algunos cambios en el código. ¿Puedo automatizar este proceso que estoy haciendo manualmente ahora mismo?

del archivo 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 la cantidad de memoria que reside mi código dentro del flash. Este es el primer 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!

    
pregunta OnkarK

2 respuestas

3

No conozco su vinculador, pero el vinculador 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, por lo que el BSS se puede borrar y los DATOS (en RAM) se pueden inicializar desde la copia en la ROM.

Fragmento de un enlace (LPC1343) que utilizo:

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

  • Usted dice que verifica el segmento de código. ¿Comprueba el segmento DATA (inicializado globalmente)? valores) también?

  • Si me pusieran esta tarea, consideraría organizar las ubicaciones en las que las ubicaciones de flash no utilizadas se llenan con un valor conocido, y organizar la columna de verificación sobre el flash total.

respondido por el Wouter van Ooijen
1

Estoy usando EW8051, pero también usa Xlink. Hay que tener en cuenta dos tamaños: 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 va en aumento) a medida que actualiza su programa y compila el enlace.

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

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

Sin embargo, la parte de la que realmente utiliza mi código se encuentra en el archivo .map:

30 739 bytes of CODE  memory

Mirando la sección de cálculo de suma de comprobación de la IAR Linker and Library Tools Reference Guide , parece que normalmente le indicaría al vinculador que calcule la suma de comprobación en todo el segmento CODE (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 final me sugieren que la suma de control se debe calcular en 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 existe cierta ambigüedad en lo que significa "todos los bytes": todo el segmento de CÓDIGO, 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 inicializan con cero. Usted debe verificar esto. : ^)

En resumen: use la marca -J para sumar la suma de comprobación de todo el segmento de CÓDIGO, 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 de CÓDIGO no es lleno de basura).

    
respondido por el David

Lea otras preguntas en las etiquetas