interrupt - 了解用于禁用和恢复 SREG 中断状态的 AVR 代码
问题描述
我对如何禁用和恢复我为 8 位 AVR 处理器找到的中断状态的示例感到有些困惑。
像 ATmega 2560 这样的 8 位 AVR 处理器在状态寄存器 (SREG) 中有一个全局中断启用位(标记为“I”)。该CLI
指令通过清除该位来禁用所有中断。来自 AVR 指令集手册:
CLI - 清除全局中断使能位
描述
清除 SREG(状态寄存器)中的全局中断允许 (I) 位。中断将立即被禁用。指令后不会执行中断
CLI
,即使它与指令同时发生CLI
。(相当于指令 BCLR 7。)
AVR 指令集手册还显示了以下示例:
1 in temp, SREG ; Store SREG value (temp must be defined by user)
2 cli ; Disable interrupts during timed sequence
3 sbi EECR, EEMWE ; Start EEPROM write
4 sbi EECR, EEWE
5 out SREG, temp ; Restore SREG value (I-flag)
第 5 行的意图似乎是将 SREG 的 I-flag 恢复到它在第 2 行执行之前的值。事实上,这段代码存储了所有 SREG 标志的状态——它似乎只是假设 SREG 的其他标志的值不会在第 1 行和第 5 行之间改变。但是,如果在第 1 行和第 2 行之间发生中断,则不能它会导致一些 SREG 的其他标志被“恢复”不正确吗?
1 in temp, SREG ; Store SREG value (temp must be defined by user)
; <------- interrupt occurs here
2 cli ; Disable interrupts during timed sequence
3 sbi EECR, EEMWE ; Start EEPROM write
4 sbi EECR, EEWE
5 out SREG, temp ; Restore SREG value (I-flag)
解决方案
- 当中断发生时,CPU 将切换到中断服务程序,但在切换之前 CPU 会记住程序的位置(通过将程序计数器压入堆栈)
- CPU 将执行 ISR
- 执行 ISR 后像中断之前一样恢复 CPU 环境(SERG、GPR、SP、PC)非常重要和关键,这将由您的代码完成(如果您在中断后没有恢复 CPU 环境,您的程序将很有可能崩溃)
- CPU 将返回相同的位置(通过从堆栈中恢复 PC)
1 in temp, SREG ; Store SREG value (temp must be defined by user)
; <------- interrupt occurs here
; <-------------go to interupt handler
; <--------Rutern from interupt with same value of temp, SREG, and all GPR are same value
2 cli ; Disable interrupts during timed sequence
3 sbi EECR, EEMWE ; Start EEPROM write
4 sbi EECR, EEWE
5 out SREG, temp ; Restore SREG value (I-flag)
上面的代码只是告诉你“确保第 3,4 行将在没有中断的情况下依次执行”
如果在第 1 行和第 2 行之间发生中断,是否会导致 SREG 的某些其他标志“恢复”不正确?
如果第 1 行和第 2 行之间发生中断,则中断将在第 2 行之前处理并返回,并且任何中断代码必须保留 CPU 环境
推荐阅读
- php - 如何链接多个页面,并将插件添加到新的自定义 WordPress 主题
- netsuite - Netsuite:自定义批量处理屏幕
- vb.net - 将 SHA-2 哈希转换为字母数字哈希 (vb.net)
- android - 未调用毕加索回调
- sorting - 调整、排序和平均不同值的数字
- google-maps - 如何从颤振应用程序导航谷歌地图应用程序
- python - 获取数据库错误,NOT NULL 约束失败
- python - \b(退格)在 Python IDLE 中无法正常工作,而是打印框字符
- bootstrap-4 - Bootstrap 4 - 在 sm 或更大上显示文本,始终显示 FontIcon
- excel - 在单元格中添加工作表计数器