Mystiskt fel, PIC32 korrupt RAM

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 45168
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Mystiskt fel, PIC32 korrupt RAM

Inlägg av TomasL »

Har ett mystiskt fel, vilket gör att RAM blir korrupt, och allting krachar.
Processorn är en PIC32MX512L.
Jag använder mig av FreeRTOS/OpenRTOS.

Följande händer.
Har ett UART-interrupt, vilket normalt skickar och tar emot data över UARTen.
UARTen är externt ansluten till en MAX3535 (isolerad RS485 tranceiver, Full Duplex).

Om RS485 bussen inte är ansluten och o-terminerad så händer konstigheter vid ett specifikt tillfälle.
Mina Interrupt-rutin känner av om det finns riktig kommunikation eller inte, om det inte finns riktig kommunikation, så kastas data och UARTen återstartas var 600s.

När detta händer så blir sannolikt vissa delar av minnet överskrivet med korrupta data, då RTOSet låser sig och enbart kör kommunikations-tasken.

Koden som skapar felet ser ut så här:
Om jag antingen kör taskENTER_CRITICAL()
eller både AQL_bus_RX_disable() och AQL_bus_TX_disable() så fungerar det.
Så vad fasiken är det som händer, naturligtvis är det ju så att eftersom bussen flyter, så kommer det en massa slumpmässiga data och interrupt, men det borde egentligen inte vara några problem.

Kod: Markera allt

// om AQL komunikationen har uteblivit i en viss tid (typ 10 min)
			// if( last_message_time_cnt > ( 10 )) {	
			if( last_message_time_cnt > global_inst.AQL_com_absence_time ) { // tid i ms
				//taskENTER_CRITICAL();
				//AQL_bus_RX_disable();
				//AQL_bus_TX_disable();
				last_message_time_cnt = 100000; // stop counting
				if(global_data.AutonomDrift_u16 == 0) {
					AQLB_Debug_Tx_Pointer_u16 	= AQLB_Tx_Pointer_u16;
					AQLB_Debug_Rx_Pointer_u16 	= AQLB_Rx_Pointer_u16;
					AQLB_Debug_Tx_Count_u16 	= AQLB_Tx_Count_u16;
					AQLB_Debug_Rx_Count_u16 	= AQLB_Rx_Count_u16;
					AQLB_Debug_fel_task_u32 	= AQLB_fel_task_u32;
					AQLB_Debug_fel_int_u32 		= AQLB_fel_int_u32;
					AQLB_Debug_Rx_int_u16 		= INTGetEnable(INT_U1RX);
					AQLB_Debug_Tx_int_u16 		= INTGetEnable(INT_U1TX);
					for(i = 0; i < 20; i++) {
						AQLB_Debug_Tx_Buffer_arr_u8[i] = AQLB_Tx_Buffer_arr_u8[i];
					}	
					for(i = 0; i < 24; i++) {
						AQLB_Debug_Rx_Buffer_arr_u8[i] = AQLB_Rx_Buffer_arr_u8[i];
					}	
				}	
				
				global_data.AutonomDrift_u16 = AUTONOM;  // 1
				AQL_bus_Restart();		// KTL 20140728 Återställ UART om vi får fel.
			//	taskEXIT_CRITICAL();
			}				

Kod: Markera allt

void AQL_bus_TX_disable(void) {	
	INTEnable(INT_U1TX, INT_DISABLED);
   U1STACLR=_U1STA_UTXEN_MASK;
   IFS0CLR =_IFS0_U1TXIF_MASK| _IFS0_U1EIF_MASK;
   PORTSetPinsDigitalOut(RS485_AQL_TX_ENABLE_PORT,RS485_AQL_TX_ENABLE_MASK);		
	PORTClearBits(RS485_AQL_TX_ENABLE_PORT,RS485_AQL_TX_ENABLE_MASK);		
	
}
//------------------------------------------------------------------------------------------------------------------------------------------

void AQL_bus_RX_disable(void) {
		INTEnable(INT_U1RX, INT_DISABLED); 
      U1STACLR=_U1STA_URXEN_MASK; 
      IFS0CLR=_IFS0_U1RXIF_MASK| _IFS0_U1EIF_MASK;
}	

Kod: Markera allt

void AQL_bus_Restart(void)
 {
	U1STACLR = _U1STA_URXEN_MASK; 
	
 	UARTConfigure(RS485_AQL_UART_PORT, UART_ENABLE_PINS_TX_RX_ONLY);

	UARTSetLineControl(RS485_AQL_UART_PORT, UART_DATA_SIZE_9_BITS | UART_PARITY_NONE | UART_STOP_BITS_1);
	UARTSetDataRate(RS485_AQL_UART_PORT, 40000000, AQL_bus_baud_arr[global_inst.AQL_BAUD_u16]);
	UARTSetFifoMode(RS485_AQL_UART_PORT, UART_INTERRUPT_ON_TX_NOT_FULL | UART_INTERRUPT_ON_RX_NOT_EMPTY);
	UARTEnable(RS485_AQL_UART_PORT, UART_ENABLE_FLAGS(UART_PERIPHERAL | UART_RX | UART_TX) );

	SetPriorityIntU1(UART_INT_PR2);
	SetSubPriorityIntU1(UART_INT_SUB_PR1);	
	
	AQL_bus_RX_enable();
	AQL_bus_TX_disable();
	
	AQLB_Tx_Count_u16 = 0;
	AQLB_Rx_Count_u16 = 0;
	
	AQLB_Rx_Pointer_u16 = 0;
	AQLB_Stat_u16 = AQLB_SMB_READY;
	AQLB_Rx_CRC_u16 = 0;
	AQLB_Do_Global_Save_u16 = 0;	
 }
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 45168
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: Mystiskt fel, PIC32 korrupt RAM

Inlägg av TomasL »

En liten ändring, det räcker med taskENTER_CRITICAL() eller AQL_bus_TX_disable() för att det skall fungera.
Fattar överhuvudtaget ingenting.
Mr Andersson
Inlägg: 1394
Blev medlem: 29 januari 2011, 21:06:30
Ort: Lapplandet

Re: Mystiskt fel, PIC32 korrupt RAM

Inlägg av Mr Andersson »

Det jag ser som enter_critical och dina bus_*_disable har gemensamt är att de stänger av interrupts så det känns som att det är någonting där som är galet.
Har ingen direkt koll på freertos själv. Har det reentrant eller nested interrupts? Du kanske får stack overflow pga för många samtidiga interupts.

Alternativt att processorn inte gillar att du ändrar i UARTen (AQL_bus_Restart) med interrupts igång. Jag hade en ARM en gång som gav exceptions om man ändrade i vissa peripherals utan att stänga av deras interrupts först.
ToPNoTCH
Inlägg: 4847
Blev medlem: 21 december 2009, 17:59:48

Re: Mystiskt fel, PIC32 korrupt RAM

Inlägg av ToPNoTCH »

Håller inte på med PIC32 och har svårt att hänga med i koden eftersom det är lite rörigt med alla code rutor.

Jag kan dock inte se någon kö hantering, semaforer eller mutex i koden.
Med din beskrivning "massa slumpmässiga data och interrupt" och ingen köhantering så kan detta vara problemet.

Olika MCU'r beter sig olika om slarvar med detta, men de jag har kört FreeRTOS på kraschar.
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 45168
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: Mystiskt fel, PIC32 korrupt RAM

Inlägg av TomasL »

Processorn köar inte interrupt, däremot kan ett nytt interrupt ske när det gamla är färdigbehandlat.

Vad jag kan konstatera är att det enda som överhuvudtaget körs är själva schedulern (dvs RTOSet), samt "COM"-Tasken (Där den första CODE-utan har ett uttdrag) , inget annat, inga interrupt från comportarna körs.
Nånting mystiskt händer när UARTen om-initialiseras (när portens TX-sida inte blivit stoppad) vilket verkar få till följd att de andra Tasken förstörs, och enbart COM-Tasken körs.
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 45168
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: Mystiskt fel, PIC32 korrupt RAM

Inlägg av TomasL »

EN ide, som skall undersökas är att av någon anledning så stängs samtliga interrupt av om man återinitialiserar porten utan att stänga den först, det kan vara en förklaring till det vi sett.
Skriv svar