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.

[参考译文] TMDX570LC43HDK:DMA CAN##39;t 正确读取某些数据(尝试 SCI TX)

Guru**** 2386600 points
Other Parts Discussed in Thread: TMDX570LC43HDK, TMS570LC4357, HALCOGEN
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1469916/tmdx570lc43hdk-dma-can-t-read-some-data-correctly-trying-to-sci-tx

器件型号:TMDX570LC43HDK
主题中讨论的其他器件: TMS570LC4357HALCOGEN

工具与软件:

您好!

我正在修整 TMDX570LC43HDK (TMS570LC4357 MCU)。 我当前正在尝试使用 DMA 通过 SCI 发送数据、但读取并不总是有效。

以下是我的最小可重现示例代码:

/**
srcs	unsigned char *[2]	[0x0000D218 {72 'H'},0x08000294 {72 'H'}]	0x08000284	
[0]	unsigned char *	0x0000D218 "Hello, wor..."	0x08000284	
[1]	unsigned char *	0x08000294 "Hello, wor..."	0x08000288	
 */

void func(void)
{
    // Enable MPU first
    _enable_interrupt_();
    _mpuInit_();
    _mpuEnable_();

    // Initialize peripherals
    sciInit();
    dmaDisable();
    dmaEnable();

    uint8_t *src1 = "Hello, world!\r\n";
    uint8_t src2[] = {'H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!', '\r', '\n'};
    uint32_t count = sizeof(src2) / sizeof(src2[0]);
    uint8_t *srcs[] = {src1, src2};
    
    for (uint8_t i = 0; i < 2; i++)
    {

        g_dmaCTRL g_dmaCTRLPKT = {
            .SADD = (uint32_t)srcs[i],
            .DADD = ((uint32_t)&sciREG1->TD) + 3, // TMS570LC4357 is big endian
            .CHCTRL = 0,
            .FRCNT = count,
            .ELCNT = 1,
            .ELDOFFSET = 0,
            .ELSOFFSET = 0,
            .FRDOFFSET = 0,
            .FRSOFFSET = 0,
            .PORTASGN = PORTA_READ_PORTB_WRITE,
            .RDSIZE = ACCESS_8_BIT,
            .WRSIZE = ACCESS_8_BIT,
            .TTYPE = FRAME_TRANSFER,
            .ADDMODERD = ADDR_INC1,
            .ADDMODEWR = ADDR_FIXED,
            .AUTOINIT = AUTOINIT_OFF,
        };

        dmaReqAssign(DMA_CH0, DMA_REQ29);
        dmaReqAssign(DMA_CH29, DMA_REQ0);
        dmaSetCtrlPacket(DMA_CH0, g_dmaCTRLPKT);
        dmaSetChEnable(DMA_CH0, DMA_HW);
        sciREG1->SETINT = (1 << 8) | (1 << 16);

        while ((dmaREG->BTCFLAG & (1 << DMA_CH0)) == 0)
        {
        }
        dmaREG->BTCFLAG = (1 << DMA_CH0);
        sciREG1->CLEARINT = (1 << 8) | (1 << 16);
    }

    while (1)
    {
    }
}

此代码执行简单的操作:从 src1读取并通过 sci 发送、然后从 src2读取并再次通过 sci 发送、然后停止。

src1和 src2包含的"Hello、world!"数据相同 两者都使用 DMA 发送、但只有 src1传输成功。 对于 src2、远程器件接收填充为0的数据而不是原始数据。

我怀疑问题与他们的记忆位置有关。 指向常量字符数组的 src1为0x0000D218、而 src2、本地 uint8_t 数组为0x08000294。

但我不知道究竟是什么导致了这个问题以及如何解决它。 我未设置 DMA 内存保护。  

谢谢!

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

     

    似乎是高速缓存问题。 我认为缓存保存的是数据、而不是实际的 RAM 存储器、但是 DMA 会尝试访问实际的 RAM 存储器以进行数据传输、因此缓存保存的数据为零。

    您可以通过以下几种方式解决此问题:

    1.  

    简单的方法是禁用缓存:

    完全禁用高速缓存并验证代码、您可以通过取消选中 HALCoGen 中的以下复选框来禁用高速缓存:

    2.  

    另一种方法是、我们可以启用缓存、但我们需要配置 对相应 RAM 区域的"直写"操作

    我在下面的主题中解释了此方法:

    (+) RM57L843:无法开始 EMAC 传输-基于 Arm 的微控制器论坛-基于 Arm 的微控制器- TI E2E 支持论坛

    如果我们将直写式存储器设置为一个区域、则对相应区域的任何写入都会更新缓存和主存储器、因此该问题应该得到解决。

    ——
    谢谢、此致、
    Jagadish。

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

    谢谢! 确实是高速缓存的问题。 我来自 RM48、它没有高速缓存、所以它完全脱离了我的视线。

    目前、我导入了 example_sys_cache.c/h 文件并使用 coreCleanDCByAddress 函数来清理特定的数据缓存。