I have problemm with critical sections again :(
When I execute vEnterCritical or vExitCritical step by step they works well.
When I step over this functions they switches CPU to interrupt mode... I can't understand such mess.
Here is my code
volatile unsigned int uiCriticalNesting = 0; extern "C" void __SWI_0 ( void ); extern "C" void __SWI_1 ( void ); void __swi(0) vEnterCritical( void ); void __SWI_0 ( void ) { int R12; __asm{ MRS R12, SPSR }; __asm{ ORR R12, R12, #0xC0 }; __asm{ MSR SPSR_CXSF, R12 }; ++uiCriticalNesting; } void __swi(1) vExitCritical( void ); void __SWI_1 ( void ) { if( uiCriticalNesting ) { --uiCriticalNesting; if( uiCriticalNesting == 0 ) { int R12; __asm{ MRS R12, SPSR }; __asm{ BIC R12, R12, #0xC0 }; __asm{ MSR SPSR_CXSF, R12 }; } } }
and:
T_Bit EQU 0x20 PRESERVE8 ; 8-Byte aligned Stack AREA SWI_Area, CODE, READONLY ARM EXPORT SWI_Handler SWI_Handler STMFD SP!, {R8, LR} ; Store R8, LR MRS R12, SPSR ; Get SPSR TST R12, #T_Bit ; Check Thumb Bit LDRNEH R12, [LR,#-2] ; Thumb: Load Halfword BICNE R12, R12, #0xFF00 ; Extract SWI Number LDREQ R12, [LR,#-4] ; ARM: Load Word BICEQ R12, R12, #0xFF000000 ; Extract SWI Number LDR R8, SWI_Count CMP R12, R8 BHS SWI_Dead ; Overflow ADR R8, SWI_Table LDR R12, [R8,R12,LSL #2] ; Load SWI Function Address MOV LR, PC ; Return Address BX R12 ; Call SWI Function LDMFD SP!, {R8, PC}^ ; Restore R8 and Return SWI_Dead B SWI_Dead ; None Existing SWI SWI_Cnt EQU (SWI_End-SWI_Table)/4 SWI_Count DCD SWI_Cnt IMPORT __SWI_0 IMPORT __SWI_1 SWI_Table DCD __SWI_0 ; SWI 0 Function Entry DCD __SWI_1 ; SWI 1 Function Entry SWI_End END
It worked for a months... Now it stopped working. Can anybody help?
HI.
<quote> the fact that it comes and goes indicates that there is something fundamentally wrong with the program. </quote>
whot book does a conclushion get seen in? i want to stay away!
but it is more probeble for problem in code and not strange spontanius changes in CPU.
Always yo're freind.
Zeusti.
I found source of problemm but I have no idea how to solve it. I use pit irq and ubgu irq, they both share system irq. When I disable dbgu irq all works ok.
So how to configure it to work properly? I have 3 constructors to create 3 global objects: one to initialize sys irq, one to initialize pit and enable it's irq and one to initialize dbgu and it's irq. I tried to change order of constructors, but with no positive result :(
void __irq AT91IRQ_SYS::IRQ (void) { PIT.irq(); calibration.irq(); AT91F_AIC_AcknowledgeIt( AT91C_BASE_AIC ); } AT91IRQ_SYS::AT91IRQ_SYS( void ) { AT91F_AIC_DisableIt( AT91C_BASE_AIC, AT91C_ID_SYS ); AT91F_AIC_ConfigureIt( AT91C_BASE_AIC, AT91C_ID_SYS, AT91C_AIC_PRIOR_LOWEST + 1, AT91C_AIC_SRCTYPE_HIGH_LEVEL, (void(*)())IRQ ); AT91F_AIC_EnableIt( AT91C_BASE_AIC, AT91C_ID_SYS ); }
void AT91PIT::irq( void ) { if ( AT91F_PITGetStatus( AT91C_BASE_PITC ) & AT91C_PITC_PITS ) { timestamp += AT91F_PITGetPIVR( AT91C_BASE_PITC ) >> 20; } } AT91PIT::AT91PIT( void ) { AT91F_PITC_CfgPMC(); AT91F_PITInit( AT91C_BASE_PITC, PIT_PERIOD, BOARD_MCK_MHZ ); AT91F_PITEnableInt( AT91C_BASE_PITC ); }
CALIBR::CALIBR( AT91PS_DBGU DBGU, unsigned int ID, unsigned int IO, unsigned int speed, AT91PS_PIO port, unsigned int pin, volatile calibration_table_crc * data, volatile internal & wew, volatile range & rng, volatile protect & p, unsigned short msk ) : state( READY2LISTEN ), bytes2read( 0 ), alreadyread( 0 ), calib_data( data ), int_data( wew ), int_rng( rng ), status( p.state ), mask( msk ), keep_alive( UNIWIBR( time_alive ) ), valid_command( UNIWIBR( time_gap ) ) { dbgu = new AT91USART( reinterpret_cast<AT91PS_USART>(DBGU), ID, IO, AT91C_US_USMODE_NORMAL, speed, par_none, stop_1 ); AT91F_PIO_CfgPeriph( port, IO, 0 ); AT91F_US_DisableIt( dbgu->pUSART, 0xFFFF ); dbgu->pUSART->US_PTCR = AT91C_PDC_TXTDIS | AT91C_PDC_RXTDIS; AT91F_US_GetChar( dbgu->pUSART ); AT91F_US_EnableIt( dbgu->pUSART, AT91C_US_RXRDY ); dbgu->pUSART->US_CR = AT91C_US_RXEN; }
Any idea what to do?