Other Parts Discussed in Thread: HALCOGEN
您好,想问下在can模块中64个message box里面有没有优先级的区别?印象中在哪里看到过说1是优先级最高的,64最低,在手册里面没找到相关的说明,这些message box会有优先级的区别吗?另外VIM模块中的中断向量是1最高吗?
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Other Parts Discussed in Thread: HALCOGEN
您好,想问下在can模块中64个message box里面有没有优先级的区别?印象中在哪里看到过说1是优先级最高的,64最低,在手册里面没找到相关的说明,这些message box会有优先级的区别吗?另外VIM模块中的中断向量是1最高吗?
另外在接收到can数据后在HCG代码生成的canGetdata()函数中会从接收到的can帧中判断数据长度size,但是实验中size的值为F,在后面接收时使用size为数组下标时会出现越界的问题,如果是8的话就没有问题,这个问题如何解释呢?
还遇到一个问题就是相同的配置,使用某些messagebox进行收数据(所有ID均接受,mask码为0)时不能接收到所有的总线上的信息,但是使用另一个message box时就可以全部接收到,两个配置完全相同,只是改变了使用的messagebox,为什么会出现这个问题呢?
不清楚这个会不会有硬件上面不兼容的情况出现,另一个can节点是采用飞利浦的芯片,会不会是硬件兼容性有问题而产生的呢?
Hi Yong,
确实如你所说,我们的Hercules芯片里面的DCAN模块是具有64个message box。每个message box 都是支持单独配置的。针对他们配置的我们有一个专门的名称叫做message object。 它的数值大小就代表了该message box的优先级。通常是数字越小,优先级越高。注意这个指的是message box的值,不是ID符的值。这个和其他的芯片不同。你在我们的TRM的DCAN章节是可以找得到关于它的详细介绍的。
另外我们的VIM中断优先级主要体现在vim的channel上面的,一般默认是channel值的数字越小,优先级越大。因为我们芯片支持软件配置匹配channel的,所以也就是说我们的中断优先级是可编程的。我们芯片的channel0对应的是我们的ESM模块,它的优先级最高,而且是固定的,不可配的。这主要是用来体现我们安全特性一个方面。
谢谢
ken
Hi Yong,
在CAN报文协议的定义中,我们一个报文信息所能具有的数据负荷能力最大是八个字节。换句话说是DLC的值最大只能设置为0.
通过你的描述,是指你设定接收的数据长度为15(F)字节嘛?如果是这样的话,这个接收是会出现越界的情况的。
如果你主机端需要发送的数据比8个字节要大,那你可以考虑多次发送。或者说是可以先配置好几个messagebox,然后在发送的过程中一次调用不同的message box来发送你所需要的数据。这样就可以避免单次发送所带来的问题。
谢谢
Ken
Hi Yong,
你的CAN总线通信速率是多大?每次发送的数据量是多少呢?而且每次发送的间隔大概多长?这些都有可能会影响到总线数据的吞吐量,同时也会影响接收数据段的稳定性和准确性。
在没有看到你的具体代码之前,我不是太好判断这是软件上面的原因还是硬件上面的原因。你说换一个messagebox就能全部接收,那这个messagebox是随便一个还是说是特定的一个messagebox?
另外在硬件上面出现不兼容的情况,一般有两种:一种说是两边的CAN收发芯片功能不一样,因为现在市面上有快速的CAN收发器也有容错性的CAN收发器,如果这两个连在一条总线上面通信,这个是会有问题的。
第二种情况是,因为CAN总线报文的波特率的设置上,有一个采样点的设置,在调试CAN总线的通信时,有的时候需要去调整这个值,从而是你能准确的收到总线的信息。以往我有遇到用两个SJA1000的CAN控制器加一颗高速CAN收发器建立通信时,需要调整这个值从而得到准确报文的经历。
谢谢
Ken
非常感谢您的及时回复,关于messagebox优先级的问题,我之前有印象是messagebox的编号越小优先级越高(与ID无关),但是在TRM手册中没有找到关于DCAN模块mailbox优先级的描述,因此不清楚到底这个有没有根据。
VIM优先级明白了
另外,那个Size的大小是根据收到的can帧信息的数据自动更新的,can帧信息来源是SJA1000芯片,不清楚为什么这边收到的size是f,添加判断语句
if(size<16 || size>8)
size=8;
后可以利用canGetdata()正常的接收数据
关于第三个问题,当使用messagebox1、7通道接收数据时无法顺利接收,但是使用2通道时就可以顺利接收,另一个can节点使用的就是sja1000+82C250,不清楚这个应该如何配置才能实现稳定的CAN总线数据传送。
Regards
yong
再与另一个can节点通信时,can总线的波特率为500kbps,采样点按照HCG中的默认设置为75,发送的数据量就是每个can帧8个字节数据,再与另一节点通信时遇到发送间隔导致的发送不成功的问题,
570与多个sja1000之间进行can通信,570向sja1000发送数据后会收到sja1000的返回数据,一周期内570需向多个sja1000发送多次数据
570芯片中采用的程序流程如下:
在发送程序后的for循环中,canbusdelay为自行设定,循环中执行的是canGetdata()函数,这个循环是增加了一个延迟时间T1,T1的大小由canbusdelay决定
当SJA1000收到570的can消息时向总线发送响应信息,这个响应信息与570发送的信息之间同样存在一个时间差计为T2,目前出现的问题是当T1与T2相近时可能导致570的can信息不能正常发出,甚至会出现死机情况,只有当T1与T2相隔开(由于要与多个SJA1000通信,所以只能是T1大于T2),才可以进行正常的can通信,请问这种情况正常吗,有没有什么好的解决方法呢?
Hi Yong,
听你的描述,感觉你是想通过CAN总线来对各个子节点之间进行时钟同步或是时钟校正的操作嘛。不知道理解对不对。
我曾经做过这样一个实验,四个TMS570的CAN节点,一个做master,三个做slave。master定时发送数据和时间值给slave,slave在接到数据后,回复收到数据时的时间值。通过四次这样的操作,然后根据IEEE1588的协议,通过算法来实现各个节点间的时钟同步。我不知道你做的是不是类似的操作,但感觉在CAN总线报文的处理方面还是有很大的一样的。
我个人建议,如果可能的话,还是通过CAN接收中断来处理接收到的报文信息。每个CAN节点的发送和接收报文设置不一样的message box和相应的ID符,然后主节点设置多个相应的发送和接收messagebox用于报文的收发,子节点只需设置不同的发送和接收的两个messagebox。这样的话,对于can报文的信息处理起来会比较顺畅。
在我的设计程序中,时钟差都是在us级别,也没有出现过报姐接收不正常的情况。当然你遇到的情况也有可能是和SJA1000的特性有关,它应该比较难去设置各个不同ID的message objective。你觉得呢?
谢谢
ken
Hi Yong,
关于你收到的CAN的信息中的size 问题,我觉得你可以通过CANoe或是CANopen之类的工具,监听一下CAN总线上的信息,看看总线上的信息每次携带的数据量具体是什么。是不是和你每次发的数据相同。我感觉在TMS570收到信息并判断size的值等于F这种情况很有可能是收到的CAN报文信息异常引起的。方便的话,你可以查查看。
关于使用messagebox1,7无法收到信息,而2通道却能收到信息,这个我也觉得比较好奇。如果真的是所有设置都一样的话,这个是说不通的。
如果可能的话,你能不能把你的CAN.c和CAN.h的文件上传上来,我们仔细看看。查查是否有什么设置不正常的地方。这样的话比较好定位具体的问题。
你的CAN节点采用的是SJA1000+ PC82c250,者是比较经典的一个组合。在SJA1000的波特率设置方程里面你可以找得到除了波特率的寄存器,还有其他几个参数。印象中好像有两个参数的和是要等于16的,但是那两个具体的数值可以调的,只要保证和等于16就行。以前我用过周立功的USB-CAN,里面芯片就是SJA1000,然后在设置波特率的界面里面有几个采样点的参数是可调的。
谢谢
ken
类似于时钟矫正的工作吧,就是主节点定期的向子节点发送数据(400ms左右吧),然后子节点在收到主节点信息后会返回一个can帧信息,与此同时,子节点也定期的向主节点送数据(3s),主节点只接收来自子节点的信息,不再发送can帧信息进行响应。
现在采用的方式就是主节点设置多个相应的发送和接收messagebox,例如,需要跟4个子节点通信则主节点应设置8个相应的messagebox,这样设置出现的问题是这样的,
每个messagebox 向单独的ID 发送没有问题;
一个messagebox 只接收一个ID 来的数据有问题:
只要有某个messagebox 通过过滤(Msk)能接收数据的时候,其它messagebox 都无法接收,也就是同时只能有一个box接收。
例如,我现在的设置方式是:令messagebox1 接收 ID为0x580来的数据,则messagebox1设置为:ID:0x580 Mask:0x00000580,其他子节点也应用相应的设置,当messagebox1接收数据时,采用其他box编号的接收就不能正常的收到总线上的相应消息。
如果采用一个messagebox接收多个ID来的数据(不设屏蔽码,所有子节点的数据都通过一个messagebox来接收),则会出现接收不流畅的现象(CAN总线不能正常的发送,接收),有时会堵住一段时间,10S 甚至更多。
不清楚应该如何设置messagebox来避免这些问题呢?
Regards,
yong
Hi Yong,
我在做程序的时候,没有遇到类似的情况啊。你可以参考一下我上传的master端的CAN.c的文件。里面设置了发送和接收不同messagebox的设置。然后接收都是采用中断接收的形式啊。没出现过问题啊。
canREG1->IF1MSK = 0xC0000000U | ((0x000007FFU & 0x000007FFU) << 18U);
canREG1->IF1ARB = 0x80000000U | 0x00000000U | 0x20000000U | ((2U & 0x000007FFU) << 18U);
canREG1->IF1MCTL = 0x00001080U | 0x00000800U | 8U;
canREG1->IF1CMD = 0xF8;
canREG1->IF1NO = 1;
/** - Initialize message 2
* - Wait until IF2 is ready for use
* - Set message mask
* - Set message control word
* - Set message arbitration
* - Set IF2 control byte
* - Set IF2 message number
*/
while ((canREG1->IF2STAT & 0x80U) ==0x80U)
{
} /* Wait */
canREG1->IF2MSK = 0xC0000000U | ((0x000007FFU & 0x000007FFU) << 18U);
canREG1->IF2ARB = 0x80000000U | 0x00000000U | 0x20000000U | ((3U & 0x000007FFU) << 18U);
canREG1->IF2MCTL = 0x00001080U | 0x00000800U | 8U;
canREG1->IF2CMD = 0xF8;
canREG1->IF2NO = 2;
/** - Initialize message 3
* - Wait until IF1 is ready for use
* - Set message mask
* - Set message control word
* - Set message arbitration
* - Set IF1 control byte
* - Set IF1 message number
*/
while ((canREG1->IF1STAT & 0x80U) ==0x80U)
{
} /* Wait */
canREG1->IF1MSK = 0xC0000000U | ((0x000007FFU & 0x000007FFU) << 18U);
canREG1->IF1ARB = 0x80000000U | 0x00000000U | 0x20000000U | ((4U & 0x000007FFU) << 18U);
canREG1->IF1MCTL = 0x00001080U | 0x00000800U | 8U;
canREG1->IF1CMD = 0xF8;
canREG1->IF1NO = 3;
/** - Initialize message 4
* - Wait until IF2 is ready for use
* - Set message mask
* - Set message control word
* - Set message arbitration
* - Set IF2 control byte
* - Set IF2 message number
*/
while ((canREG1->IF2STAT & 0x80U) ==0x80U)
{
} /* Wait */
canREG1->IF2MSK = 0xC0000000U | ((0x000007FFU & 0x000007FFU) << 18U);
canREG1->IF2ARB = 0x80000000U | 0x00000000U | 0x00000000U | ((2U & 0x000007FFU) << 18U);
canREG1->IF2MCTL = 0x00001080U | 0x00000400U | 8U;
canREG1->IF2CMD = 0xF8;
canREG1->IF2NO = 4;
/** - Initialize message 5
* - Wait until IF1 is ready for use
* - Set message mask
* - Set message control word
* - Set message arbitration
* - Set IF1 control byte
* - Set IF1 message number
*/
while ((canREG1->IF1STAT & 0x80U) ==0x80U)
{
} /* Wait */
canREG1->IF1MSK = 0xC0000000U | ((0x000007FFU & 0x000007FFU) << 18U);
canREG1->IF1ARB = 0x80000000U | 0x00000000U | 0x00000000U | ((3U & 0x000007FFU) << 18U);
canREG1->IF1MCTL = 0x00001080U | 0x00000400U | 8U;
canREG1->IF1CMD = 0xF8;
canREG1->IF1NO = 5;
/** - Initialize message 6
* - Wait until IF2 is ready for use
* - Set message mask
* - Set message control word
* - Set message arbitration
* - Set IF2 control byte
* - Set IF2 message number
*/
while ((canREG1->IF2STAT & 0x80U) ==0x80U)
{
} /* Wait */
canREG1->IF2MSK = 0xC0000000U | ((0x000007FFU & 0x000007FFU) << 18U);
canREG1->IF2ARB = 0x80000000U | 0x00000000U | 0x00000000U | ((4U & 0x000007FFU) << 18U);
canREG1->IF2MCTL = 0x00001080U | 0x00000400U | 8U;
canREG1->IF2CMD = 0xF8;
canREG1->IF2NO = 6;
/** - Initialize message 7
* - Wait until IF1 is ready for use
* - Set message mask
* - Set message control word
* - Set message arbitration
* - Set IF1 control byte
* - Set IF1 message number
*/
while ((canREG1->IF1STAT & 0x80U) ==0x80U)
{
} /* Wait */
canREG1->IF1MSK = 0xC0000000U | ((0x000007FFU & 0x000007FFU) << 18U);
canREG1->IF1ARB = 0x80000000U | 0x00000000U | 0x20000000U | ((7U & 0x000007FFU) << 18U);
canREG1->IF1MCTL = 0x00001080U | 0x00000000U | 8U;
canREG1->IF1CMD = 0xF8;
canREG1->IF1NO = 7;
程序终端接收采用的是switch(messagebox)的形式来判断是接收到那个slave发送的信息,具体如下:
void canMessageNotification(canBASE_t *node, uint32 messageBox)
{
switch(messageBox)
{
case canMESSAGE_BOX1:
canTransmit(node,canMESSAGE_BOX7,Tx_Data_CAN);
break;
case canMESSAGE_BOX2:
canTransmit(node,canMESSAGE_BOX8,Tx_Data_CAN);
break;
...
}
希望对你有所帮助。
谢谢
ken
您好,我看了下您的程序,貌似在使用HCG生成代码时每个Messagebox的ID仍然是按照原来的,比如mesagebox1的ID就是1,屏蔽码是7FF,但是我自己试的时候,在HCG中将ID设置为我需要的,比如说0x580(使用messagebox 2),当屏蔽码设置为7FF时,TMS570收不到总线上ID为0x580的消息,但是当屏蔽码设置为0x580时,TMS570(主节点)就能够接收到来自总线上的ID为0x580的消息,但是在接收之后的messagebox中(使用messagebox4接收ID为0x680的消息,屏蔽码设置为0x680),就不能正常接收,但是将messagebox2中的屏蔽码改为7FF,此时messagebox2不能收到信息,但是messagebox4能正常接收。
即messagebox之间貌似有一种屏蔽的机制,不清楚为什么在前面的messagebox接收了消息以后,后面的会接收不到,还有就是这个屏蔽码具体是如何工作的呢?我的理解是如果某一位设置为1的话,那么在接收信息时是需要校验改位的ID的,但是为什么将屏蔽码设置为7ff(即每位ID都需要校验)时,570收不到总线上相应ID的信息呢?
Regards,
yong
Hi Yong,
这个屏蔽码的作用其实就是想你所说的一样,如果他的某一位被设置为 1的话,相对应的ID的这意味必须也是为1才能最终通过过滤。这个有点像我们所的位与运算。即如果将所有的屏蔽为设置位0x7FF,那么只有和ID符一样的message ID才能被接收进来。
从你的描述上来看,感觉还是比较奇怪的。我以往的设计都没有出现这样的问题。你在设置HALCOGEN的时候,是不是每个messagebox的输入输出值都是按你的要求设置的。虽然觉得问这个有点业余,但是很多情况下,这种小错误也会导致接收不能成功。
最后就是如果可能的话,你把你HALCOGEN的配置文件(.hcg文件)发上来,我帮你看看具体的属性配置吧。不然感觉这样语言的描述还是有点事倍功半。
谢谢
ken
确实是比较费事,如果您没有碰到过类似的问题的话应该是某些设置不太一样,方不方便您把邮箱给我呢?我把相关的配置文件跟程序给您发过去,到时麻烦您看下。
Regards
yong
确实是比较费事,如果您没有碰到过类似的问题的话应该是某些设置不太一样,方不方便您把邮箱给我呢?我把相关的配置文件跟程序给您发过去,到时麻烦您看下。
Regards
yong
确实是比较费事,如果您没有碰到过类似的问题的话应该是某些设置不太一样,方不方便您把邮箱给我呢?我把相关的配置文件跟程序给您发过去,到时麻烦您看下。
Regards
yong
Hi Yong,
关于CAN总线方面的问题,已经回复了你的邮件。请查收。
同时在我们的论坛里我也上传了关于CAN通信的源代码文件。
如果还有什么问题的话,欢迎继续讨论。
谢谢
ken