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.

[参考译文] TMS320F28388D:28388D 中的 MCAN 问题

Guru**** 2511415 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1557840/tms320f28388d-mcan-issue-in-28388d

器件型号:TMS320F28388D


工具/软件:

尊敬的团队:  

我 观察到与 DCAN 相比、MCAN 存在几个问题。

1.我们需要通过获取字节来准备浮点或 int 数据、否则数据与 DCAN 相比变得重叠、这是 CPU 的额外负担。 由于数据为 uint16_t、当我们仅传输 uint16_t 的低字节时、系统将进行传输。 是否有任何方法可以直接将 float 传输或传输到 MCAN_TxBufElement 或 MCAN_RxBufElement 中字段的 uint16_t DATA[]中 、例如 DCAN 中的字节外设和接口寄存器?

2.使用 TI 驱动程序库函数 (MCAN_readMsgRam、MCAN_writeMsgRam) 读取或写入消息 RAM 需要大量时间。 由于我们在中断中有 TX 和 RX、这些函数大约需要 3.2us、每个时间在中断中很重要。  由于我们在中断中轮询消息、 在 ISR 中轮询 TX 消息、因此我们是否可以缩短该时间?

  MCAN_writeMsgRam (MCANA_DRIVER_BASE、MCAN_MEM_TYPE_BUF、IDx、&TX);->约为 3.2us

  MCAN_readMsgRam (MCANA_DRIVER_BASE、MCAN_MEM_TYPE_BUF、bufIndex、0、&g_rxBuf[bufIndex]);  ->约 3.2us

提前感谢。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Yeidda:

    MCAN/DCAN 有效载荷以字节为单位。  用户必须配置数据在 CAN 帧中的组织方式。  如果要发送浮点数据、则必须了解浮点数据类型的形成方式。  根据定义、浮点数据类型是数字的 32 位表示。  这就是 IEEE 754。  例如、IEEE 754 格式的浮点数–1.234 和 3.1416 分别表示为 32 位数字 0xBF9DF3B6 和 0x40490FF9。  这也是浮点数在 C28x 中的表示方式。  也就是说、–1.234 可以在有效载荷中作为 4 个字节 0xBF、0x9D、0xF3 和 0xB6 传输、3.1416 可以作为 4 个字节 0x40、0x49、0x0F 和 0xF9 传输。  在接收节点上、您需要组织数据、以便可以重建原始 IEEE 754 格式。  由于字节序、您可能必须将字节顺序混合。

    遗憾的是、访问和传输消息 RAM 的内容是通过 driverlib 函数中使用的 IFx 寄存器实现的。  如果您使用的是 MCAN 并且不需要完整的 64 字节有效载荷、您可以尝试减少该有效载荷、以查看消息 RAM driverlib 执行时间是否减少。  

    此致、

    Joseph

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    1.我的问题与 MCAN 缓冲区元素的数据[]如何在 C28x 上键入和访问:

    Tx/WORD Rx 元素将数据[]公开为 16 位(字)存储。 在 C28x 上、当我通过 uint16_t 指针/数组进行写入时、每次写入自然会携带两个字节。 如果 I 按顺序加载 8 个有效载荷字节、它们最终会生成 data[0].data[3](四个 16 位字)、而不会占用八个不同的字节索引。

    发送时、打包逻辑会忽略每个 16 位数据[n]的“高位字节“、因此必须手动构建带有移位和掩码的按字节有效载荷、或重新打包为 32 位字、以获得预期的总线字节流。

         1.1.是否有官方支持的方式(API、pragma 或访问模式)在 F28388D 上逐字节写入/读取 MCAN 消息 RAM、从而避免在每个有效载荷上手动跳变/掩码?

         1.2.如果 MCAN MsgRAM 的 C28x 不支持字节写入、为确保以最小的开销实现正确的字节排序、TI 建议在 C2000 上使用什么打包例程? (例如,打包到 uint32_t 通道并依赖 driverlib 作为 32 位字突发?)

        1.3.当用户将 tx.data[]准备为 16 位字时、driverlib 预期的字节序/字节通道映射有没有任何指导、以便高字节不会被丢弃?

    2. MCAN_readMsgRam / MCAN_writeMsgRam 执行时间、即使 DLC=8 也是如此、我也为 8 字节配置了缓冲区

    我为 MCAN_writeMsgRam (MCANA_DRIVER_BASE、MCAN_MEM_TYPE_BUF、IDx、&TX) 和 MCAN_readMsgRam (...、&Rx)(DLC=8) 测量了~3.2µs、 在 ISR 上下文中执行。 这对我的时序预算来说很重要(我在轮询 Rx、还从 ISR 传输数据)

         2.1.是否有 driverlib 或模块配置可以在 DLC=8 时缩短这些 MsgRAM 访问时间(例如,限制有效载荷长度,不同的元素配置,缓存等)?

        2.2. driverlib 中的 if-register 传输是否是 C2000 上唯一支持的路径、或者是否有一种更快的机制(例如,任何 DMA 或备用访问模式)用于将 8 字节有效载荷移入/移出消息 RAM?

       2.3.~TI 推荐的能够尽可能缩短 ISR 时间的技术(例如预先准备的 Tx 元素、避免某些状态读取或使用特定的 API)、这些技术会显著降低每次调用的 μ V 3.2µs?

    • 提前感谢。  
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    当前的 CAN_readMessage API 不支持浮点数据传输。  C2000 中的最小数据单元是 16 位(字节)、这给打包 CAN 有效载荷带来了挑战。  您可以做的是创建 API can_readDataReg API 的副本(在 can_readMessage 中调用)、并且还创建 can_readMessage 的副本

    要读取浮点数据、请修改 can_readDataReg 的副本、并将*data 的类型更改为 float。  Youn 希望按如下方式修改代码:

    static inline void
    CAN_readDataRegFloat(float *data, const uint32_t address, uint32_t size)
    {
        uint32_t idx;
        uint32_t dataReg = address;
    
        //
        // Loop always copies 2 byte per iteration.
        //
        for(idx = 0U; idx < size; idx++)
        {
            //
            // Read out the data
            //
            data[idx] = HWREG(dataReg);
    
            dataReg+=2;
        }
    }
    

    您还需要更新 can_readMessage 的副本、以便它将调用 can_readDataReffloat。  同样也应该适用于 MCAN。

    至于 ISR 读取、当前消息 RAM 不支持 DMA、但是 F28388D 器件上有 3 个内核、因此您可能可以计划在与 CAN ISR 协商的其他内核上读取消息。  也许这会对您的时间预算有所帮助。

    此致、

    Joseph

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我们计划也使用其他内核、但目前我们正在使用其中一个内核。  MCAN_readMsgRam、MCAN_writeMsgRam 等 TI 驱动程序库函数具有 大量位移动和其他条件、这会导致时间增加、因此我们为 TX 专用缓冲器创建了如下自定义函数:

    Bool MCAN_TxBuff_fastU32 (MCAN_TxBufIndex idx_enum、uint32_t payload_word0、uint32_t payload_word1)

    uint32_t startAddr = 0U、elemSize = 0U、elemAddr = 0U;
    uint32_t idx = 0u;
    IDX = idx_enum;

    //检查 TX 缓冲区是否空闲
    if (*(volatile uint32_t *)(MCANA_DRIVER_BASE + MCAN_TXBRP)&(1UL <<(uint32_t) idx))

    返回 false;
    }

    startAddr = HW_RD_FIELD32 (MCANA_DRIVER_BASE + MCAN_TXBC、MCAN_TXBC_TBSA);
    elemSize = HW_RD_FIELD32 (MCANA_DRIVER_BASE + MCAN_TXESC、MCAN_TXESC_TBDS);
    startAddr =(uint32_t)(startAddr << 2U);
    elemSize = MCAN_getMsgObjSize (elemSize)* 4U;
    elemAddr = MCANA_DRIVER_BASE + MCAN_MCAN_MSG_MEM + startAddr +(elemSize * idx);

    //写入新数据
    HW_WR_REG32 (elemAddr + 8U、payload_word0);
    HW_WR_REG32 (elemAddr + 12U、PAYLOAD_word1);
    HW_WR_FIELD32 (MCANA_DRIVER_BASE + MCAN_CCCR、MCAN_CCCR.CCE、0x0U);
    HW_WR_REG32 (MCANA_DRIVER_BASE + MCAN_TXBAR、(1UL <<(uint32_t) idx));
    返回 true;
    }

    我只是想知道,如果我使用像上面一样的时间减少到 50%的原稿会有任何问题.

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您当然可以使用自己的例程来读取消息 RAM 内容。  driverlib API 不一定是为优化速度而编写的、因此消除位移位有助于减少开销。  在此特定应用中、我看到您会在写入前首先检查缓冲区是否是空闲的。  这是正确的方法。  我认为实施没有任何问题。  如果您没有 TOTHER 问题、我会将此帖子标记为已关闭、否则请随时在此处发布。  

    此致、

    Joseph