Flexcan loopback的问题

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Flexcan loopback的问题

3,198 Views
colinluan
Contributor III

Hi, @jeremyzhou 

我这两天在调试Flexcan,由于目前只有一块开发板,所以先用loopback模式在调试,目前出现了一个比较奇怪的现象:

1、我在发送时,在调用完FLEXCAN_TransferSendNonBlocking函数后使用xEventGroupWaitBits等待中断中发送完成的事件来实现同步

    handle->rxXfer.mbIdx = RX_MESSAGE_BUFFER_NUM;
    handle->rxXfer.frame = &handle->rxFrame;
    FLEXCAN_TransferReceiveNonBlocking(handle->cfg->base, &handle->flexcanHandle, &handle->rxXfer);

    // /* Send data through Tx Message Buffer. */
    handle->txXfer.mbIdx = TX_MESSAGE_BUFFER_NUM;
    handle->txXfer.frame = &handle->txFrame;
	 FLEXCAN_TransferSendNonBlocking(handle->cfg->base, &handle->flexcanHandle, &handle->txXfer);
	 
	 xEventGroupWaitBits(handle->txEvent, CAN_TX_COMPLETE, pdTRUE, pdFALSE, portMAX_DELAY);

 

 在中断中发送完成后使用xEventGroupSetBitsFromISR发送事件。

static void flexcan_callback(CAN_Type *base, flexcan_handle_t *handle, status_t status, uint32_t result, void *userData)
{
    BaseType_t xHigherPriorityTaskWoken, xResult;
    pkiCanHandle_t *pkiHandle = (pkiCanHandle_t *)userData;
    switch (status)
    {
        case kStatus_FLEXCAN_RxIdle:
            if (RX_MESSAGE_BUFFER_NUM == result) {
                flexcan_frame_t *rxFrame = pkiHandle->rxXfer.frame;
                fifoEnqueue(&pkiHandle->rxFifo, &rxFrame->dataByte0, 1);
                fifoEnqueue(&pkiHandle->rxFifo, &rxFrame->dataByte1, 1);
                fifoEnqueue(&pkiHandle->rxFifo, &rxFrame->dataByte2, 1);
                fifoEnqueue(&pkiHandle->rxFifo, &rxFrame->dataByte3, 1);
                fifoEnqueue(&pkiHandle->rxFifo, &rxFrame->dataByte4, 1);
                fifoEnqueue(&pkiHandle->rxFifo, &rxFrame->dataByte5, 1);
                fifoEnqueue(&pkiHandle->rxFifo, &rxFrame->dataByte6, 1);
                fifoEnqueue(&pkiHandle->rxFifo, &rxFrame->dataByte7, 1);
                rxCount++;
            }
            break;

        case kStatus_FLEXCAN_TxIdle:
            if (TX_MESSAGE_BUFFER_NUM == result) {
                xResult = xEventGroupSetBitsFromISR(pkiHandle->txEvent, CAN_TX_COMPLETE, &xHigherPriorityTaskWoken);
                txCount++;
            }
            break;

        default:
            break;
    }
}

 现在的现象是只要我使用xEventGroupWaitBits来等待事件,则过几次就再也等待不到中断返回来的事件,一直在挂起状态,感觉发送中断都无法再进入,如果把这句屏蔽掉,就可以正常运行。

现在不太能理解为什么加了xEventGroupWaitBits就导致一段时间后就进不了中断了?(疑似)

 

0 Kudos
Reply
6 Replies

3,180 Views
jeremyzhou
NXP Employee
NXP Employee

Hi,
非常感谢使用NXP产品,很高兴为你提供技术支持!
针对你的问题,我建议你最好详细介绍一下你的测试流程,提供更多的信息,比如调试代码,开发板以对应步骤,这样方便复现和发现问题。
Have a great day,
TIC

 

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
Reply

3,173 Views
colinluan
Contributor III

Hi, 我的代码在附件里,现在我这边只有一块开发板RT1064的开发板MIMXRT1064-EVK,我想用Loopback模式来验证我自己写的驱动,我的思路是第一步调通最基本的loopback模式,然后再把我自己写的驱动逻辑加进来,我使用的是CAN2,loopback模式实现如下:

1、管脚配置

pin.png

2、初始化

static void flexCanTestInit(void)
{
   flexcan_config_t flexcanConfig;
   flexcan_rx_mb_config_t mbConfig;

   /*Clock setting for FLEXCAN*/
   CLOCK_SetMux(kCLOCK_CanMux, FLEXCAN_CLOCK_SOURCE_SELECT);
   CLOCK_SetDiv(kCLOCK_CanDiv, FLEXCAN_CLOCK_SOURCE_DIVIDER);
   NVIC_SetPriority(CAN2_IRQn, 4);
//    PRINTF("\r\n==FlexCAN loopback example -- Start.==\r\n\r\n");

   FLEXCAN_GetDefaultConfig(&flexcanConfig);
#if defined(CAN_CTRL1_CLKSRC_MASK)
   if (!FSL_FEATURE_FLEXCAN_INSTANCE_SUPPORT_ENGINE_CLK_SEL_REMOVEn(EXAMPLE_CAN))
   {
       flexcanConfig.clksrc=kFLEXCAN_ClkSrcPeri;
   }
#endif
   flexcanConfig.enableLoopBack = true;
   FLEXCAN_Init(EXAMPLE_CAN, &flexcanConfig, EXAMPLE_CAN_CLK_FREQ);


   /* Setup Rx Message Buffer. */
   mbConfig.format = kFLEXCAN_FrameFormatStandard;
   mbConfig.type = kFLEXCAN_FrameTypeData;
   mbConfig.id = FLEXCAN_ID_STD(0x123);
   FLEXCAN_SetRxMbConfig(EXAMPLE_CAN, RX_MESSAGE_BUFFER_NUM, &mbConfig, true);

   FLEXCAN_SetTxMbConfig(EXAMPLE_CAN, TX_MESSAGE_BUFFER_NUM, true);

   /* Create FlexCAN handle structure and set call back function. */
   FLEXCAN_TransferCreateHandle(EXAMPLE_CAN, &flexcanHandle, flexcan_callback1, NULL);
}

 初始化为Loopback模式,CAN ID为0x123,回调函数为flexcan_callback1:

static EventGroupHandle_t txEvent;
static void flexcan_callback1(CAN_Type *base, flexcan_handle_t *handle, status_t status, uint32_t result, void *userData)
{
	BaseType_t xHigherPriorityTaskWoken, xResult;
    switch (status)
    {
        /* Process FlexCAN Rx event. */
        case kStatus_FLEXCAN_RxIdle:
            if (RX_MESSAGE_BUFFER_NUM == result)
            {
                rxComplete = true;
            } 
            break;

        /* Process FlexCAN Tx event. */
        case kStatus_FLEXCAN_TxIdle:
            if (TX_MESSAGE_BUFFER_NUM == result)
            {
                txComplete = true;
                xEventGroupSetBitsFromISR(txEvent, 0x01, &xHigherPriorityTaskWoken);
            }
            break;

        default:
            break;
    }
}

 

3、收发调试函数

每次发送后,等待callback函数中的txEvent事件进行同步

static void flexCanTest(void)
{
    PRINTF("\r\n==FlexCAN loopback example -- Start.==\r\n\r\n");
   /* Prepare Tx Frame for sending. */
   txFrame.format = kFLEXCAN_FrameFormatStandard;
   txFrame.type = kFLEXCAN_FrameTypeData;
   txFrame.id = FLEXCAN_ID_STD(0x123);

   txFrame.length = 8;

   txFrame.dataWord0 = CAN_WORD0_DATA_BYTE_0(0x11) | CAN_WORD0_DATA_BYTE_1(0x22) | CAN_WORD0_DATA_BYTE_2(0x33) |
                       CAN_WORD0_DATA_BYTE_3(0x44);
   txFrame.dataWord1 = CAN_WORD1_DATA_BYTE_4(0x55) | CAN_WORD1_DATA_BYTE_5(0x66) | CAN_WORD1_DATA_BYTE_6(0x77) |
                       CAN_WORD1_DATA_BYTE_7(0x88);

   PRINTF("Send message from MB%d to MB%d\r\n", TX_MESSAGE_BUFFER_NUM, RX_MESSAGE_BUFFER_NUM);
   PRINTF("tx word0 = 0x%x\r\n", txFrame.dataWord0);
   PRINTF("tx word1 = 0x%x\r\n", txFrame.dataWord1);

   rxXfer.mbIdx = RX_MESSAGE_BUFFER_NUM;
   rxXfer.frame = &rxFrame;
   FLEXCAN_TransferReceiveNonBlocking(EXAMPLE_CAN, &flexcanHandle, &rxXfer);

   /* Send data through Tx Message Buffer. */
   txXfer.mbIdx = TX_MESSAGE_BUFFER_NUM;
   txXfer.frame = &txFrame;
   FLEXCAN_TransferSendNonBlocking(EXAMPLE_CAN, &flexcanHandle, &txXfer);

   rxComplete = false;
   txComplete = false;
   /* Waiting for Rx Message finish. */
   xEventGroupWaitBits(txEvent, 0x01, pdTRUE, pdFALSE, portMAX_DELAY);
//    while ((!rxComplete) || (!txComplete))
//    {
//    	vTaskDelay(10);
//    };

   PRINTF("\r\nReceived message from MB%d\r\n", RX_MESSAGE_BUFFER_NUM);
   PRINTF("rx word0 = 0x%x\r\n", rxFrame.dataWord0);
   PRINTF("rx word1 = 0x%x\r\n", rxFrame.dataWord1);

   PRINTF("\r\n==FlexCAN loopback example -- Finish.==\r\n");
}

 4、建立Freertos任务,每500ms发送一次数据

void flexCanTestTask(void *ptr)
{
	flexCanTestInit();
	txEvent = xEventGroupCreate();
	while(1)
	{
		flexCanTest();
		vTaskDelay(500);
	}
}

 

现在的现像是发了一阵之后就卡死在了如下的事件等待中。

xEventGroupWaitBits(txEvent, 0x01, pdTRUE, pdFALSE, portMAX_DELAY);

output.png

5、除了测试了任务,另外建立了几个任务如下:

task status.png

UART1 driver task 是我自己写的uart驱动

IDLE是自己定义的IDLE任务

FlexCan Test Task 就是上述的测试任务

我的环境为:SDK使用的是2.4.1,MCUXpresso为10.3.1

0 Kudos
Reply

3,159 Views
jeremyzhou
NXP Employee
NXP Employee

Hi,
感谢回复。
我觉得你现在要排查的的是,在Flexcan发送完后,是否都顺利的执行一些代码并且xResult 是否为success,建议先减少task数量降低工程复杂度。

case kStatus_FLEXCAN_TxIdle:
if (TX_MESSAGE_BUFFER_NUM == result) {
xResult = xEventGroupSetBitsFromISR(pkiHandle->txEvent, CAN_TX_COMPLETE, &xHigherPriorityTaskWoken);
txCount++;
}


Have a great day,
TIC

 

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
Reply

3,149 Views
colinluan
Contributor III

感觉问题出现的很诡异,我现在的代码运行起来后跑一段时间就卡死,再也进不了中断了。然后我写了个函数,但是并没有调用,然后再次运行时发现跑两下就死了,不知道为什么会有影响?我看了下,这个没有被调用的函数被编译进目标文件了,我的理解是无非就是占用了些Flash,但是不应该对我的结果产生影响。另外有什么方法不编译没有被调用的函数吗?

0 Kudos
Reply

3,154 Views
colinluan
Contributor III

前面两次可以正常进中断,第三次失败的那一次直接就没有进中断。另外我跟踪了FLEXCAN_TransferReceiveNonBlocking跟FLEXCAN_TransferSendNonBlocking这两个函数,看起来一切都正常,没有报任何错误。

0 Kudos
Reply

3,139 Views
jeremyzhou
NXP Employee
NXP Employee

Hi, 感谢回复。 正如我前面说的,你可以先简化程序,再进行测试。 其次,你查看一下中断标志,确认为啥没有进入中断,还是被什么给抢占了。 Have a great day, TIC ------------------------------------------------------------------------------- Note: - If this post answers your question, please click the "Mark Correct" button. Thank you! - We are following threads for 7 weeks after the last post, later replies are ignored Please open a new thread and refer to the closed one, if you have a related question at a later point in time. -------------------------------------------------------------------------------

0 Kudos
Reply