2011-07-19 17 views
5

En las definiciones CMSIS de gcc se puede encontrar algo como esto:datos de la memoria Barrera (DMB) en las bibliotecas CMSIS de Cortex-M3

static __INLINE void __DMB(void) { __ASM volatile ("dmb"); } 

Mi pregunta es: ¿qué uso hace de una barrera de memoria han si lo hace no declarar "memoria" en la lista de clobber

¿Es un error en core_cm3.h o hay una razón por la cual gcc debería comportarse correctamente sin ayuda adicional?

+1

Buena pregunta. Tenga en cuenta que Linux utiliza el clobber 'memory': http://lxr.free-electrons.com/source/arch/arm/include/asm/system.h?v=2.6.39#L135 – ninjalj

+1

@ninjalj: Gracias por el enlazar. (no apareció en google rápido) – jpc

Respuesta

5

Hice algunas pruebas con gcc 4.5.2 (construido con LTO). Si puedo compilar este código:

static inline void __DMB(void) { asm volatile ("dmb"); } 
static inline void __DMB2(void) { asm volatile ("dmb" ::: "memory"); } 

char x; 

char test1 (void) 
{ 
    x = 15; 
    return x; 
} 

char test2 (void) 
{ 
    x = 15; 
    __DMB(); 
    return x; 
} 

char test3 (void) 
{ 
    x = 15; 
    __DMB2(); 
    return x; 
} 

usando arm-none-eabi-gcc -Os -mcpu=cortex-m3 -mthumb -c dmb.c, a continuación, a partir arm-none-eabi-objdump -d dmb.o me sale esto:

00000000 <test1>: 
    0: 4b01  ldr r3, [pc, #4] ; (8 <test1+0x8>) 
    2: 200f  movs r0, #15 
    4: 7018  strb r0, [r3, #0] 
    6: 4770  bx lr 
    8: 00000000 .word 0x00000000 

0000000c <test2>: 
    c: 4b02  ldr r3, [pc, #8] ; (18 <test2+0xc>) 
    e: 200f  movs r0, #15 
    10: 7018  strb r0, [r3, #0] 
    12: f3bf 8f5f dmb sy 
    16: 4770  bx lr 
    18: 00000000 .word 0x00000000 

0000001c <test3>: 
    1c: 4b03  ldr r3, [pc, #12] ; (2c <test3+0x10>) 
    1e: 220f  movs r2, #15 
    20: 701a  strb r2, [r3, #0] 
    22: f3bf 8f5f dmb sy 
    26: 7818  ldrb r0, [r3, #0] 
    28: 4770  bx lr 
    2a: bf00  nop 
    2c: 00000000 .word 0x00000000 

Es obvio que __DBM() sólo se inserta la instrucción dmb y se tarda DMB2() a la fuerza en realidad el compilador purgar los valores almacenados en caché en los registros.

Supongo que encontré un error CMSIS.

2

En mi humilde opinión, la versión de CMSIS es correcta.

La inyección de la instrucción barrera sin la memoria en la lista clobber logra exactamente lo que se supone que debe hacer:

Si la escritura anterior en la variable "x" se reguló a continuación, se ha comprometido. Esto es útil, por ejemplo, si va a pasar una dirección "x" como una dirección DMA, o si va a configurar MPU.

No tiene efecto al devolver "x" (se garantiza que su programa sea correcto incluso si omite la barrera de memoria).

Por otro lado al insertar memoria en la lista de palabras clave, no tiene ningún tipo de efecto en situaciones como el ejemplo anterior (DMA, MPU ..).

La única diferencia en este último caso es que si tiene un ISR que modifica el valor de "x" después de "strb", entonces el valor que se devolverá será el valor modificado por el ISR, porque el clobber hizo que el compilador leyera de memoria para registrarse nuevamente. Pero si quiere obtener esto, entonces debe usar variables "volátiles".

En otras palabras: la fuerzas de barrera caché vs memoria se comprometen con el fin de garantizar la coherencia con otros recursos HW que podrían tener acceso a la memoria RAM, mientras que la memoria clobbering causa compilador para dejar de asumir la memoria no ha cambiado y para leer de nuevo en los registros locales , eso es otra cosa con diferentes propósitos (no importa si el cambio de memoria todavía está en caché o si ya está comprometido en RAM, porque se garantiza que una operación eventual de carga de asm funcionará en ambos casos sin barreras).

+1

¿Pero no es el compilador libre de reordenar las instrucciones de los alrededores para que la escritura en "x" no llegue a la caché en el momento en que se ejecuta la barrera? Quería que la memoria se bloqueara para que el compilador se viera obligado a enviar la variable a la memoria (posiblemente memoria caché) y luego a la barrera para forzar el caché al ras. – jpc

Cuestiones relacionadas