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.

[参考译文] DK-TM4C129X:估算散聚传输的 UDMA 处理时间

Guru**** 2535150 points
Other Parts Discussed in Thread: ADS8598S

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/771658/dk-tm4c129x-estimating-udma-processing-time-for-a-scatter-gather-transfer

器件型号:DK-TM4C129X
主题中讨论的其他器件:ADS8598S

我正在进行一个时序关键型 ADC 卸载过程、我已经开始工作了、但下游处理所需的时间比我想的长大约50%。 ADC 是一款8通道18位 SAR、我使用20MHz SPI (QSSI)和 UDMA 在大约4.8us 的时间内卸载它。 这将为我提供一个9 x 16位块、其中8 x 18位样本通过"条形轮询"进行采样。 目前、我正在使用 UDMA 存储器散聚传输将18位采样解压为32位字。 然后、我将32位字移出以使数据正确对齐、并将结果复制到输出队列。 使用本地优化代码时、对齐和复制过程大约需要1.5 us。  

但是、在处理器以60 MHz 运行时、使用处理器内存时、散聚 UDMA 过程似乎需要大约6 us 的时间。 该过程进行8次传输、每次传输3个字节。 总线没有其他 DMA 处理争用。 理想情况下、我希望在3us 以下进行解压缩处理、这使我能够以100kHz 的频率运行 ADC。

6us 对于8 x 3字节 UDMA 散聚交易是否听起来正确?

哪些因素可能会影响总交易时间?

我的设置代码是:

//设置散聚处理以从 DMA 解压18位样本
//缓冲区到32位样本块
uint8_t *字节源= reinterpret_cast (sDMARxBuffer);
size_t taskIdx = 0;

while (*输入枚举&& taskIdx < 8)
{
size_t srcByteOffset =(*输入枚举-1)* 18 / 8;

++输入基准;
sSampleXferTable[taskIdx]= uDMATaskStructEntry(
3、UDMA_SIZE_8、
UDMA_SRC_INC_8、字节源+ srcByteOffset、
UDMA_DST_INC_8、sSamplesUnpackBuffer + taskIdx、
UDMA_ARB_2、
!*输入枚举? UDMA_MODE_AUTO:UDMA_MODE_MEM_散 射收集
);
++taskIdx;
}

IntRegister (UDMA_INT_SW、CommitSamples);
IntEnable (UDMA_INT_SW);
uDMAChannelAttributeEnable (UDMA_CHANGE_SW、0);

//提供散聚 DMA 处理高优先
级 UDMA_PRIOSET_R = 1 << UDMA_CHANGE_SW;

//设置解压指针
uDMAChannelScatterGatherSet (UDMA_CHANGE_SW、8、sSampleXferTable、0);

我是否可以通过另一种方法来解决此问题? 一种可能是 ADC 卸载和样本解压缩 UDMA 流程重叠、但我在这方面没有取得太大成功。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    使用散射/聚光进行解包将不会非常有效。 由于样本数是动态的、因此您需要花费 CPU 时间来设置任务列表。 然后、对于您传输的每3个字节、您将有额外的3个周期的 UDMA 内存到外设传输以加载下一个任务。

    您是否考虑过使用外设散聚模式从 SSI 复制到每个通道的单独存储器阵列? 这样、当 SSI 接收到下一个数据时、就会进行传输和解包。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Bob:

    当我知道需要哪些通道时、设置在开始采样时仅发生一次、因此设置开销非常不相关。 每个采样块的 CPU 开销在几个中断处理程序中:

    void UnpackSamples()
    {//
    DMA 传输后 SSI1 uDMA 的中断处理程序。
    SetRGBLed (BLULed | GRNLed);
    
    //调试
    +++*sSampleTxBuffer;
    
    //在 SSI1传输后清理
    SSIDMADisable (SSI1_BASE、SSI_DMA_TX | SSI_DMA_RX);
    SSI1_ICR_R = SSI1_RIS_R;//清除暂挂的 SSIDMA_TX
    
    
    ~
    
    
    (SSI1_DMA_RX);* SSIRF_DR_R_R_R_R_R_R_R_R_R_RTO_R= SSING_R_R_R_R_RING_TRING_TRIP_TRIP_TRIP_TRIP_TRIP_TRIP_TRIP_TRIP_TRIP_TRIP_TRIP_TRIP_TRIP_TRIP_TRIP_TR
    
    //启动样本解压并提交处理
    uDMAChannelScatterGatherSet (UDMA_CHANGE_SW、8、sSampleXferTable、0);
    NVIC_EN1_R |= 1 <<(44 - 32);//启用 UDMA SW 中断
    UDMA_ENASET_R |= 1 << UDMA_REST=
    
    
    
    
    
    
    
    
    1 (UDMA_SND = 1);AULT_ENCC1 (UDMA_SND = 1)= 1 (UDMA_REST = 1);ENCC3 (UDMA_SND = 1) CC1 (UDMA_SND = 1);EN1 (UDMA_EN1)= EN1 (UDMA_SND = EN1) //清除暂挂的 UDMA SW 中断
    NVIC_DIS1_R =1 <<(44 - 32);//并禁用 IT
    
    Int32_t *至= gSampleBuffer->mBuffer[gSampleBuffer->mNextIn].mChanSamples;
    Int32_t *自= sSampleUnFFFFBuffer;
    
    *至++=*(
    
    从*12+至+)+;从*12+至++至++(++至++至++);从*12+至++至++至++
    *T++=(*从++<<8)和0xFFFFFFC000;
    *到++=(*从++<< 14)和0xFFFFFFC000;
    *到++=(*从++<< 12)和0xFFFFFFC000;
    *到++=(*从+<<10)和0xFFFFFFC000;
    到+SampleC000
    
    缓冲
    区(*从+8)(*到+SampleC000缓冲区)
    gSampleBuffer->mNextIn = 0;
    
    if (gSampleBuffer->mNextOut =gSampleBuffer->mNextIn)
    //缓冲区溢出。 放入最早的样本。
    if (gSampleBuffer->mNextOut =gSampleBuffer->mNextIn
    &&&&+gSampleBuffer->mNextOut >= kSampleBufferSize
    )
    gSampleBuffer->mNextOut = 0;
    
    SetRGBLed (LEDSOff);
    }
    

    每种模式的运行时间约为1.5us、并针对调优的速度进行本地优化。

    整个任务的关键在于、ADC (ADS8598S - 8通道18位 SAR)生成8 x 18位的打包流、从而提供一个144位块(9 x 16位字)、其中18位样本字条形码通过块进行轮询。 SSI 的字长范围为4至16位、因此不会本地处理 ADC 的18位样本。 我可以通过传输9 x 16位字并手动处理 ADC 的 SPI 使能线来解决这一问题、但我遇到了解包问题。

    嗯、我可以将 SSI 设置为使用9位字。 我仍然需要执行一些后处理、以将每个样本的两个9位值组合成适当对齐的32值、但我已经完成了大部分工作、并且速度相当快。

    我将告诉您我是如何开始的。 不过、可能需要几天时间才能回到这项任务-在我处理其他事项时、这项任务被搁置了。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    使用9位 SSI 传输、而不是16位、可以将采样率从每采样约16us 降至约8us。

    UDMA 处理时间或 UDMA 传输结束时的中断延迟存在一些变化。 在大多数情况下、我看到从 SPI 传输结束到传输中断结束中断处理开始的时间大约为0.6us。 每1ms 或0.7ms (周期会交替!) 我看到3 - 4us 中断延迟。 有什么想法吗? 我想 USB SOF 是固定的1ms、但实际上不是。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    RAM 总线上的 CPU 活动量和外设总线将影响 UDMA 传输的时间。 CPU 始终具有优先级。 响应中断请求的时间因当前指令执行所需的周期数而异、即使没有处理其他中断。 但是、该延迟的交替性质意味着它与应用相关。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    事实证明、代码的几个部分在禁用中断方面有点激进! 只需稍微考虑需要禁用的内容、并保证中断的优先级。

    我通过以下方式跟踪了该问题:使用 Saleae 逻辑分析仪查看备用 I/O 位、并注释掉代码块。 借助逻辑分析仪、我可以使用基于脉宽的事件检测轻松搜索长脉冲(8us - 11us!)、间隔数百个脉冲。 很棒的工具!