arm - 启用外设定时器和定时器实际开始计数之间是否有延迟?这是什么延迟,是什么原因造成的?
问题描述
我正在尝试配置一个计时器(TIM9)及其中断处理程序以单步执行程序。我的方法是先中断第一条指令,然后在中断处理程序中配置定时器,使其在从 ISR 返回后立即触发中断。
现在,我仍在尝试正确迈出第一步。
这是我现在正在使用的示例代码。我已将定时器配置为在其计数器等于某个比较值时生成中断。我将比较值设置为 1,以便代码在定时器的 1 个周期后被中断。根据参考手册,计数器在设置启用位后开始计数 1 个周期,所以我添加了一个 NOP。
/*
* TIM9 is configured to generate an interrupt when counter s equal to compare value
*/
TIM9->CCR1 = 1; // set compare 1 value to 1
TIM9->CR1 |= 1; // enable TIM9
__ISB(); // flush pipeline
__asm volatile ("NOP"); // from reference manual: counter starts counting 1 cycle after setting CEN bit
__asm volatile("MOV r8, #1 \n\t"); // expect to interrupt this instruction
__asm volatile("MOV r8, #2 \n\t");
__asm volatile("MOV r8, #3 \n\t");
__asm volatile("MOV r8, #4 \n\t");
为了验证正确的指令是否被中断,我在进入中断处理程序后使用 GDB 检查寄存器 r8 的内容,我发现它实际上等于 6。这意味着延迟比 1 个周期长得多,或者我我只是错过了一些东西。
我可以简单地在第一条 MOV 指令之前添加 5 条 NOP 指令,以便在正确的时间发生中断,但我不明白为什么这是必要的。据我所知,我现在拥有的代码应该在第一条 MOV 指令期间产生一个中断。
为什么我会出现这种行为?为什么在启用定时器和产生中断之间似乎有这么长的延迟?
这可能是因为计数器值等于比较值与实际产生中断之间存在延迟吗?
或者这可能与管道的工作方式有关?
我已将定时器的预分频器设置为 0,并且没有发生内部时钟分频,因此定时器应该与系统时钟具有相同的频率。
解决方案
我不知道你为什么要检查它。它按预期工作。
- NOP 是添加延迟的最坏方法。它与 8 位 AVR 的 NOP 不同。它会立即从管道中冲出,并且只能用作填充。
- CEN 之后的 1 个时钟表示一个定时器时钟,而不是 HCLK 时钟(它们可以相同)
- CCRx = 1 表示两个时钟。
- 如果您从 FLASH 运行 - 添加等待状态
- 管道执行状态不容易确定。被中断的实际指令不一定是您实际认为的指令。中断的时间是确定的,而不是实际的指令。
推荐阅读
- javascript - 表单提交后停止页面重定向到php文件
- typo3 - 如何在 TYPO3 中设置默认 colPos
- openstack-cinder - 显示所有项目的煤渣配额使用情况?
- mysql - MySQL - 复制或更新一个表中的更改行
- apache-kafka - kafka 的 Confluent 和 Spring 模式注册表
- javascript - 浏览器 | 如何要求以前由 Browserify 创建的模块?
- mysql - MySQL 查询优化 LEFT JOIN 和 DISTINCT
- javascript - 如何防止ios中的后滑反应本机
- python - python在if语句中引发异常
- r - 尽管 xpath 似乎是正确的,但找不到元素