Hi Daniel,
I am able to get one example and did the configuration according to the example. But, I got the Hard fault in UART receive callback (Storing data into Mailbox) when I use the DMA. The receive callback (Storing data into Mailbox) working fine when I use the interrupts.
Scenario 1: (Attached System view traces in zip file)
.transferType = LPUART_USING_INTERRUPTS
uart receive callback: Receiving data using mail boxes
The receive function is working fine but end up problem with watchdog failure(ISR calls so frequently and not giving time to OS Scheduler, attached the System view screenshot). I try to reduce the priority for ISR to 120 and still the issue not solved and ISR calls frequently.
Scenario 2: (attachment: UART_watchdog_disabled_Hang_In_ISR)
.transferType = LPUART_USING_INTERRUPTS
uart receive callback: Receiving data using mail boxes
Watchdog disabled
The controller completely hanged in ISR only (ISR47 in system view). ISR does not allow the Systick, UART_TX task or UART_RX task.
Why UART hanged in ISR? How can recover from the ISR hanging?
Scenario 3: (Attached CPU registers and Hardfault registers)
transferType = LPUART_USING_DMA
uart receive callback: Receiving data using mail boxes
Got the Impreiserr and Forced (attached screenshots)
How can I fix this Hard fault in uart_callback function(UART RX callback)?
//Receive callback
static void uart_callback(void *driver_state, uart_event_t event, void *user_data)
{
(void) driver_state;
(void) user_data;
if(event == UART_EVENT_RX_FULL){
//memcpy(&uart_buff[cnt],&g_uart_rx_buf[0], 1 );
OS_MAILBOX_Put1(&g_uart_rx_mb,&c);
LPUART_DRV_SetRxBuffer(INST_UART0, g_uart_rx_buf, 1);
}
}
//UART init
void uart_init()
{
OS_MAILBOX_Create(&g_uart_rx_mb, 1, UART_RX_MB_BUFFER_SIZE, g_uart_rx_mb_buffer);
OS_QUEUE_Create(&g_uart_uds_queue, &g_uart_qu_buffer, sizeof(g_uart_qu_buffer));
OS_MUTEX_Create(&g_uart_tx_mutex);
INT_SYS_SetPriority(s_lpuartRxTxIrqId[INST_UART0], UART_IRQ_PRIO);
LPUART_DRV_Init(INST_UART0, &uart0_State, &uart0_InitConfig0);
LPUART_DRV_InstallRxCallback(INST_UART0, uart_callback, NULL);
debug_log_print(LL_DEV, MOD_UART, "Init OK\n");
}
//Send data calling from TX Task
void uart_send_enc_can_frame(uint32_t can_id, uint8_t* can_data, uint8_t can_data_len)
{
uart_enc_can_frame_t enc_can_frame;
memset(&enc_can_frame, 0, sizeof(enc_can_frame));
enc_can_frame.header.sig_0 = UART_HEADER_SIG_0;
enc_can_frame.header.sig_1 = UART_HEADER_SIG_1;
enc_can_frame.header.frame_type = UART_FRAME_TYPE_ENCAPSULATED_CAN_MSG;
enc_can_frame.header.payload_len = sizeof(enc_can_frame.enc_can_payload);
enc_can_frame.enc_can_payload.can_frame_id = can_id;
enc_can_frame.enc_can_payload.can_frame_len = can_data_len;
for(uint8_t i=0; i<can_data_len; i++)
enc_can_frame.enc_can_payload.can_data[i] = can_data[i];
enc_can_frame.footer.crc16 = CRC16_DNP_CalcChecksum(&enc_can_frame.enc_can_payload, sizeof enc_can_frame.enc_can_payload);
if(OS_MUTEX_LockTimed(&g_uart_tx_mutex, UART_TX_MUTEX_TO) == 0){
debug_log_print(LL_ERR, MOD_UART, "TX Enc CAN frame blocked\n");
return;
}
if(LPUART_DRV_SendDataBlocking(INST_UART0, (uint8_t*)&enc_can_frame, sizeof enc_can_frame, UART_TX_TIMEOUT) != STATUS_SUCCESS){
debug_log_print(LL_ERR, MOD_UART, "TX Low Level error\n");
}
OS_MUTEX_Unlock(&g_uart_tx_mutex);
}
//RX Task
static void uart_rx_task()
{
rb_init(&g_uart_rx_rb, g_uart_rx_rb_data, UART_RX_RB_SIZE);
status_t rx_status = STATUS_SUCCESS;
do{
OS_Delay(10);
rx_status = LPUART_DRV_ReceiveData(INST_UART0, g_uart_rx_buf, 1);
}while(rx_status != STATUS_SUCCESS);
debug_log_print(LL_DEV, MOD_UART, "RX Receiving Started\n");
while(1)
{
uart_set_diagnosis_mode();
uint8_t data = 0;
uint32_t bytes_remaining = 0;
status_t s = LPUART_DRV_GetReceiveStatus(INST_UART0, &bytes_remaining);
if(s != STATUS_BUSY){
debug_log_print(LL_ERR, MOD_UART, "RX Failed with code %i\n", s);
s = LPUART_DRV_ReceiveData(INST_UART0, g_uart_rx_buf, 1);
debug_log_print(LL_INFO, MOD_UART, "RX Restarted with code %i\n", s);
}
if(OS_MAILBOX_GetTimed1(&g_uart_rx_mb, (char*) &data, UART_RX_IDLE_TO) != 0)
continue; //BUGFIX for UART RX failing: Restarting RX after being idle too long
/* if (uart_receive_flag == 1)
{
uart_receive_flag = 0;
memcpy(&data, &g_uart_rx_buf[0], 1);
LPUART_DRV_SetRxBuffer(INST_UART0, g_uart_rx_buf, 1);
}
else
{
OS_Delay(1);
continue;
}*/
if(rb_bytes_free(&g_uart_rx_rb) == 0)
rb_pop(&g_uart_rx_rb, 1);
rb_push(&g_uart_rx_rb, &data, 1);
uart_header_t header;
int16_t frame_offset = uart_find_frame(&g_uart_rx_rb, &header);
if(frame_offset == -1)
continue;
if(frame_offset > 0){
rb_pop(&g_uart_rx_rb, frame_offset); //drop everythin before the found frame
debug_log_print(LL_DEV, MOD_UART, "RX Dropped %i bytes before valid frame\n", frame_offset);
}
switch(header.frame_type)
{
case UART_FRAME_TYPE_ENCAPSULATED_CAN_MSG:
{
uart_enc_can_frame_t enc_can_frame;
if(uart_extract_enc_can_frame(&g_uart_rx_rb, &enc_can_frame) == true)
{
if(enc_can_frame.enc_can_payload.can_frame_id == 0x667 &&
enc_can_frame.enc_can_payload.can_frame_len == 2 &&
enc_can_frame.enc_can_payload.can_data[0] == 0xFF &&
enc_can_frame.enc_can_payload.can_data[1] == 0x00)
{
debug_log_print(LL_INFO, MOD_UART, "Reset to Bootloader via UART triggered \n");
SystemSoftwareReset();
}
else
{
uart_rx_unpack_msg(&enc_can_frame);
}
}
//TODO: else?
}
break;
case UART_FRAME_TYPE_UDS_DIAGNOSIS:
{
static uart_uds_frame_t enc_uds_frame;
g_uart_current_mode = UART_DIAGNOSIS_MODE;
OS_Delay(100);
if (g_uart_comm_status == UART_COMM_RUNNING)
{
debug_log_print(LL_DEV, MOD_GPIO, "UDS diagnosis started, UART tx Communication stopped \n");
g_uart_comm_status = UART_COMM_SUSPENDED;
OS_TASK_Suspend(&g_uart_tx_tcb);
}
if(uart_extract_uds_frame(&g_uart_rx_rb, &enc_uds_frame) == true)
{
OS_QUEUE_Put(&g_uart_uds_queue, enc_uds_frame.uds_data, enc_uds_frame.header.payload_len);
/* listening to TESTER PRESENT message from CMx tool */
if(enc_uds_frame.uds_data[0] == UDS_SERVICE_TESTER_PRESENT && enc_uds_frame.uds_data[1] == 0)
{
g_uart_testerpresent_start_time = OS_TIME_GetTicks();
}
}
}
break;
default:
debug_log_print(LL_ERR, MOD_UART, "RX Unknown Frame Type Detected: %i\n", header.frame_type);
break;
}
}
}
Best Regards,
Sai