gpt4 book ai didi

c - Arm assembly 中的意外时序

转载 作者:行者123 更新时间:2023-12-04 08:47:29 26 4
gpt4 key购买 nike

我需要一个非常精确的时间,所以我写了一些汇编代码(用于 ARM M0+)。
但是,在示波器上进行测量时,时间并不是我所期望的。

#define LOOP_INSTRS_CNT                 4 // subs: 1, cmp: 1, bne: 2 (when branching)
#define FREQ_MHZ (BOARD_BOOTCLOCKRUN_CORE_CLOCK / 1000000)
#define DELAY_US_TO_CYCLES(t_us) ((t_us * FREQ_MHZ + LOOP_INSTRS_CNT / 2) / LOOP_INSTRS_CNT)

static inline __attribute__((always_inline)) void timing_delayCycles(uint32_t loopCnt)
{
// note: not all instructions take one cycle, so in total we have 4 cycles in the loop, except for the last iteration.
__asm volatile(
".syntax unified \t\n" /* we need unified to use subs (not for sub, though) */
"0: \t\n"
"subs %[cyc], #1 \t\n" /* assume cycles > 0 */
"cmp %[cyc], #0 \t\n"
"bne.n 0b\t\n" /* this instruction costs 2 cycles when branching! */
: [cyc]"+r" (loopCnt) /* actually input, but we need a temporary register, so we use a dummy output so we can also write to the input register */
: /* input specified in output */
: /* no clobbers */
);
}

// delay test
#define WAIT_TEST_US 100
gpio_clear(PIN1);
timing_delayCycles(DELAY_US_TO_CYCLES(WAIT_TEST_US));
gpio_set(PIN1);
非常基本的东西。但是,延迟(通过将 GPIO 引脚设置为低电平、循环然后再次设置为高电平来测量)时序始终比预期高 50%。我尝试了低值(1 us 给 1.56 us),最多 500 ms 给 750 ms。
我尝试单步执行,循环实际上只执行 3 个步骤:subs (1)、cmp (1)、branch (2)。括号是预期的时钟周期数。
任何人都可以阐明这里发生了什么吗?

最佳答案

经过一些好的建议,我发现问题可以通过两种方式解决:

  • 以相同频率运行内核时钟和闪存时钟(如果代码从闪存运行)
  • 将代码放在 SRAM 中以避免闪存访问等待状态。

  • 注意:如果有人复制了上面的代码,请注意您可以删除 cmp,因为 subs 设置了 s 标志。如果这样做,请记住将指令计数设置为 3 而不是 4。这将为您提供更好的时间分辨率。

    关于c - Arm assembly 中的意外时序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64240957/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com