AVR 关全局中断的函数cli();的疑问
void system_set_exec_alarm(uint8_t code) {
uint8_t sreg = SREG;
cli();
sys_rt_exec_alarm = code;
SREG = sreg;
}
上面的这个函数的意思是不是这样
把状态寄存器的数据保存到sreg这里。
然后关全局中断的函数cli();
变量赋值
还原状态寄存器的值
后面为什么不调用sei();开中断呢?
ARM中怎么才能获得状态寄存器的值呢?
如果之前中断就是关闭的,SREG=sreg后,中断还是关闭的
如果你用sei,破坏了原来状态 有可能之前状态本来就是关闭的, 如果你强迫症成对的对称用,就得IF ELSE了,很啰嗦。 liuqian 发表于 2017-10-10 12:35
如果之前中断就是关闭的,SREG=sreg后,中断还是关闭的
如果你用sei,破坏了原来状态 ...
谢谢
这样写的好处是为了保证函数的原子操作。如果之前是关闭的,那么还写这句话干什么呢?为什么sei后就破坏了呢?
关闭之前有可能是开的,也有可能是关闭的。
如果用sei(),则将关闭的那种情况破坏了。 写入 SREG 时,就已经包含了 CLI() 或者 SEI() 了。
你把 CLI() 换成 SREG&=~(1<<7) 就看懂了:
void system_set_exec_alarm(uint8_t code) {
uint8_t sreg = SREG;
SREG&=~(1<<7); // <=> CLI()
sys_rt_exec_alarm = code;
SREG = sreg;
}
这个过程就是个 保存现场——执行原子操作——恢复现场 的过程,无论之前是否 I 置位,都不会发生错误或影响。 t3486784401 发表于 2017-10-10 18:04
写入 SREG 时,就已经包含了 CLI() 或者 SEI() 了。
你把 CLI() 换成 SREG&=~(1
非常感谢,那么请问对应的STM32F4要想实现这种原子操作该怎么写呢? 王涛 发表于 2017-10-11 09:09
非常感谢,那么请问对应的STM32F4要想实现这种原子操作该怎么写呢?
并不熟悉 NVIC 的用法,目测也是关一个中断允许位。
页:
[1]