首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在没有计时器的情况下,将手臂皮质M0+延迟n个周期?

如何在没有计时器的情况下,将手臂皮质M0+延迟n个周期?
EN

Stack Overflow用户
提问于 2014-12-16 17:15:15
回答 2查看 14.3K关注 0票数 5

我想将ARM Cortex M0+延迟n个周期,而不使用计时器,代码大小尽可能小。(我认为这要求使用集会。)

0循环的延迟很简单,没有代码。一个周期的延迟是一个NOP。两个周期的延迟是两个NOPs。

在什么时候开始循环(代码大小)是有效的?

最紧的循环需要多少周期?设置时间是几点?

贴上答题:

以下C代码:

代码语言:javascript
运行
复制
register unsigned char counter = 100;
while (counter-- > 0) {
  asm("");
}

当使用gcc和-O3编译时:

代码语言:javascript
运行
复制
    mov r3, #100
.L5:
    sub r3, r3, #1
    uxtb    r3, r3
    cmp r3, #0
    bne .L5

这要么说明手工编码ARM程序集仍然有目的,要么(更有可能)说明上面的C代码不是向编译器传达我想要做的事情的最佳方式。

评论?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-12-16 20:57:11

代码将取决于具体的n是什么,以及它是否需要动态变量,但是给定M0+核心的指令时序,为特定例程建立边界是非常简单的。

对于最小的(6字节)完全循环,有一个固定的8位直接计数器:

代码语言:javascript
运行
复制
   movs  r0, #NUM    ;1 cycle
1: subs  r0, r0, #1  ;1 cycle
   bne   1b          ;2 if taken, 1 otherwise

有了NUM=1,我们可以得到至少3个循环,再加上在765个循环(当然,您可以从NUM=0获得2^32次迭代,但这似乎有点傻)的每个额外循环到NUM=255的3个循环。这使得循环的下界在大约6个周期内是实用的。有了一个固定的循环,就很容易将NOPs (甚至嵌套循环)放入其中,以延长每次迭代,并在前后对齐循环长度的非倍数。如果您可以在需要开始等待之前在寄存器中安排许多迭代,那么您可能会丢失初始的mov,并且几乎有3个或多个循环的倍数,减去一个。如果您需要对可变延迟进行单周期解析,则初始设置成本将更高一些,以便对其余部分进行校正(我会这样做:将计算出的分支放入NOP雪橇中)。

我假设,如果您正处于周期关键时间点,您已经中断了(否则会在CPSID的某个地方添加另一个循环),并且您没有任何总线等待状态,将额外的周期添加到指令获取中。

至于在C中尝试这样做:您必须黑进一个空的asm,以防止“无用”循环被优化掉,这是一种提示。抽象的C机器没有“指令”或“循环”的概念,所以根本就没有办法用语言可靠地表达这一点。试图依赖特定的C结构来编译到合适的指令是极其脆弱的--更改编译器标志;升级编译器;更改影响寄存器分配的远程代码,从而影响指令的选择;等等--几乎任何事情都可能意外地更改生成的代码,所以我认为手工编码的程序集是循环精确代码的唯一合理方法。

票数 8
EN

Stack Overflow用户

发布于 2014-12-16 20:55:38

我能想到的最短的手臂循环是这样的:

代码语言:javascript
运行
复制
mov r0, #COUNT
L:
subs r0, r0, #1
bnz L

因为我没有这个设备,所以不知道时间。这些都是核心依赖。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27510198

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档