XC32 optimiza la capacidad de uso para la lectura de registros

2

Estoy enfrentando un problema con la optimización del compilador XC32. Cada vez que escribo una función para leer algo del registro, XC32 optimiza (lee: elimina) la variable que contiene el valor de retorno.

Tengo una función de envoltura que lee un pin perticular del puerto perticular:

uint8_t u8INT_DIO_ReadRangeSelect(void)
{
    uint8_t u8pinstatus = 0;

    // Read pin assigned to Range Select input
    u8pinstatus = (uint8_t) SYS_PORTS_PinRead(PORTS_ID_0, 
            RANGE_SELECT_PORT, RANGE_SELECT_PIN);

    return u8pinstatus;
}

Aquí SYS_PORTS_PinRead es un código generado por Harmony (herramienta de generación de código de PIC) y solo lee el pin del puerto. El código para eso es:

return( _SFR_BIT_READ( _PORTS_READ_B_VREG(index) + ((channel-1) * 0x40), bitPos ) );

Ten en cuenta que es una función en línea.

Ahora, cuando configuro el nivel de optimización en 1, XC32 elimina la variable u8pinstatus y siempre devuelve 0.

Pero si declaro u8pinstatus como volatile , todo funciona bien (lo que se esperaba).

Pero luego tengo que declarar todas las variables volátiles porque todas las funciones de mi envoltorio siempre están devolviendo 0. Eso no es una buena manera.

¿Es que XC32 se volvió loco o estoy haciendo algo mal?

Información adicional:

Código de ensamblaje con optimización :

!uint8_t u8INT_DIO_ReadRangeSelect(void)
!{
0x9D00AA8C: ADDIU SP, SP, -24
0x9D00AA90: SW RA, 20(SP)
!    uint8_t u8pinstatus = 0;
!    
!    // Read pin assigned to Range Select input
!    u8pinstatus = (uint8_t) SYS_PORTS_PinRead(PORTS_ID_0, 
0x9D00AA94: ADDU A0, ZERO, ZERO
0x9D00AA98: ADDIU A1, ZERO, 3
0x9D00AA9C: JAL SYS_PORTS_PinRead
0x9D00AAA0: ADDIU A2, ZERO, 8
!            RANGE_SELECT_PORT, RANGE_SELECT_PIN);
!    return u8pinstatus;
!}
0x9D00AAA4: LW RA, 20(SP)
0x9D00AAA8: JR RA
0x9D00AAAC: ADDIU SP, SP, 24

Código de ensamblaje sin optimización :

!uint8_t u8INT_DIO_ReadRangeSelect(void)
!{
0x9D00F998: ADDIU SP, SP, -32
0x9D00F99C: SW RA, 28(SP)
0x9D00F9A0: SW S8, 24(SP)
0x9D00F9A4: ADDU S8, SP, ZERO
!    uint8_t u8pinstatus = 0;
0x9D00F9A8: SB ZERO, 16(S8)
!    
!    // Read pin assigned to Range Select input
!    u8pinstatus = (uint8_t) SYS_PORTS_PinRead(PORTS_ID_0, 
0x9D00F9AC: ADDU A0, ZERO, ZERO
0x9D00F9B0: ADDIU A1, ZERO, 3
0x9D00F9B4: ADDIU A2, ZERO, 8
0x9D00F9B8: JAL SYS_PORTS_PinRead
0x9D00F9BC: NOP
0x9D00F9C0: SB V0, 16(S8)
!            RANGE_SELECT_PORT, RANGE_SELECT_PIN);
!    return u8pinstatus;
0x9D00F9C4: LBU V0, 16(S8)
!}
0x9D00F9C8: ADDU SP, S8, ZERO
0x9D00F9CC: LW RA, 28(SP)
0x9D00F9D0: LW S8, 24(SP)
0x9D00F9D4: ADDIU SP, SP, 32
0x9D00F9D8: JR RA
0x9D00F9DC: NOP
    
pregunta Swanand

1 respuesta

2

Las optimizaciones del compilador generalmente asumen que nada más que el propio programa puede alterar el contenido de la memoria. Con esa suposición, las lecturas repetidas del mismo registro en un microcontrolador a menudo se optimizan, porque el compilador no ve nada en el código que pueda dar un resultado diferente con la ejecución repetida. ¿Por qué ejecutar las mismas instrucciones una y otra vez si el resultado siempre será el mismo?

Volatile es la solución. Le dice al compilador que algo más en el universo podría alterar esa dirección particular en la memoria, y que sus suposiciones sobre valores futuros no son necesariamente ciertas. "No me optimices, hermano".

En resumen, creo que las cosas se están comportando exactamente como se pretendía.

    
respondido por el Stephen Collings

Lea otras preguntas en las etiquetas