全部学习汇总: https://github.com/GreyZhang/J1939_basic
之前,大概分析了J1939_ISR,要想明确弄清楚J1939的收发的机理需要继续分析两个CAN的收发接口。这里,先尝试分析一下CAN消息的接收功能。
首先需要注意的是,这个函数用了static,因此使用的范围会有一些限制。通常是不会出一个文件,尤其是其在C文件中定义的。后面的代码,出现了好几重的预处理,目前我的emacs配置下需要层层查看。万不得已,兴许我还得尝试做个代码修改测试下。这么看起来,在我自己的工具链的打造上,还是得继续优化才好。
首先,确认一下这段代码的真实功能。因此,需要查看一下ECAN_LEGACY_MODE的定义。在工程中的定义:
还有一个定义:
接下来,看上面的第二个定义是否能够起作用。这样,需要看ECAN_IS_CAN_MODULE是否定义过。需要分析如下代码:
这部分信息可能是存在于编译器IDE的设置中,不是很好找。因此,我直接注入了一部分错误代码:
结果编译没有任何问题。因此,上面的几个都不会生效,进一步可以知道如下部分不生效:
而这样,ECAN_LEGACY_MODE的数值应该是J1939_FALSE。这样,就可以继续解读接收函数了。
这样,接收其实是采用FIFO的模式。不过,这个代码的处理还是多少跟我认识的FIFO处理还不是很一样。
这样,循环里面上面这一大段其实是做一个报文内容的读取。这样,结合之前的理解,后面应该还有一个队列的缓冲处理。
这个可能是跟硬件MCU相关度很高的,暂且跳过去。感觉上,这个跟协议栈理解相关度不是很大。
接下来,判断PF,之后根据PF做不同的处理。
我看的这个例程其实就是命令地址功能,因此下面这段代码会生效。而上面这部分,是对于CM的处理。结合之前的分析整理,CM的过程其实是分为两部分。首先,一个发给全局地址的CM,里面包含了数据量、多少包、PGN的信息。如果收到了这样的报文,那么说明接下来需要获取命令地址。因此,这里面有一个标志位更新。
这是对于DT的判断,其实还是比较容易理解的。从这里,我进一步清楚了这个命令地址的过程。其实,这个应该是首先有一个节点发出CM以及数据量和数据包的信息。然后,带着NAME和地址。而这一组全都是广播报文,因此需要总线上的全部支持该功能的节点来处理。节点判断自己被点名了,那么就去尝试做新的地址声明。
还有两个分支,一个是请求,另一个是我之前已经熟悉的地址声明。默认情况则是直接进行报文的队列接收。这样,后续应该还得有一个请求的处理分析。这个后续再做处理。