When lin is used as the Master and the LIN host scheduling table has multiple ID, when receiving and sending are processed at the same time in the LIN interrupt, ID data loss and garbled code will occur.The following is my source code, please take a look at it for me,thanks
this is lin callback function:
lin_callback_t lin_rx_tx_handle_callback(uint32_t instance, lin_state_t * lin1_State)
{
lin_callback_t callbackCurrent;
callbackCurrent = lin1_State->Callback;
uint8_t lin_id_index = 0;//lin number index
switch (lin1_State->currentEventId)
{
case LIN_PID_OK:
/* Set timeout */
LIN_DRV_SetTimeoutCounter(INST_LIN1, TIMEOUT);
for(lin_id_index = 0; lin_id_index < MASTER_FRAME_COUNT; lin_id_index++)
{
if(g_lin_master_schedule_list_config[lin_id_index].ID == lin1_State->currentId)
{ /* If PID is FRAME_TX_RSP, salve node will receive data from master node */
if(g_lin_master_schedule_list_config[lin_id_index].Type == FRAME_TX_RSP)
{
/* Call to Send Frame DATA Function */
LIN_DRV_SendFrameData(INST_LIN1, g_lin_master_Pdu_Matrix[lin_id_index].buf, sizeof(g_lin_master_Pdu_Matrix[lin_id_index].buf));
break;
}
else if(g_lin_master_schedule_list_config[lin_id_index].Type == FRAME_RX_RSP )
{
/* Call to Receive Frame DATA Function */
//current_id_sn = lin_id_index;
//receive_new_frame_flag = 1;
LIN_DRV_ReceiveFrameData(INST_LIN1, g_lin_master_Pdu_Matrix[lin_id_index].buf, sizeof( g_lin_master_Pdu_Matrix[lin_id_index].buf));
break;
}
else
{
}
}
}
break;
/* If PID is FRAME_GO_TO_SLEEP, salve node will go to sleep mode */
case LIN_PID_ERROR:
/* Go to idle mode */
LIN_DRV_GoToSleepMode(INST_LIN1);
break;
case LIN_TX_COMPLETED:
case LIN_RX_COMPLETED:
/* Go to idle mode */
LIN_DRV_GotoIdleState(INST_LIN1);
break;
case LIN_CHECKSUM_ERROR:
case LIN_READBACK_ERROR:
case LIN_FRAME_ERROR:
case LIN_RECV_BREAK_FIELD_OK:
/* Set timeout */
LIN_DRV_SetTimeoutCounter(INST_LIN1, TIMEOUT);
break;
case LIN_WAKEUP_SIGNAL:
/* Set wakeup signal flag */
// wakeupSignalFlag = true;
break;
case LIN_SYNC_ERROR:
case LIN_BAUDRATE_ADJUSTED:
case LIN_NO_EVENT:
case LIN_SYNC_OK:
default:
/* do nothing */
break;
}
return callbackCurrent;
}
How to increase the frame slot and frame duration, or how to optimize my program?
Hi,
try
#define TIME_BASE 5
const struct_lin_master_config g_lin_master_schedule_list_config[5] =
{
{0x14,8,FRAME_TX_RSP,2},
{0x21,8,FRAME_TX_RSP,6},
{0x3A,8,FRAME_RX_RSP,10},
{0x0C,8,FRAME_RX_RSP,14},
{0x02,8,FRAME_RX_RSP,18},
};
I cannot test the project. It gives me some PE errors.
BR, Petr
I looked for a problem later. The reason why there is a frame error in my code is that the LIN configuration table I configured is inconsistent with the actual received byte length, and another reason is that the frame gap is set too small, but now I have extended the frame gap to 50ms to send a frame request, but occasionally there are a few error frames, but I have no problem with the frame gap 10ms on other MCU platforms.
Hi,
and do you also set proper byte length when starting to receive response according schedule list? You have
LIN_DRV_ReceiveFrameData(INST_LIN1, g_lin_master_Pdu_Matrix[lin_id_index].buf, sizeof( g_lin_master_Pdu_Matrix[lin_id_index].buf));
How this correspond to different byte counts in a schedule list?
BR, Petr
Yes, I corrected this error, and now the schedule set can be received and sent, but I found that there will still be a lot of irrelevant error frames, so I changed the frame gap to 40ms, and there will also be one or two error frames. But I think the frame gap is too long, is there any optimization method?
Hi,
try to set higher priority for LPUART interrupt.
Try to rewrite its callback to have faster header response, for example using lin_master_sn and lin_current_ID you updated when header is send, could be ...
case LIN_PID_OK:
/* Set timeout */
LIN_DRV_SetTimeoutCounter(INST_LIN1, TIMEOUT);
//if(lin_current_ID == lin1_State->currentId)
{ /* If PID is FRAME_TX_RSP, salve node will receive data from master node */
if(g_lin_master_schedule_list_config[lin_master_sn].Type == FRAME_RX_RSP )
{
/* Call to Receive Frame DATA Function */
//current_id_sn = lin_id_index;
//receive_new_frame_flag = 1;
LIN_DRV_ReceiveFrameData(INST_LIN1, g_lin_master_Pdu_Matrix[lin_master_sn].buf, g_lin_master_schedule_list_config[lin_master_sn].len);
break;
}
else if(g_lin_master_schedule_list_config[lin_master_sn].Type == FRAME_TX_RSP)
{
/* Call to Send Frame DATA Function */
LIN_DRV_SendFrameData(INST_LIN1, g_lin_master_Pdu_Matrix[lin_master_sn].buf, g_lin_master_schedule_list_config[lin_master_sn].len);
break;
}
else
{
}
}
break;
BR, Petr
I find that it's okay to just send a frame, but there will be a problem if you accept a frame to join.
I'm using SDK_S32K1XX_15,I dong't have any errors,In addition, I changed my frame gap, but there was a loss of frames
这是我的报文
Hi,
does the issue also happen if you extend time base or increase frame slot duration?
Also when searching for frame ID in lin_rx_tx_handle_callback is the receive (LIN_DRV_ReceiveFrameData) started before slave sends starts sending data?
BR, Petr