S32K144: CAN0 and CAN1 communication lost after some packet

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

S32K144: CAN0 and CAN1 communication lost after some packet

跳至解决方案
1,889 次查看
Jimmybai
Contributor II

I use one S32K144 EVB's CAN0 and CAN1 to complete CAN's Tx and Rx. The code is based Demo_CAN_S32K144 project. CAN0 send a 8 bytes frame to CAN1, CAN1 receive the frame and verify if this frame is desired packet. If yes, change CAN-ID and send same frame to CAN0. When CAN0 receiver CAN1's reply frame, verify to see if it is the desired frame. If yes, CAN0 send next frame to CAN1, CAN1 receive the frame and verify it......

At first, the code process soomthly. But CAN0/CAN1 tx/rx run about send 5000+ frame, the CAN0 send a frame without a data content. The communication procedure stop. The can device USBCANFD show the last frame is a remote frame, but I don't send remote frame in code. I don't know it is a remote frame or a false frame without frame content.  I attach the last data's waveform and USBCAN device's data log. Thanks.

Jimmybai_0-1736850821479.pngJimmybai_1-1736851134029.png

 

0 项奖励
回复
1 解答
1,791 次查看
Jimmybai
Contributor II
Thank you. My version is S32DS for ARM 2.2. Just now I found the root cause and resolve method in website. The Rx_buffCfg/Tx_buffCfg structure can't be set as a local variable in CAN0_Init()/CAN1_Init(), they should be set as gloabl variable. For detail, please find chapter 3.3 in the link https://blog.csdn.net/tao475824827/article/details/106757092

在原帖中查看解决方案

0 项奖励
回复
4 回复数
1,830 次查看
Jimmybai
Contributor II

I runn the code and find in CAN0_Callback_Func()/CAN1_Callback_Func() functions,  the CAN_Receive() always return STATUS_BUSY, not STATUS_SUCCESS. Maybe that's the root cause. But I don't know why this condition happens, can anyone give me some explaination? Thanks.

0 项奖励
回复
1,815 次查看
PetrS
NXP TechSupport
NXP TechSupport

Hi,

you did not specify SDK version you have.  Note there was some driver fixes over the time, so be sure to have latest one.

BR, Petr

0 项奖励
回复
1,792 次查看
Jimmybai
Contributor II
Thank you. My version is S32DS for ARM 2.2. Just now I found the root cause and resolve method in website. The Rx_buffCfg/Tx_buffCfg structure can't be set as a local variable in CAN0_Init()/CAN1_Init(), they should be set as gloabl variable. For detail, please find chapter 3.3 in the link https://blog.csdn.net/tao475824827/article/details/106757092
0 项奖励
回复
1,863 次查看
Jimmybai
Contributor II

I attach the main() function code below:

#define LED1(x)  PINS_DRV_WritePin(PTA,1,!x);//RED
#define LED2(x)  PINS_DRV_WritePin(PTB,8,!x);//GREEN
#define LED3(x)  PINS_DRV_WritePin(PTB,9,!x);//BLUE
 
can_message_t canX_Tx_msg[10] = {
{.cs = 0U, .id = 0x06, .data = "01234567", .length = 8},
{.cs = 0U, .id = 0x06, .data = "12345678", .length = 8},
{.cs = 0U, .id = 0x06, .data = "23456789", .length = 8},
{.cs = 0U, .id = 0x06, .data = "34567890", .length = 8},
{.cs = 0U, .id = 0x06, .data = "45678901", .length = 8},
{.cs = 0U, .id = 0x06, .data = "56789012", .length = 8},
{.cs = 0U, .id = 0x06, .data = "67890123", .length = 8},
{.cs = 0U, .id = 0x06, .data = "78901234", .length = 8},
{.cs = 0U, .id = 0x06, .data = "89012345", .length = 8},
{.cs = 0U, .id = 0x06, .data = "90123456", .length = 8},
 };
 
 
#define Rx_Filter  0x0
char IRQ_CAN0_RX = 0;
char IRQ_CAN1_RX = 0;
char IRQ_CAN2_RX = 0;
char IRQ_CAN0_RX_SUCC = 0;
char IRQ_CAN1_RX_SUCC = 0;
char IRQ_CAN2_RX_SUCC = 0;
 
uint32_t can0_tx_total_cnt = 0;
uint32_t can0_rx_total_cnt = 0;
uint32_t can0_rx_succ_cnt = 0;
uint32_t can0_rx_fail_cnt = 0;
 
uint32_t can1_tx_total_cnt = 0;
uint32_t can1_rx_total_cnt = 0;
uint32_t can1_rx_succ_cnt = 0;
uint32_t can1_rx_fail_cnt = 0;
can_message_t recvMsg_CAN0;
can_message_t recvMsg_CAN1;
can_message_t recvMsg_CAN2;
 
#define RX_MAILBOX_CAN0  (0UL)
#define TX_MAILBOX_CAN0  (1UL)
 
#define RX_MAILBOX_CAN1  (2UL)
#define TX_MAILBOX_CAN1  (3UL)
 
#define RX_MAILBOX_CAN2  (4UL)
#define TX_MAILBOX_CAN2  (5UL)
 
 
void can_normal_en(int canSn)
{
if(canSn == 0)
{
PINS_DRV_ClearPins(PTD, 1 << 9);
}
 
if(canSn == 1)
{
PINS_DRV_ClearPins(PTB, 1 << 4);
}
 
if(canSn == 2)
{
PINS_DRV_ClearPins(PTC, 1 << 11);
}
}
 
void can_silent_en(int canSn)
{
if(canSn == 0)
{
PINS_DRV_SetPins(PTD, 1 << 9);
}
 
if(canSn == 1)
{
PINS_DRV_SetPins(PTB, 1 << 4);
}
 
if(canSn == 2)
{
PINS_DRV_SetPins(PTC, 1 << 11);
}
}
 
 
/*CAN0回调函数*/
void CAN0_Callback_Func (uint32_t instance,can_event_t event,uint32_t buffIdx,void *flexcanState)
{
(void)flexcanState; //此处防止警报
(void)instance;
(void)buffIdx;
if(CAN_Receive(&can_pal0_instance, RX_MAILBOX_CAN0, &recvMsg_CAN0) == STATUS_SUCCESS)//接收报文并重新注册回调函数
IRQ_CAN0_RX_SUCC = 1;
else
IRQ_CAN0_RX_SUCC = 0;
 
switch(event) //回调事件
{
case CAN_EVENT_RX_COMPLETE: //接收完成事件
IRQ_CAN0_RX = 1;
break;
case CAN_EVENT_TX_COMPLETE: //发送完成事件
break;
default:
break;
}
}
 
void CAN1_Callback_Func (uint32_t instance,can_event_t event,uint32_t buffIdx,void *flexcanState)
{
(void)flexcanState;
(void)instance;
(void)buffIdx;
if(CAN_Receive(&can_pal1_instance, RX_MAILBOX_CAN1, &recvMsg_CAN1) == STATUS_SUCCESS)//接收报文并重新注册回调函数
IRQ_CAN1_RX_SUCC = 1;
else
IRQ_CAN1_RX_SUCC = 0;
 
switch(event)
{
case CAN_EVENT_RX_COMPLETE:
IRQ_CAN1_RX = 1;
break;
case CAN_EVENT_TX_COMPLETE:
break;
default:
break;
}
}
 
 
void CAN2_Callback_Func (uint32_t instance,can_event_t event,uint32_t buffIdx,void *flexcanState)
{
(void)flexcanState;
(void)instance;
(void)buffIdx;
if(CAN_Receive(&can_pal2_instance, RX_MAILBOX_CAN2, &recvMsg_CAN2) == STATUS_SUCCESS)//接收报文并重新注册回调函数
IRQ_CAN2_RX_SUCC = 1;
else
IRQ_CAN2_RX_SUCC = 0;
switch(event)
{
case CAN_EVENT_RX_COMPLETE:
IRQ_CAN2_RX = 1;
break;
case CAN_EVENT_TX_COMPLETE:
break;
default:
break;
}
}
 
 
void CAN0_Init(void)
{
CAN_Init(&can_pal0_instance, &can_pal0_Config0);
can_buff_config_t Rx_buffCfg =  {
      .enableFD = false,
      .enableBRS = false,
      .fdPadding = 0U,
      .idType = CAN_MSG_ID_STD,
      .isRemote = false
};
 
can_buff_config_t Tx_buffCfg =  {
      .enableFD = false,
      .enableBRS = false,
      .fdPadding = 0U,
      .idType = CAN_MSG_ID_STD,
      .isRemote = false
};
CAN_ConfigRxBuff(&can_pal0_instance, RX_MAILBOX_CAN0, &Rx_buffCfg, Rx_Filter); //注册接收配置和MSGID过滤器(如过滤器配置为0x1,则只接受msgid 0x1发来的报文)
CAN_ConfigTxBuff(&can_pal0_instance, TX_MAILBOX_CAN0, &Tx_buffCfg); //配置发送
/*设置MSGID的掩码,掩码粗略可以理解为对11bit MSGID地址的过滤
如果某bit位需要过滤设置为1,不过滤设置为0,例如掩码设置为0x7ff则过滤全部标准id,如果设置为0x7fe,这只能接受0x01的报文(不存在0x0的地址)*/
CAN_SetRxFilter(&can_pal0_instance,CAN_MSG_ID_STD,RX_MAILBOX_CAN0,0); //设置MSGID掩码,
CAN_InstallEventCallback(&can_pal0_instance,&CAN0_Callback_Func,(void*)0); //注册回调函数
CAN_Receive(&can_pal0_instance, RX_MAILBOX_CAN0, &recvMsg_CAN0); //*****重点****此函数不只有接收作用 还有续订回调函数的作用.
}
 
 
void CAN1_Init(void)
{
CAN_Init(&can_pal1_instance, &can_pal1_Config0);
can_buff_config_t Rx_buffCfg =  {
      .enableFD = false,
      .enableBRS = false,
      .fdPadding = 0U,
      .idType = CAN_MSG_ID_STD,
      .isRemote = false
};
 
can_buff_config_t Tx_buffCfg =  {
      .enableFD = false,
      .enableBRS = false,
      .fdPadding = 0U,
      .idType = CAN_MSG_ID_STD,
      .isRemote = false
};
CAN_ConfigRxBuff(&can_pal1_instance, RX_MAILBOX_CAN1, &Rx_buffCfg, Rx_Filter);
CAN_ConfigTxBuff(&can_pal1_instance, TX_MAILBOX_CAN1, &Tx_buffCfg);
CAN_SetRxFilter(&can_pal1_instance,CAN_MSG_ID_STD,RX_MAILBOX_CAN1,0);
CAN_InstallEventCallback(&can_pal1_instance,&CAN1_Callback_Func,(void*)0);
CAN_Receive(&can_pal1_instance, RX_MAILBOX_CAN1, &recvMsg_CAN1);
}
 
void CAN2_Init(void)
{
CAN_Init(&can_pal2_instance, &can_pal2_Config0);
can_buff_config_t Rx_buffCfg =  {
      .enableFD = false,
      .enableBRS = false,
      .fdPadding = 0U,
      .idType = CAN_MSG_ID_STD,
      .isRemote = false
};
 
can_buff_config_t Tx_buffCfg =  {
      .enableFD = false,
      .enableBRS = false,
      .fdPadding = 0U,
      .idType = CAN_MSG_ID_STD,
      .isRemote = false
};
CAN_ConfigRxBuff(&can_pal2_instance, RX_MAILBOX_CAN2, &Rx_buffCfg, Rx_Filter);
CAN_ConfigTxBuff(&can_pal2_instance, TX_MAILBOX_CAN2, &Tx_buffCfg);
CAN_SetRxFilter(&can_pal2_instance,CAN_MSG_ID_STD,RX_MAILBOX_CAN2,0);
CAN_InstallEventCallback(&can_pal2_instance,&CAN2_Callback_Func,(void*)0);
CAN_Receive(&can_pal2_instance, RX_MAILBOX_CAN2, &recvMsg_CAN2);
}
 
 
int main(void)
{
int MCU_Freq;
int sendGap = 200;
/*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/
#ifdef PEX_RTOS_INIT
    PEX_RTOS_INIT();                   /* Initialization of the selected RTOS. Macro is defined by the RTOS component. */
#endif
  /*** End of Processor Expert internal initialization.                    ***/
 
CLOCK_SYS_Init(g_clockManConfigsArr, CLOCK_MANAGER_CONFIG_CNT,g_clockManCallbacksArr, CLOCK_MANAGER_CALLBACK_CNT);
CLOCK_SYS_UpdateConfiguration(0U, CLOCK_MANAGER_POLICY_AGREEMENT);
MCU_Freq = delay_init();//初始化delay函数
PINS_DRV_Init(NUM_OF_CONFIGURED_PINS, g_pin_mux_InitConfigArr); //初始化IO
 
CAN0_Init();
CAN1_Init();
CAN2_Init();
 
FLEXIO_UART_init(); /*! Initialize Timer 0, Shifter 0 to emulate
* an UART transmitter instance, using:
* FXIO_D2 to generate baud-rate (output disabled).
* FXIO_D1 as output shifter pin.
*/
 
FLEXIO_100KHz_PWM_init(50); /*! Initialize Timer 1 and FXIO_D0 to emulate PWM. */
FLEXIO_UART("CAN_TX_RX_Demo. MCU Run Frequency is %d Mhz \r\n",MCU_Freq);
 
can_normal_en(0);
can_normal_en(1);
can_normal_en(2);
CAN_Send(&can_pal0_instance, TX_MAILBOX_CAN0, &canX_Tx_msg[can0_tx_total_cnt%10]);
delay_us(sendGap);
    while(1)
    {
if (IRQ_CAN0_RX)//如果接收到CAN报文会通过串口打印出来
//if(1)
{
IRQ_CAN0_RX = 0;
if(IRQ_CAN0_RX_SUCC)
//if(1)
{
if(strcmp((char *)recvMsg_CAN0.data, (char *)canX_Tx_msg[can0_tx_total_cnt%10].data) == 0)
//if(1)
{
delay_us(sendGap);
IRQ_CAN0_RX_SUCC = 0;
can0_tx_total_cnt++;
CAN_Send(&can_pal0_instance, TX_MAILBOX_CAN0, &canX_Tx_msg[can0_tx_total_cnt%10]);
delay_us(sendGap);
}
else
can0_rx_fail_cnt++;
}
else
can0_rx_fail_cnt++;
 
if(can0_tx_total_cnt%1000 == 0)
{
FLEXIO_UART("Transmit sendGap=%dus,TxCnt=%d,LastData=<%s>\r\n",sendGap,can0_tx_total_cnt,canX_Tx_msg[can0_tx_total_cnt%10].data);
}
}
 
if (IRQ_CAN1_RX)//如果接收到CAN报文会通过串口打印出来
{
IRQ_CAN1_RX = 0;
can1_rx_total_cnt++;
if(IRQ_CAN1_RX_SUCC)
{
if(strcmp((char *)recvMsg_CAN1.data, (char *)canX_Tx_msg[can0_tx_total_cnt%10].data) == 0)
{
delay_us(sendGap);
IRQ_CAN1_RX_SUCC = 0;
can1_rx_succ_cnt++;
recvMsg_CAN1.id = 0x08;
CAN_Send(&can_pal1_instance, TX_MAILBOX_CAN1, &recvMsg_CAN1);
delay_us(sendGap);
}
else
can1_rx_fail_cnt++;
}
else
can1_rx_fail_cnt++;
 
if(can1_rx_total_cnt%1000 == 0)
{
FLEXIO_UART("Receive sendGap=%dus,RxCnt=%d,FailCnt=%d,LastData=<%s>\r\n",sendGap,can1_rx_total_cnt,can1_rx_fail_cnt,recvMsg_CAN1.data);
}
}
    }
  /*** Don't write any code pass this line, or it will be deleted during code generation. ***/
  /*** RTOS startup code. Macro PEX_RTOS_START is defined by the RTOS component. DON'T MODIFY THIS CODE!!! ***/
  #ifdef PEX_RTOS_START
    PEX_RTOS_START();                  /* Startup of the selected RTOS. Macro is defined by the RTOS component. */
  #endif
  /*** End of RTOS startup code.  ***/
  /*** Processor Expert end of main routine. DON'T MODIFY THIS CODE!!! ***/
  for(;;) {
    if(exit_code != 0) {
      break;
    }
  }
  return exit_code;
  /*** Processor Expert end of main routine. DON'T WRITE CODE BELOW!!! ***/
} /*** End of main routine. DO NOT MODIFY THIS TEXT!!! ***/

 

标记 (1)
0 项奖励
回复