Muy mal rendimiento con PIC32

2

Tengo un problema con un rendimiento muy malo en mi código PIC32. Por ejemplo, tengo este ISR que da servicio a varias fuentes de interrupción diferentes:

volatile int rxEvents = 0;
volatile int txEvents   = 0;
volatile int int1Events = 0;
volatile int events     = 0;
volatile bool spi_read_flag  = 0;
volatile bool spi_write_flag = 0;
volatile bool spi_int_flag   = 0;
volatile bool adc_ready = 0;
void __attribute__((__interrupt__)) _DefaultInterrupt(){
    PIN(TIMER, LAT, LAT) = 1; // turn on an IO pin
    if(IFS0bits.T1IF){
        IFS0bits.T1IF = 0;
        AD1CON1bits.ASAM = 1; // begin sampling
    }
    if(IFS1bits.AD1IF){
        IFS1bits.AD1IF = 0;
        adc_ready = true;
    }

    ++events;
    if(IFS1bits.SPI2RXIF){
        ++rxEvents;
        IFS1bits.SPI2RXIF = 0;
        spi_read_flag = 1;
    }
    if(IFS1bits.SPI2TXIF){
        ++txEvents;
        IFS1bits.SPI2TXIF = 0;
        spi_write_flag = 1;
    }
    if(IFS0bits.INT1IF){
        ++int1Events;
        IFS0bits.INT1IF = 0;
        spi_int_flag = 1;
    }
    PIN(TIMER, LAT, LAT) = 0; // turn off the IO pin
}

Como puede ver, simplemente está verificando y borrando bits de marca, y configurando algunas banderas booleanas / realizando otras acciones simples.

Al determinar el alcance del pin IO, he encontrado que en algunos casos este ISR puede tardar hasta 100us en completarse, lo que a mi velocidad de reloj de 8MHz significaría que requiere 800 instrucciones, lo que parece una locura. Una captura de pantalla de la sincronización del pin IO se puede ver a continuación.

Mipreguntaes,¿quéestácausandoestebajorendimiento?¿Hayalgúnajustederelojquemefalta?HeverificadoqueelrelojSPIfuncionaa500kHz,comoseesperabaconunaescalade8yunrelojdelsistemade8MHz.Acontinuaciónsemuestralaconfiguracióncompletaqueestoyusando:

//DEVCFG3//USERID=NoSetting//DEVCFG2#pragmaconfigFPLLIDIV=DIV_12//PLLInputDivider(12xDivider)#pragmaconfigFPLLMUL=MUL_24//PLLMultiplier(24xMultiplier)#pragmaconfigUPLLIDIV=DIV_12//USBPLLInputDivider(12xDivider)#pragmaconfigUPLLEN=OFF//USBPLLEnable(DisabledandBypassed)#pragmaconfigFPLLODIV=DIV_256//SystemPLLOutputClockDivider(PLLDivideby256)//DEVCFG1#pragmaconfigFNOSC=FRC//OscillatorSelectionBits(FastRCOsc(FRC))#pragmaconfigFSOSCEN=ON//SecondaryOscillatorEnable(Enabled)#pragmaconfigIESO=ON//Internal/ExternalSwitchOver(Enabled)#pragmaconfigPOSCMOD=OFF//PrimaryOscillatorConfiguration(Primaryoscdisabled)#pragmaconfigOSCIOFNC=ON//CLKOOutputSignalActiveontheOSCOPin(Enabled)#pragmaconfigFPBDIV=DIV_8//PeripheralClockDivisor(Pb_ClkisSys_Clk/8)#pragmaconfigFCKSM=CSDCMD//ClockSwitchingandMonitorSelection(ClockSwitchDisable,FSCMDisabled)#pragmaconfigWDTPS=PS1048576//WatchdogTimerPostscaler(1:1048576)#pragmaconfigFWDTEN=ON//WatchdogTimerEnable(WDTEnabled)//DEVCFG0#pragmaconfigDEBUG=OFF//BackgroundDebuggerEnable(Debuggerisdisabled)#pragmaconfigICESEL=ICS_PGx2//ICE/ICDCommChannelSelect(ICEEMUC2/EMUD2pinssharedwithPGC2/PGD2)#pragmaconfigPWP=OFF//ProgramFlashWriteProtect(Disable)#pragmaconfigBWP=OFF//BootFlashWriteProtectbit(ProtectionDisabled)#pragmaconfigCP=OFF//CodeProtect(ProtectionDisabled)

Aquíestáeldesmontajecompleto,121instruccionesentotal,creoqueesodeberíasignificaruntiempodeejecuciónenelpeordeloscasos,aproximadamente15,(amenosquemefaltenalgunaspenalizacionesgravesrelacionadasconelaccesoalamemoria):

17:void__attribute__((__interrupt__))_DefaultInterrupt(){9D003854415DE800RDPGPRSP,SP9D003858401B7000MFC0K1,EPC9D00385C401A6002MFC0K0,SRSCtl9D00386027BDFFE0ADDIUSP,SP,-329D003864AFBB001CSWK1,28(SP)9D003868401B6000MFC0K1,Status9D00386CAFBA0018SWK0,24(SP)9D003870401A6800MFC0K0,Cause9D003874AFBB0014SWK1,20(SP)9D003878001AD282SRLK0,K0,109D00387C7F5B7A84INSK1,K0,10,69D0038807C1B2044INSK1,ZERO,1,49D003884409B6000MTC0K1,Status9D003888AFA30004SWV1,4(SP)9D00388CAFA20000SWV0,0(SP)9D0038908FA30018LWV1,24(SP)9D0038943063000FANDIV1,V1,159D00389814600003BNEV1,ZERO,0x9D0038A89D00389C00000000NOP9D0038A0AFBE000CSWS8,12(SP)9D0038A4AFA40008SWA0,8(SP)9D0038A803A0F021ADDUS8,SP,ZERO18:PIN(TIMER,LAT,LAT)=1;//indicatesamplingstarted9D0038AC3C03BF88LUIV1,-165049D0038B08C626160LWV0,24928(V1)9D0038B424040001ADDIUA0,ZERO,19D0038B87C820844INSV0,A0,1,19D0038BCAC626160SWV0,24928(V1)19:if(IFS0bits.T1IF){9D0038C03C02BF88LUIV0,-165049D0038C48C421030LWV0,4144(V0)9D0038C830420010ANDIV0,V0,169D0038CC1040000ABEQV0,ZERO,0x9D0038F89D0038D000000000NOP20:IFS0bits.T1IF=0;9D0038D43C03BF88LUIV1,-165049D0038D88C621030LWV0,4144(V1)9D0038DC7C022104INSV0,ZERO,4,19D0038E0AC621030SWV0,4144(V1)21:AD1CON1bits.ASAM=1;//beginsampling9D0038E43C03BF81LUIV1,-165119D0038E88C629000LWV0,-28672(V1)9D0038EC24040001ADDIUA0,ZERO,19D0038F07C821084INSV0,A0,2,19D0038F4AC629000SWV0,-28672(V1)22:}23:if(IFS1bits.AD1IF){9D0038F83C02BF88LUIV0,-165049D0038FC8C421040LWV0,4160(V0)9D00390030420002ANDIV0,V0,29D00390410400007BEQV0,ZERO,0x9D0039249D00390800000000NOP24:IFS1bits.AD1IF=0;9D00390C3C03BF88LUIV1,-165049D0039108C621040LWV0,4160(V1)9D0039147C020844INSV0,ZERO,1,19D003918AC621040SWV0,4160(V1)25:adc_ready=true;9D00391C24020001ADDIUV0,ZERO,19D003920A3828023SBV0,-32733(GP)26:}27:28:++events;9D0039248F82801CLWV0,-32740(GP)9D00392824420001ADDIUV0,V0,19D00392CAF82801CSWV0,-32740(GP)29:if(IFS1bits.SPI2RXIF){9D0039303C02BF88LUIV0,-165049D0039348C421040LWV0,4160(V0)9D00393830420080ANDIV0,V0,1289D00393C1040000ABEQV0,ZERO,0x9D0039689D00394000000000NOP30:++rxEvents;9D0039448F828010LWV0,-32752(GP)9D00394824420001ADDIUV0,V0,19D00394CAF828010SWV0,-32752(GP)31:IFS1bits.SPI2RXIF=0;9D0039503C03BF88LUIV1,-165049D0039548C621040LWV0,4160(V1)9D0039587C0239C4INSV0,ZERO,7,19D00395CAC621040SWV0,4160(V1)32:spi_read_flag=1;9D00396024020001ADDIUV0,ZERO,19D003964A3828020SBV0,-32736(GP)33:}34:if(IFS1bits.SPI2TXIF){9D0039683C02BF88LUIV0,-165049D00396C8C421040LWV0,4160(V0)9D00397030420040ANDIV0,V0,649D0039741040000ABEQV0,ZERO,0x9D0039A09D00397800000000NOP35:++txEvents;9D00397C8F828014LWV0,-32748(GP)9D00398024420001ADDIUV0,V0,19D003984AF828014SWV0,-32748(GP)36:IFS1bits.SPI2TXIF=0;9D0039883C03BF88LUIV1,-165049D00398C8C621040LWV0,4160(V1)9D0039907C023184INSV0,ZERO,6,19D003994AC621040SWV0,4160(V1)37:spi_write_flag=1;9D00399824020001ADDIUV0,ZERO,19D00399CA3828021SBV0,-32735(GP)38:}39:if(IFS0bits.INT1IF){9D0039A03C02BF88LUIV0,-165049D0039A48C421030LWV0,4144(V0)9D0039A830420080ANDIV0,V0,1289D0039AC1040000ABEQV0,ZERO,0x9D0039D89D0039B000000000NOP40:++int1Events;9D0039B48F828018LWV0,-32744(GP)9D0039B824420001ADDIUV0,V0,19D0039BCAF828018SWV0,-32744(GP)41:IFS0bits.INT1IF=0;9D0039C03C03BF88LUIV1,-165049D0039C48C621030LWV0,4144(V1)9D0039C87C0239C4INSV0,ZERO,7,19D0039CCAC621030SWV0,4144(V1)42:spi_int_flag=1;9D0039D024020001ADDIUV0,ZERO,19D0039D4A3828022SBV0,-32734(GP)43:}44:PIN(TIMER,LAT,LAT)=0;//indicatesamplingstarted9D0039D83C03BF88LUIV1,-165049D0039DC8C626160LWV0,24928(V1)9D0039E07C020844INSV0,ZERO,1,19D0039E4AC626160SWV0,24928(V1)45:}9D0039E803C0E821ADDUSP,S8,ZERO9D0039EC8FA20018LWV0,24(SP)9D0039F03042000FANDIV0,V0,159D0039F414400005BNEV0,ZERO,0x9D003A0C9D0039F800000000NOP9D0039FC8FBE000CLWS8,12(SP)9D003A008FA40008LWA0,8(SP)9D003A048FA30004LWV1,4(SP)9D003A088FA20000LWV0,0(SP)9D003A0C41606000DIZERO9D003A10000000C0EHB9D003A148FBA001CLWK0,28(SP)9D003A188FBB0014LWK1,20(SP)9D003A1C409A7000MTC0K0,EPC9D003A208FBA0018LWK0,24(SP)9D003A2427BD0020ADDIUSP,SP,329D003A28409A6002MTC0K0,SRSCtl9D003A2C41DDE800WRPGPRSP,SP9D003A30409B6000MTC0K1,Status9D003A3442000018ERET

Lalíneadecomandocompletaestáaquí(rutasacortadas,peroporlodemássinmodificar)

"...\xc32-gcc.exe" -g -x c -c -mprocessor=32MX440F256H -MMD -MF blep_asynch.o.d -o blep_asynch.o blep_asynch.c 
"...\xc32-gcc.exe" -g -x c -c -mprocessor=32MX440F256H -MMD -MF interrupt.o.d -o interrupt.o interrupt.c 
"...\xc32-gcc.exe" -g -x c -c -mprocessor=32MX440F256H -MMD -MF data_handler.o.d -o data_handler.o data_handler.c 
"...\xc32-gcc.exe" -g -x c -c -mprocessor=32MX440F256H -MMD -MF timer.o.d -o timer.o timer.c 
"...\xc32-gcc.exe" -g -x c -c -mprocessor=32MX440F256H -MMD -MF acilib.o.d -o acilib.o acilib.c 
"...\xc32-gcc.exe" -g -x c -c -mprocessor=32MX440F256H -MMD -MF adc.o.d -o adc.o adc.c 
"...\xc32-gcc.exe" -g -x c -c -mprocessor=32MX440F256H -MMD -MF blep.o.d -o blep.o blep.c 
"...\xc32-gcc.exe"   -mprocessor=32MX440F256H  -o project.production.elf main.o bit_order.o acilib.o blep.o adc.o timer.o interrupt.o blep_asynch.o aci_asynch.o data_handler.o          -Wl,--defsym=__MPLAB_BUILD=1,--defsym=_min_heap_size=128,-Map="project.production.map"
    
pregunta Gordon Bailey

3 respuestas

5

La configuración predeterminada de PIC32 es mala con respecto al rendimiento. Uno de los stickies en el foro de PIC32 en el sitio web de microchip dirija esto:

  

Al iniciar PIC32 independientemente de la configuración de los fusibles del oscilador que tiene   especificado comienza con

     

NO se activa el almacenamiento en caché

     

NO se ha habilitado el búfer de captación previa

     

7 estados de espera de FLASH

     

1 estados de espera SRAM

     

Todos estos elementos afectarán el rendimiento de su código y causa   para que funcione significativamente más lento de lo que cabría esperar. Asi como regla   ponga en la primera línea de su función principal lo siguiente:

SYSTEMConfigPerformance(80000000); 
     

donde el número entre paréntesis es el reloj de instrucciones final elegido   tarifa. Esta función configurará correctamente las características de rendimiento de   el PIC32 con el número correcto de estados de espera FLASH y RAM para el   La velocidad elegida y también permitirá el almacenamiento en caché y la captura previa. Configurar esto   Primero y ver que velocidad obtienes. Deberías encontrarlo mucho más rápido. Tú   A continuación, tendrá que jugar con la configuración de optimización del compilador para   mejorar el rendimiento un poco más.

Intente ejecutar la rutina de rendimiento de configuración y vea si ayuda.

    
respondido por el justing
1

Esto no es una respuesta, bug una ruta de depuración. Los PIC32 tienen una gran cantidad de opciones de reloj, y IIRC, si los que solicitas están causando problemas, los relojes harán todo lo posible para encontrar una manera que funcione.

El primer paso para mí en casos como este es verificar los relojes de mi sistema deshaciéndome de todo mi código, excepto de configuraciones simples, programando una simple interrupción del temporizador que no hace más que cambiar un poco, y asegurarme de lo que veo. tiene sentido. Si lo hace, entonces comienzo a agregar código, y si no lo hace, generalmente se identifica mi problema.

Personalmente, hago algo como esto cada vez que comienzo un proyecto, generalmente antes de que los problemas empiecen a ocurrir. Es un buen hábito para entrar.

    
respondido por el Scott Seidman
0

Tu FPLLIDIV parece ser demasiado alto. La documentación indica que la entrada de PLL debe estar entre 4 y 5 MHz. Con el reloj RC de 8 MHz, el FPLLIDIV debería ser 2.

Con un divisor de entrada de 12, un multiplicador de pll de 24 y un divisor de salida de 256, obtienes un divisor total de 128: tu velocidad de reloj final parece ser de 8 MHz DIV 128.

Y también agrega un divisor periférico de 8: la velocidad de reloj de su PIN parece ser de 8 kHz.

Esta es mi configuración con el oscilador RC rápido interno. No estoy seguro si todos los artículos están configurados al mejor valor. Pero funciona razonable:

#pragma config FPLLIDIV = DIV_2         // PLL Input Divider (2x Divider)
#pragma config FPLLMUL = MUL_16         // PLL Multiplier (20x Multiplier)
#pragma config FPLLODIV = DIV_1         // System PLL Output Clock Divider (PLL Divide by 1)
#pragma config FWDTEN = OFF

#pragma config FNOSC = FRCPLL           // Oscillator Selection Bits (Fast RC Osc with PLL)
#pragma config FSOSCEN = OFF            // Secondary Oscillator Enable (Disabled)
#pragma config IESO = OFF               // Internal/External Switch Over (Disabled)
#pragma config POSCMOD = OFF            // Primary Oscillator Configuration (Primary osc disabled)
#pragma config OSCIOFNC = OFF           // CLKO Output Signal Active on the OSCO Pin (Disabled)
#pragma config FPBDIV = DIV_1           // Peripheral Clock Divisor (Pb_Clk is Sys_Clk/1)
#pragma config FCKSM = CSDCMD           // Clock Switching and Monitor Selection (Clock Switch Disable, FSCM Disabled)
    
respondido por el auchmonoabspielbar

Lea otras preguntas en las etiquetas