4 votos

La automatización de vinculador de cambio de archivo

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

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

El crc se calcula utilizando IAR Xlink enlazador y se mantiene al final de la flash. De nuevo el crc se calcula en tiempo de ejecución del código y se compara con el valor almacenado en el flash para comprobar la integridad. Sin embargo, sólo podemos calcular el crc en el segmento de código de la memoria flash. Su tamaño puede cambiar siempre que se realicen algunos cambios en el código. Puede automatizar este proceso que estoy manualmente haciendo ahora?

a partir de el .xcl enlazador de archivo:

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

-HFF         

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

Aquí tengo que cambiar el valor final del segundo segmento de código que se 0x20A13 ahora. Puedo obtener este valor .archivo de mapa, me.e en cuanto a la memoria rango que mi código es el que residen dentro del flash. Este es el 1er cambio puedo hacer.

Aquí tengo que hacer el 2do cambio de 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, ayudar a la automatización de este proceso!!

3voto

GetFree Puntos 495

En no saber su linker, pero el gcc enlazador puede PROPORCIONAR una etiqueta, que dirección se puede utilizar en el código. Esta característica se utiliza comúnmente para informar a la startupcode sobre el inicio y el final de los DATOS y BSS segmentos, por lo que el BSS se puede borrar y los DATOS (en la RAM) puede ser intialized de la copia de la ROM.

Fragmento de un (LPC1343) linkerscript yo 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 __texto_final será en la dirección más allá del texto. Puede ser utilizado en el código para el cálculo del CRC.

Dos observaciones:

  • Usted dice que usted compruebe el segmento de código. Asegúrese de que usted el segmento de DATOS (inicializado global los valores)?

  • Si esta tarea se puso sobre mí, me gustaría considerar la posibilidad de arreglar las cosas que se utilicen flash lugares que están llenos de un valor conocido, y organizar el checksumn sobre el total de la flash.

2voto

pauliephonic Puntos 1497

Estoy usando EW8051, pero también utiliza Xlink. Hay dos tamaños para tener en cuenta: uno es el tamaño del segmento de CÓDIGO, que generalmente no va a cambiar; y el otro es el tamaño de su código ocupa, que variará (generalmente de crecimiento), como la actualización de su programa y compilar enlace.

Por ejemplo, aquí desde mi linker .xcl archivo puede ver 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 porción de que realmente utilizada por el código aparece en el .archivo de mapa:

30 739 bytes of CODE  memory

Busca en la sección de cálculo de suma de comprobación de la IAR Enlazador y Herramientas de la Biblioteca de la Guía de Referencia, parece que normalmente instruir al enlazador para calcular la suma de comprobación sobre todo el segmento de CÓDIGO (todos 0x8000 bytes en mi caso). Este es el ejemplo de código 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 */
    }
}

El inicio y el final de las direcciones sugieren fuertemente que la suma de comprobación se calcula sobre la totalidad del segmento.

En la documentación de la -J de la bandera, los estados de referencia "Nota: Si no especifica los rangos de forma explícita, todos los bytes en la final de la aplicación se incluyen en el cálculo." Admito que hay una cierta ambigüedad en lo que "todos los bytes" significa: todo el segmento de CÓDIGO, o simplemente el tramo utilizado.

Por supuesto, la única manera de que este esquema de trabajo sería si los bytes no utilizados en el segmento de CÓDIGO son inicializados a cero. Usted debe comprobar esto. :^)

En resumen: el uso de la -J bandera de la suma de comprobación de todo el segmento de CÓDIGO, hacer lo mismo en tu código, y ver si funciona (después de verificar con el depurador, por ejemplo, que la parte no utilizada del CÓDIGO segmentment no está llena de basura).

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X