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.

[参考译文] EK-TM4C129EXL:获得固定周期短延迟

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1247941/ek-tm4c129exl-getting-a-fixed-period-short-delay

器件型号:EK-TM4C129EXL

您好!

我需要定时器 A 的两个部分以相同的频率运行(2.5MHz @ CPU 时钟= 120MHz)、但它们之间存在一定的相移。

下面的代码在理论上是所需的、但如果代码发生变化、执行时间可能会有所不同-我怀疑这是由于流水线等原因。

TimerEnable (TIMER0_BASE、TIMER_B);

_ nop();
_ nop();
_ nop();
_ nop();
_ nop();
_ nop();
_ nop();
_ nop();
_ nop();
_ nop();
_ nop();
_ nop();

TimerEnable (TIMER0_BASE、TIMER_A);

另一个选项是__delay_cycles 内在函数、该内在函数携带警告:

请注意:周期时序基于0个等待状态。
结果因其他等待状态而异。 为
实现不考虑动态
预测。 对于较大的输出电压、
考虑到流水线清除行为、准确性较低。

-测试时表现相同。

我知道将清空管线的指令"isb"。 您能建议在此实例中如何使用此值、或者以其他方式获得所需延迟、使其与周围代码更改无关吗? 此代码只需要在系统启动时运行一次。

谢谢!

马修

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

    我发现这似乎回答了我的问题:

    CCS/EK-TM4C129EXL:EK-TM4C129EXL:延迟时间-基于 Arm 的微控制器论坛-基于 Arm 的微控制器- TI E2E 支持论坛

    因此、使用 MAP_SysCtlDelay (在 ROM 中)将避免预取问题:

    "为了获得更高的精确度、可以使用此功能的 ROM 版本。 该版本不会受到与闪存和完整缓冲区相关的计时变异的影响、但仍会因中断服务例程而延迟。"

    我尝试过这个方法、但它没有解决 问题、这表明预取不会导致我看到的问题。

    我尝试将代码放入函数中以确保一致的对齐:

    __attribute__(已对齐(4))) void set_hw_timers (void)
    {
    SET_TEST_PIN();
    TimerEnable (TIMER0_BASE、TIMER_B);
    MAP_SysCtlDelay (4);
    TimerEnable (TIMER0_BASE、TIMER_A);
    clear_test_pin ();

    同样、这并没有解决这个问题。

    这种可变性似乎会在各个编译之间发生、因此添加/删除程序中其他位置的代码会影响上述代码的执行时间。 可以在逻辑分析仪上看到该差异。 此程序中没有优化、运行代码时也没有中断。

    谢谢。

    马修

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    "要获得更高的精确度,可以使用此函数的 ROM 版本。 该版本不会受到与闪存和完整缓冲区相关的计时变异的影响、但仍会因中断服务例程而延迟。"

    Matthew、您好!

     ROM_SysCtlDelay 将从 ROM 执行单周期代码。 没有像闪存中那样的引脚。 闪存本身的单周期存取时间更短、因此流水线作业进入图片、以便在 CPU 读取之前提前读取。  

    我尝试将代码放入函数中以确保一致的对齐:

    __attribute__(已对齐(4))) void set_hw_timers (void)
    {
    SET_TEST_PIN();
    TimerEnable (TIMER0_BASE、TIMER_B);
    MAP_SysCtlDelay (4);
    TimerEnable (TIMER0_BASE、TIMER_A);
    clear_test_pin ();

    同样、这并没有解决这个问题。

    这种可变性似乎会在各个编译之间发生、因此添加/删除程序中其他位置的代码会影响上述代码的执行时间。 可以在逻辑分析仪上看到该差异。 此程序中没有优化、运行代码时也没有中断。

    [/报价]

    SET_TEST_Pin ()和 CLEAR_TEST_Pin ()之间有多少个周期? 我建议您不要调用 SET_TEST_Pin 和 CLEAR_TEST_Pin、因为从闪存中提取代码时、这两个函数将受到流水线的影响。 您能否直接使用 HWREG 来设置和清除引脚。 也可以通过直接使用 HWREG 启用 Timer_B 和 Timer_A 来启用 TimerEnable。 另一个方法是调用 ROM_TimerEnable 而不是 TimerEnable。 您需要对 SET_TEST_Pin 和 CLEAR_TEST_Pin 中的任何 API 调用执行相同的操作、以便仅使用 ROM 版本。 希望您可以更好地控制周期。  

     

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

    尊敬的 Charles:

    谢谢你的建议,我会尝试这些事情,让你知道我如何得到.

    此致、

    马修

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

    尊敬的 Charles:

    我做了一些测试。

    首先,我发现,当使用下面一行 作为测试来关闭预取时,变异性就会消失:

    HWREG (FLASH_CONF)= FLASH_CONF_FPFOFF;

    然后、我按照建议(如下)更改了程序。 直到我将函数放入 RAM 中、仍然存在一些可变性、现在所有构建的周期看起来都相同。

    我不会自己尝试这样做、但出于好奇心、您是否曾有客户永久关闭预取? 这显然会减慢应用的速度、但会使时序更具确定性、这在某些情况下很重要。

    __attribute__((ramfunc)) void start_timer0_a_b (void)
    {
    //注释:为了获得正确的相位,需要为双边时钟偏移定时器启动
    //连续时钟与 SSI 时钟之间。
    #IF 1
    MAP_GPIOPinWrite (GPIO_PORTD_BASE、GPIO_PIN_2、GPIO_PIN_2); //设置测试引脚
    MAP_TimerEnable (TIMER0_BASE、TIMER_B);// DMA


    _ nop();
    _ nop();
    _ nop();
    _ nop();

    //调整 NOP 以获得所需的相移

    MAP_TimerEnable (TIMER0_BASE、TIMER_A);// PWM
    MAP_GPIOPinWrite (GPIO_PORTD_BASE、GPIO_PIN_2、0);           //清除测试引脚
    #endif

    此致、

    马修

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    在我把函数放入 RAM 之前,仍然存在一些变异性,现在所有版本的周期似乎都相同。

    Matthew、您好!

     看起来您在没有可变性的构建中找到了一致的解决方案。 RAM 访问始终为单周期。 话虽如此、如果你从 RAM 中运行此函数、那么我认为你无需关闭针对闪存的预取、因为预取将不会影响从 RAM 中执行代码。 这是您看到的内容吗?

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

    尊敬的 Charles:

    没有-我没有很好地解释它。 我只是暂时关闭了预取来查看它是否导致了问题,只是为了证明一个点,然后我再次将其打开并保持它。

    没错、我展示的从 RAM 运行的代码显示了在启用预取的默认状态下没有任何变异性。

    此致、

    马修

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    从 RAM 运行时,显示预取在默认启用状态下不存在可变性。

    Matthew、您好!

     感谢您的确认。