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;
}