TMS570L1227,在动态管理CAN message Box时,会发生CANID和CAN消息内容错位的现象,这是为什么产生的?
官方有没有CAN动态管理的例程或者源码可以参考的?
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.
TMS570L1227,在动态管理CAN message Box时,会发生CANID和CAN消息内容错位的现象,这是为什么产生的?
官方有没有CAN动态管理的例程或者源码可以参考的?
Ruizhi Lee 说:在动态管理CAN message Box时,会发生CANID和CAN消息内容错位的现象
能否请您详细说明下?最好给出您的代码,谢谢
Ruizhi Lee 说:官方有没有CAN动态管理的例程或者源码可以参考的?
据我所知是没有CAN动态管理的例程的
我曾经用过的发送方式是
void CANSimpleSend(canBASE_t *const canreg, uint32_t msgbox, uint32_t ID, uint8_t *const data) { static uint32_t ret = 0U; uint8_t trytimes = 3U; canUpdateID(canreg, msgbox, 1U << 30U | 1U << 29U | (ID & 0x1FFFFFFFU)); do { ret = canTransmit(canreg, msgbox, data); if (ret == 0U) { int16_t i = 1000U; while (i > 0) i--; } trytimes--; } while ((ret == 0U) && (trytimes > 0U)); }
uint16 CANSend(uint8 Dest, CAN_MSG_TYPE type, uint8 *const data) { uint32 canid = 0U; canid |= (type & 0xFFU); canid |= Dest << 8U; canid |= GetBoardID() << 16U; /* CANID 30bit: ext_ID 29bit: Dir Transmit */ static uint32_t msgbox = canMESSAGE_BOX1; data[0U] = canindex++; /* data[0] is frame index */ /* CAN1 */ CANSimpleSend(canREG1,msgbox,canid,data); /* CAN2 */ CANSimpleSend(canREG2,msgbox,canid,data); msgbox++; if (msgbox == canMESSAGE_BOX9) msgbox = canMESSAGE_BOX1; return 0; }
动态通过messagebox1-8进行发送,这种情况下,高速发送时错误率非常高
修改后的发送方式,将更改ID和更改数据融合,为
uint8_t canSimpleTransmit(canBASE_t *const canreg, uint32_t msgbox, uint32_t ID, uint8_t * data) { uint32 i; uint32 success = 0U; uint32 regIndex = (msgbox - 1U) >> 5U; uint32 bitIndex = 1U << ((msgbox - 1U) & 0x1FU); /** - Check for pending message: * - pending message, return 0 * - no pending message, start new transmission */ if ((canreg->TXRQx[regIndex] & bitIndex) != 0U) { success = 0U; } else { /** - Wait until IF1 and IF2 is ready for use */ while( ((canreg->IF1STAT & 0x80U) ==0x80U) || ((canreg->IF2STAT & 0x80U) ==0x80U) ) { } /* Wait */ /** - Configure IF2 for * - Message direction - Read * - Data Read * - Clears NewDat bit in the message object. */ canreg->IF2CMD = 0xA0U; /* Copy passed value into the arbitration register. */ canreg->IF2ARB &= 0x80000000U; canreg->IF2ARB |= (ID & 0x7FFFFFFFU); /** - Configure IF1 for * - Message direction - Write * - Data Update * - Start Transmission */ canreg->IF1CMD = 0x87U; /** - Copy TX data into IF1 */ for (i = 0U; i < 8U; i++) { #if ((__little_endian__ == 1) || (__LITTLE_ENDIAN__ == 1)) /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */ node->IF1DATx[i] = *data; /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */ /*SAFETYMCUSW 567 S MR:17.1,17.4 <APPROVED> "Pointer increment needed" */ data++; #else /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */ canreg->IF1DATx[s_canByteOrder[i]] = *data; /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */ /*SAFETYMCUSW 567 S MR:17.1,17.4 <APPROVED> "Pointer increment needed" */ data++; #endif } /** - Update message box number. */ /*SAFETYMCUSW 93 S MR: 6.1,6.2,10.1,10.2,10.3,10.4 <APPROVED> "LDRA Tool issue" */ canreg->IF2NO = (uint8) msgbox; /** - Wait until data are copied into IF2 */ while ((canreg->IF2STAT & 0x80U) ==0x80U) { } /* Wait */ /** - Copy TX data into message box */ /*SAFETYMCUSW 93 S MR: 6.1,6.2,10.1,10.2,10.3,10.4 <APPROVED> "LDRA Tool issue" */ canreg->IF1NO = (uint8) msgbox; /** - Wait until data are copied into IF1 */ while ((canreg->IF1STAT & 0x80U) ==0x80U) { } /* Wait */ success = 1U; } return success; }
修改后,错误率大大下降,但是还是偶尔存在错误
现在应用是构建在高安全需求基础上的,对这个要求比较严格,希望能得到稳定的管理方案
Susan Yang 说:请问您现在错位的具体表现是什么?
消息对象的发送优先级附加在消息编号上。消息号越小优先级越高。如果有多个传输请求(传输请求X寄存器)待处理,则将优先处理优先级最高的消息。优先级较低的消息可能不会永远发送。
您可以在传输新数据之前检查所有未决的TX请求标志。例如:
if ((canreg->TXRQX != 0U) {
success = 0U;
}
您上面说的消息优先级,是在本机的mailbox里也会进行比较对吗?也就是说,即便低优先级的消息先到达mailbox,也可能比高优先级而后到的发送晚对吗?
我现在的现象是,例如:
void user_main(void) { SystemInit(); while (1) { uint8_t temp[8] = {0}; memset(temp, 0x00, 8); CANSimpleSend(canREG3, temp, 0x00); memset(temp, 0xff, 8); CANSimpleSend(canREG3, temp, 0xff); } }
理论上讲,总线上会出现ID为0xff,数据为8个0xff的帧,和ID为0x00,数据为8个0x00的帧
现在的情况是,会出现交叉,即出现ID为0x00,数据为0xff的帧,和ID为0xff,数据为0x00的帧