在官方SDK的flexcan例程中,为什么flexcan中断中处理完邮箱的中断以后,要关闭对应邮箱的中断,即将IMASK对应位置0.
这样当下次需要使用这个邮箱传输数据时,需要再次将IMASK寄存器对应位置1,从而开启中断。
如果这个操作是必要的,它的作用是什么呢?
Hi @TheSix ,
感谢您对NXP产品感兴趣。抱歉我回复晚了。
实际上在这里关闭邮箱的中断是一个常见的操作,在 FlexCAN 中,每个邮箱都有一个中断标志位,用于指示该邮箱是否接收到了新的消息。当收到消息时,该标志位会被置位,并触发中断服务程序 (ISR)。在 ISR 中,您需要处理接收到的消息,并清除中断标志位。如果不清除中断标志位,则 ISR 会一直被触发,即使没有新的消息可供处理。
Best regards,
Gavin
我也很奇怪,RT1176也有同样的问题,为什么要关闭邮箱中断呢,在初始化中使能一次邮箱中断,不就可以一直等待控制器触发中断吗,我理解代码这样写是为了在当前邮箱没有处理完数据的时候先关闭中断,让下一包数据由另一个空闲邮箱接收,但在控制器自己的处理机制中,如果当前邮箱CODE为FULL状态,会有内部锁,锁住当前邮箱,再来数据会由另一个空闲态邮箱处理,当两个邮箱都是FULL状态时,会尝试去覆盖最后一个 使用的邮箱,但是邮箱处于锁定状态,数据会存储在SMB(隐式缓冲区,无法查看)中,此时查看CODE状态是溢出态
在我调试CAN驱动的时候发现,如果瞬时来了多包数据,这个关闭邮箱中断并清除中断标志位的操作有可能会出现异常,导致接收直接瘫痪,我测试的现象是,多包数据到达时,邮箱1会处理不完,邮箱2去开始接收,等邮箱1处理完后,继续由邮箱1来接收数据,但某一次,邮箱1开始不接收任何数据,数据全部由邮箱2来接收,当邮箱2大量接收一阵数据后,邮箱2也不再接收数据,此时去查看寄存器对应的位,邮箱2的MASK位为0,但FLAG位为1,证明程序运行到了FLEXCAN_TransferFDAbortReceive函数来关闭了邮箱使能,但是不知道什么原因没有运行到FLEXCAN_ClearMbStatusFlags函数
我尝试注释掉中断处理中的disable MASK,并且在中断回调中也不再次enable MASK,我只在初始化中enable邮箱一次,后续测试发现,功能正常但我配置的两个接收邮箱,只有一个在一直接收,但是也没有丢包的情况出现