Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT




Loading

UART crashes everything on PIC32

Posted by enrad on May 6, 2017

Processor is PIC32MX695F512L Dev-ID says  54300053 (from Real-ICE), so it should be silicon-rev 5. I am using OPEN/FREE-RTOS   I have an ISR servicing UART1. The UART is connected to a MAX3535, RS485 isolated tranceiver in full duplex mode (RS485-4-Wire). My ISR detects if there is no transmission the bus, or if the transmission is incorrect data is trashed and buffers flushed. If any of the above conditions is present for more than 600s I reset the UART. Now this is where the problems starts: If the RS485 bus is disconnected and un-terminated, I obviously will get a lot of random data into the UART. My ISR will detect this as a fault and will reset the UART after 600s. When the reset code is exicuted it seems that the Data-memory is trashed, and the RTOS seems to crash only running the communication task. ~~~  if( lastmessagetimecnt > globalinst.AQLcomabsencetime ) { // tid i ms     //taskENTERCRITICAL();     //AQLbusRXdisable();     //AQLbusTXdisable();     lastmessagetimecnt = 100000; // stop counting     if(globaldata.AutonomDriftu16 == 0) {      AQLBDebugTxPointeru16 = AQLBTxPointeru16;      AQLBDebugRxPointeru16 = AQLBRxPointeru16;      AQLBDebugTxCountu16 = AQLBTxCountu16;      AQLBDebugRxCountu16 = AQLBRxCountu16;      AQLBDebugfeltasku32 = AQLBfeltasku32;      AQLBDebugfelintu32 = AQLBfelintu32;      AQLBDebugRxintu16 = INTGetEnable(INTU1RX);      AQLBDebugTxintu16 = INTGetEnable(INTU1TX);      for(i = 0; i < 20; i++) {       AQLBDebugTxBufferarru8[i] = AQLBTxBufferarru8[i];      }      for(i = 0; i < 24; i++) {       AQLBDebugRxBufferarru8[i] = AQLBRxBufferarru8[i];      }     }          globaldata.AutonomDriftu16 = AUTONOM; // 1     AQLbusRestart(); // KTL 20140728 Återställ UART om vi får fel.    // taskEXITCRITICAL();    } ~~~ In the above code snippet, No crashes occur if the following lines is enabled: taskENTERCRITICAL();  or  AQLbusTXdisable();   If only the line AQLbusRXdisable(); is enabled, it will crash Obviously the code is working now, since I currently disables both the transmitter and receiver before restarting the UART. But I like to know why and what is happening, since I cannot see any logical reason to why it crashes ~~~ void AQLbusTXdisable(void) {  INTEnable(INTU1TX, INTDISABLED);    U1STACLR=U1STAUTXENMASK;    IFS0CLR =IFS0U1TXIFMASK| IFS0U1EIFMASK;    PORTSetPinsDigitalOut(RS485AQLTXENABLEPORT,RS485AQLTXENABLEMASK);  PORTClearBits(RS485AQLTXENABLEPORT,RS485AQLTXENABLE_MASK);   } //------------------------------------------------------------------------------------------------------------------------------------------

void AQLbusRXdisable(void) {   INTEnable(INTU1RX, INTDISABLED);       U1STACLR=U1STAURXENMASK;       IFS0CLR=IFS0U1RXIFMASK| _IFS0U1EIF_MASK; }

void AQLbusRestart(void)  {  U1STACLR = U1STAURXENMASK;     UARTConfigure(RS485AQLUARTPORT, UARTENABLEPINSTXRX_ONLY);

 UARTSetLineControl(RS485AQLUARTPORT, UARTDATASIZE9BITS | UARTPARITYNONE | UARTSTOPBITS1);  UARTSetDataRate(RS485AQLUARTPORT, 40000000, AQLbusbaudarr[globalinst.AQLBAUDu16]);  UARTSetFifoMode(RS485AQLUARTPORT, UARTINTERRUPTONTXNOTFULL | UARTINTERRUPTONRXNOTEMPTY);  UARTEnable(RS485AQLUARTPORT, UARTENABLEFLAGS(UARTPERIPHERAL | UARTRX | UARTTX) );

 SetPriorityIntU1(UARTINTPR2);  SetSubPriorityIntU1(UARTINTSUBPR1);    AQLbusRXenable();  AQLbusTXdisable();    AQLBTxCountu16 = 0;  AQLBRxCountu16 = 0;    AQLBRxPointeru16 = 0;  AQLBStatu16 = AQLBSMBREADY;  AQLBRxCRCu16 = 0;  AQLBDoGlobalSave_u16 = 0;  } ~~~


UART crashes everything on PIC32

Posted by rtel on May 6, 2017

I am using OPEN/FREE-RTOS

If you have an OpenRTOS license please use WITTENSTEIN's ticketed support service.


UART crashes everything on PIC32

Posted by enrad on May 6, 2017

currently freertos, since we still is in protype stage


UART crashes everything on PIC32

Posted by rtel on May 6, 2017

I don't know what is going on inside the functions, but can I summaries as:

1) Interrupt service routines access buffers. 2) The buffers are also accessed when the UART is reset from a task. 3) If the UART interrupts are disabled before the task accesses the buffers then everything is ok.

If so then I would guess that, in the case you are not disabling interrupts, the ISR is attempting to access a buffer that is in an inconsistent state due to the buffer being accessed simultaneously from non-ISR code.

Or am I missing the point?


UART crashes everything on PIC32

Posted by enrad on May 6, 2017

In all honsty, I havent got a clue, what is actually happening, the only thing I'll se is that everyting stops working, and the com-task is the only thing running. The task itself looks like this, this is the code that actually crashes the RTOS. When it is modified as above, no crashes (what I can see occurs) When the crash occurs, the ISR is not running, and nothing else, exept the task below, ~~~ void ISRhandleTask(void *pvParameters){ // int k, i, n, s, num; uint16 flushRX, time100u16, i; uint32 aqloldtimeu32, aqlsecondsdiffu32;

aql_old_time_u32 = 0;
time_100_u16 = 0;

while(1) {

// Printadio("ISRHANDLE"); if(AQLBDoGlobalSaveu16) { AQLBDoGlobalSaveu16 = 0; // GlobalSave(); }

	if(AQLB_Stat_u16 == AQLB_SMB_SEND) {
		// send a modbus command				
		AQLB_Stat_u16 = AQLB_SMB_SENDING;	
	}

	// if modbus command is retured 
	//	if(......( {
	// 	set AQLB_Stat_u16 = AQLB_SMB_READY;		
	//	}

	// om AQL-slaven fått ett meddelande
	// ktl autonom mod 20140321
	if (!(global_data.AutonomDrift_u16 == AUTONOM_MAN)) {
		if(message_flag == 1) {
			last_message_time_cnt = 0;
			message_flag = 0;
			global_data.AutonomDrift_u16 = NOT_AUTONOM;	
			global_data.AQL_aktiv_u16 = 1; // kontaktad av master
		}	
	}
	if(time_100_u16 > 200 ) {
		time_100_u16 = 0;

		aql_seconds_diff_u32 = RTC_Get_seconds_diff(&aql_old_time_u32);

		last_message_time_cnt += aql_seconds_diff_u32;

		// 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
			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.
		}				
	}	


	if ( U1STA & AQLB_COM_ERRORS ) {     
		if (U1STAbits.FERR)	{
				global_data.AQL_Bus_stat.FRERR_u32++;
		}
		if (U1STAbits.OERR)	{
				global_data.AQL_Bus_stat.OWERR_u32++;
		}			
		if (U1STAbits.PERR)	{
				global_data.AQL_Bus_stat.PAERR_u32++;
		}
		//	Print232("OERR 241");
		//	Print232var3("AQL_Bus slave error: ",global_data.AQL_Bus_stat.FRERR_u32 
		//		,global_data.AQL_Bus_stat.OWERR_u32 ,global_data.AQL_Bus_stat.PAERR_u32 );

    	flushRX = U1RXREG;   // Flush register
    	flushRX = U1RXREG;   // Flush register
   	flushRX = U1RXREG;   // Flush register
    	flushRX = U1RXREG;   // Flush register         

    	flushRX = U1RXREG;   // Flush register
    	flushRX = U1RXREG;   // Flush register 
    	flushRX = U1RXREG;   // Flush register 
    	flushRX = U1RXREG;   // Flush register 
		// Print_adio_var("AQLB_Rx_Pointer_u16 ",AQLB_Rx_Pointer_u16);
    	AQLB_Rx_Pointer_u16 = 0;
    	AQLB_fel_task_u32++;				

     U1STACLR=_U1STA_OERR_MASK | _U1STA_FERR_MASK | _U1STA_PERR_MASK;   
  }

	delay_time = 5; // 2ms
	time_100_u16 +=delay_time;				
	vTaskDelay(delay_time);
}	

}

~~~


UART crashes everything on PIC32

Posted by rtel on May 7, 2017

I'm not sure it is unexpected that resetting something without first disabling its interrupts would cause a problem. Really you want to stop the peripheral operating before resetting it, especially if you are accessing the same data from the interrupt handler and a task.

Can you explain what you mean by that is the only task that is running. Is it the highest priority task in the system? In which case if it is stuck in a loop it will prevent lower priority tasks from running.

How are you determining that this is the only task that is still running.

Do you have configASSERT() defined to something that will sit in a loop?

If that really is the only task that is running, and you pause the debugger, what is the task doing?


UART crashes everything on PIC32

Posted by enrad on May 7, 2017

All tasks have the same priority. The other tasks do visual things, like display-update and blinking som LED's amongst other things. The ISR is also supposed to blink some LED's Since nothing of that is happening, i Would assume that no other tasks is running. When I pause the debugger and singlestep/step over the only thing that happens is that the code is switching between the com-task and vTaskDelay. The only configASSERT is the defaults. For debug reason I have temporarly enabled "vApplicationStackOverflowHook()" but it never gets there.

Yes I know that one should stop the pheripial before changing it, obviously a miss from my side, however it shouldn't have so dramatical effects, I would think.


UART crashes everything on PIC32

Posted by rtel on May 7, 2017

If vTaskDelay() is blocking for the correct time it would seem the OS is still running. Is it possible the interrupt is continuously being re-entered, so most processing time is taken up by repeated execution of the handler?


UART crashes everything on PIC32

Posted by enrad on May 7, 2017

Well, I thought so to, but the handler is not running (no LED's blinking). Yes I think that the OS is till running, but the other tasks is destroyed, for some reason


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

FreeRTOS kernel V10 is available for immediate download. Now MIT licensed.


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS