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就导致一段时间后就进不了中断了?(疑似)
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.
-------------------------------------------------------------------------------
Hi, 我的代码在附件里,现在我这边只有一块开发板RT1064的开发板MIMXRT1064-EVK,我想用Loopback模式来验证我自己写的驱动,我的思路是第一步调通最基本的loopback模式,然后再把我自己写的驱动逻辑加进来,我使用的是CAN2,loopback模式实现如下:
1、管脚配置
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);
5、除了测试了任务,另外建立了几个任务如下:
UART1 driver task 是我自己写的uart驱动
IDLE是自己定义的IDLE任务
FlexCan Test Task 就是上述的测试任务
我的环境为:SDK使用的是2.4.1,MCUXpresso为10.3.1
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.
-------------------------------------------------------------------------------
感觉问题出现的很诡异,我现在的代码运行起来后跑一段时间就卡死,再也进不了中断了。然后我写了个函数,但是并没有调用,然后再次运行时发现跑两下就死了,不知道为什么会有影响?我看了下,这个没有被调用的函数被编译进目标文件了,我的理解是无非就是占用了些Flash,但是不应该对我的结果产生影响。另外有什么方法不编译没有被调用的函数吗?
前面两次可以正常进中断,第三次失败的那一次直接就没有进中断。另外我跟踪了FLEXCAN_TransferReceiveNonBlocking跟FLEXCAN_TransferSendNonBlocking这两个函数,看起来一切都正常,没有报任何错误。
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. -------------------------------------------------------------------------------