我使用带有ARM Cortex-M4处理器的STM32F429。我的前提是我不知道ARM的组装,但我需要优化代码。我读了
的解决方案How to measure program execution time in ARM Cortex-A8 processor?
这就是我需要的,但该解决方案适用于Cortex-A8。一时兴起,我尝试在我的代码上实现上面的链接代码,但我在这一点上获得了一个SEGV:
if (enable_divider)
value |= 8; // enable "by 64" divider for CCNT.
value |= 16;
// program the performance-counter control-register:
asm volatile ("MCR p15, 0, %0, c9, c12, 0\t\n" :: "r"(value)); /*<---Here I have SEGV error*/
// enable all counters:
asm volatile ("MCR p15, 0, %0, c9, c12, 1\t\n" :: "r"(0x8000000f));
// clear overflows:
asm volatile ("MCR p15, 0, %0, c9, c12, 3\t\n" :: "r"(0x8000000f));
如何调整此汇编代码以在ARM Cortex-M4上执行?
答案 0 :(得分:1)
抛弃Cortex-A8方法。
对于大多数基于Cortex-M的微控制器来说,这是正确的方法(不要使用SysTick!):
LDR
指令轮询计时器值。NOP
指令,然后运行您要测量的代码。NOP
指令,然后在结束测量时使用单个LDR
指令轮询计时器值。 NOP
说明是为了准确,以确保流水线操作不会影响您的结果。
这在Cortex-M3上是必需的,因为一条LDR
指令需要两个时钟周期。两个连续的LDR
指令可以流水线化,因此它们总共只需要3个时钟周期。
有关指令集时序的更多信息,请参见ARM信息中心的Cortex-M4 Technical Reference Manual。
当然,您应该从内部SRAM运行代码,以确保它不会因慢速闪存而减慢速度。
我不能保证这在所有设备上都是100%周期精确的,但它应该非常接近。 (见下面的Chris&#39;评论)。您还应该知道这是为了在没有中断的环境中使用。