cancel
Showing results for 
Search instead for 
Did you mean: 

issue of ThreadX and FDCAN function

dqsh06
Associate III

Hello @D.Botelho @mƎALLEm 

I had an issue of ThreadX and FDCAN transmit as below.

I use the stm32g474 and config a threadx and fdcan with stm32cubemx, so far it works well.

but when i add some fdcan transmit code, it comes strangely.

the code as below

void appThread2(ULONG thread_input)
{
  while(1)
  {
    if(fdcan1_RXFlag == 1)
    {
      fdcan1_RXFlag = 0; // Clear the receive flag
      for(int i = 0; i < 8; i++)
      {
        fdcan1TxData[i] = fdcan1RxData[i]+1; // Copy received data to transmit buffer
      }

      my_FDCAN1_Transmit(fdcan1TxData); // Echo back the received data
      printf("FDCAN1 Received data: ");
      for (int i = 0; i < 8; i++)
      {
        printf("%02X ", fdcan1RxData[i]);
      }
      printf("\r\n");
    }

    // // 发送 0x12
    fdcan1TxHeader.Identifier=0x012;
    fdcan1TxData[0] = (dis_sensor_data1.dis1 >> 0) & 0xff;
    fdcan1TxData[1] = (dis_sensor_data1.dis1 >> 8) & 0xff;
    fdcan1TxData[2] = (dis_sensor_data1.dis2 >> 0) & 0xff;
    fdcan1TxData[3] = (dis_sensor_data1.dis2 >> 8) & 0xff;
    fdcan1TxData[4] = (dis_sensor_data1.dis3 >> 0) & 0xff;
    fdcan1TxData[5] = (dis_sensor_data1.dis3 >> 8) & 0xff;
    fdcan1TxData[6] = (dis_sensor_data1.dis4 >> 0) & 0xff;
    fdcan1TxData[7] = (dis_sensor_data1.dis4 >> 8) & 0xff;
    my_FDCAN1_Transmit(fdcan1TxData);

    // // 发送 0x13
    fdcan1TxHeader.Identifier=0x013;
    fdcan1TxData[0] = (dis_sensor_data2.dis1 >> 0) & 0xff;
    fdcan1TxData[1] = (dis_sensor_data2.dis1 >> 8) & 0xff;
    fdcan1TxData[2] = (dis_sensor_data2.dis2 >> 0) & 0xff;
    fdcan1TxData[3] = (dis_sensor_data2.dis2 >> 8) & 0xff;
    fdcan1TxData[4] = (dis_sensor_data2.dis3 >> 0) & 0xff;
    fdcan1TxData[5] = (dis_sensor_data2.dis3 >> 8) & 0xff;
    fdcan1TxData[6] = (dis_sensor_data2.dis4 >> 0) & 0xff;
    fdcan1TxData[7] = (dis_sensor_data2.dis4 >> 8) & 0xff;
    my_FDCAN1_Transmit(fdcan1TxData);

    // // 发送 0x14
    fdcan1TxHeader.Identifier=0x014;
    fdcan1TxData[0] = sbusHandle.isExist;   // 遥控器工作状态
    fdcan1TxData[1] = sys_status;           // 系统状态
    fdcan1TxData[2] = (encoder_data1.counter >> 0) & 0xff;
    fdcan1TxData[3] = (encoder_data1.counter >> 8) & 0xff;
    fdcan1TxData[4] = (encoder_data2.counter >> 0) & 0xff;
    fdcan1TxData[5] = (encoder_data2.counter >> 8) & 0xff;
    fdcan1TxData[6] = encoder_data1.direction;
    fdcan1TxData[7] = encoder_data1.direction;
    my_FDCAN1_Transmit(fdcan1TxData);

    // 发送 0x15
    fdcan1TxHeader.Identifier=0x015;
    fdcan1TxData[0] = RS485_RXData[0]+0x0A;
    fdcan1TxData[1] = RS485_RXData[1];         
    fdcan1TxData[2] = RS485_RXData[2];
    fdcan1TxData[3] = RS485_RXData[3];
    fdcan1TxData[4] = RS485_RXData[4];
    fdcan1TxData[5] = RS485_RXData[5];
    fdcan1TxData[6] = RS485_RXData[6];
    fdcan1TxData[7] = RS485_RXData[7];
    my_FDCAN1_Transmit(fdcan1TxData);

    tx_thread_sleep(20); // Sleep for 20 ticks
  }
}

I use a thread to send can message with a peroid of 20ms.

the CAN message ID is 0x12, 0x13, 0x14, 0x15.

as the code above,  when i compiled the code and programming to mcu, just after 1s, the system stack and Error_Handler() called. when I comment out 0x15 CAN transimt, only transmit 0x12, 0x13, 0x14, it works well. 

why?

I have increased the thread_stack of appThread2, but it seems the issue still exists.

how should i do to fix this issue?

 

Thanks,

dqsh06

5 REPLIES 5
Karl Yamashita
Principal

You forgot to show code for my_FDCAN1_Transmit

CANable V3 firmware | CAN-X CAN bus analyzer software for CANable V3 |
TimerCallback tutorial! | UART and DMA Idle with multiple UART instances tutorial!

If you find my solution useful, please click the Accept as Solution so others see the solution.

@Karl Yamashita ,

OK, the code of my_FDCAN1_Transmit is as below:

void my_FDCAN1_Transmit(uint8_t *TxData)
{
    // 发送数据
    if (HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &fdcan1TxHeader, TxData) != HAL_OK)
    {
        // usb_printf("HAL_FDCAN_AddMessageToTxFifoQ failed\r\n");
        printf("HAL_FDCAN_AddMessageToTxFifoQ failed\r\n");
        Error_Handler();
    }
}

and just as your minds, the function 

HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &fdcan1TxHeader, TxData)
returns HAL_ERROR when call my_FDCAN1_Transmit() for ID 0x15.
because i got a printf of 
"HAL_FDCAN_AddMessageToTxFifoQ failed"
and Error_Handler() called.

 why call HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &fdcan1TxHeader, TxData) failed for ID 0x15?

 

Thanks.

Because you're trying to send 5 CAN messages (your reply message and 4 other CAN messages) back to back and your Tx only has 3 mailboxes. The mailboxes are getting full quickly, so you get HAL_ERROR.

Create a queue buffer to hold your CAN messages and when you call HAL_FDCAN_AddMessageToTxFifoQ and it returns HAL_OK, then you increment your queue pointer. When you get HAL_FDCAN_TxFifoEmptyCallback, you can send the next message in the queue. To get HAL_FDCAN_TxFifoEmptyCallback, you need to activate the notification

if (HAL_FDCAN_ActivateNotification(msg->hfdcan, FDCAN_FLAG_RX_FIFO0_NEW_MESSAGE | FDCAN_IT_TX_FIFO_EMPTY, 0) != HAL_OK)
	{
		Error_Handler();
	}

 

CANable V3 firmware | CAN-X CAN bus analyzer software for CANable V3 |
TimerCallback tutorial! | UART and DMA Idle with multiple UART instances tutorial!

If you find my solution useful, please click the Accept as Solution so others see the solution.

Hello @Karl Yamashita ,

Thanks for your reply, but it is too difficult for me, can i just add a delay after 3 transmit to wait the transmit mailbox has space?  as below

    // 发送 0x12
    fdcan1TxHeader.Identifier=0x012;
    fdcan1TxData[0] = (dis_sensor_data1.dis1 >> 0) & 0xff;
    fdcan1TxData[1] = (dis_sensor_data1.dis1 >> 8) & 0xff;
    fdcan1TxData[2] = (dis_sensor_data1.dis2 >> 0) & 0xff;
    fdcan1TxData[3] = (dis_sensor_data1.dis2 >> 8) & 0xff;
    fdcan1TxData[4] = (dis_sensor_data1.dis3 >> 0) & 0xff;
    fdcan1TxData[5] = (dis_sensor_data1.dis3 >> 8) & 0xff;
    fdcan1TxData[6] = (dis_sensor_data1.dis4 >> 0) & 0xff;
    fdcan1TxData[7] = (dis_sensor_data1.dis4 >> 8) & 0xff;
    my_FDCAN1_Transmit(fdcan1TxData);
    
    // 发送 0x13
    fdcan1TxHeader.Identifier=0x013;
    fdcan1TxData[0] = (dis_sensor_data2.dis1 >> 0) & 0xff;
    fdcan1TxData[1] = (dis_sensor_data2.dis1 >> 8) & 0xff;
    fdcan1TxData[2] = (dis_sensor_data2.dis2 >> 0) & 0xff;
    fdcan1TxData[3] = (dis_sensor_data2.dis2 >> 8) & 0xff;
    fdcan1TxData[4] = (dis_sensor_data2.dis3 >> 0) & 0xff;
    fdcan1TxData[5] = (dis_sensor_data2.dis3 >> 8) & 0xff;
    fdcan1TxData[6] = (dis_sensor_data2.dis4 >> 0) & 0xff;
    fdcan1TxData[7] = (dis_sensor_data2.dis4 >> 8) & 0xff;
    my_FDCAN1_Transmit(fdcan1TxData);
    tx_thread_sleep(1);

    // 发送 0x14
    fdcan1TxHeader.Identifier=0x014;
    fdcan1TxData[0] = sbusHandle.isExist;   // 遥控器工作状态
    fdcan1TxData[1] = sys_status;           // 系统状态
    fdcan1TxData[2] = (encoder_data1.counter >> 0) & 0xff;
    fdcan1TxData[3] = (encoder_data1.counter >> 8) & 0xff;
    fdcan1TxData[4] = (encoder_data2.counter >> 0) & 0xff;
    fdcan1TxData[5] = (encoder_data2.counter >> 8) & 0xff;
    fdcan1TxData[6] = encoder_data1.direction;
    fdcan1TxData[7] = encoder_data2.direction;
    my_FDCAN1_Transmit(fdcan1TxData);

    // 发送 0x15
    fdcan1TxHeader.Identifier=0x015;
    fdcan1TxData[0] = RS485_RXData[0]+0x0A;
    fdcan1TxData[1] = RS485_RXData[1];         
    fdcan1TxData[2] = RS485_RXData[2];
    fdcan1TxData[3] = RS485_RXData[3];
    fdcan1TxData[4] = RS485_RXData[4];
    fdcan1TxData[5] = RS485_RXData[5];
    fdcan1TxData[6] = RS485_RXData[6];
    fdcan1TxData[7] = RS485_RXData[7];
    my_FDCAN1_Transmit(fdcan1TxData);
    tx_thread_sleep(20);

How do you think just add a tx_thread_sleep(1) to wait?

 

Thanks.

Saket_Om
ST Employee

Hello @dqsh06 

Please refer to example below:

STM32CubeG4/Projects/STM32G474E-EVAL/Examples/FDCAN/FDCAN_Com_IT at master · STMicroelectronics/STM32CubeG4 · GitHub

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Saket_Om