AVR:main()/ISR 干扰
AVR: main()/ISR interference
我在 C 中的 ATmega168(从)上使用 I2C(使用 avr-gcc 编译),但这可能是关于中断的一般问题。
在我的 C 程序中,我有一个 uint8_t i2c_buffer[32]
类型的全局变量,用于存储一些传感器和配置数据。每当总线主机读取或写入从机时,I2C-ISR 也会访问该数组。
由于通信是在硬件中驱动的,因此到 ram(我的 I2C 缓冲区变量)的传输是由中断触发的。
我知道由于 ISR 和我的主例程之间的竞争条件,不小心从 ISR 和主例程访问变量可能会导致数据损坏,但我不确定如何正确处理这个问题。
有人告诉我在 main 访问相关变量时禁用中断。
这将保护变量不被损坏,但另一方面这不会导致数据丢失吗?
如果主机在中断被禁用时尝试发送数据怎么办?
我猜,由于 I2C 接口仍处于启用状态,输入字节至少会写入 TWDR。那是对的吗?
如果是:有没有办法在主例程完成访问变量后立即触发 ISR?
并且:如果一个实例(ISR 或 main)仅读取而不写入缓冲区的特定部分,此问题是否仍然存在?
一般需要在主进程(main program)中创建临界区。当您的主程序访问共享变量时,您需要禁用中断。
您有一个现成的标准解决方案:
#include <util/atomic.h>
/* ....*/
ATOMIC_BLOCK(ATOMIC_FORCEON)
{
/* potentially non atomic opeartions */
}
我在 C 中的 ATmega168(从)上使用 I2C(使用 avr-gcc 编译),但这可能是关于中断的一般问题。
在我的 C 程序中,我有一个 uint8_t i2c_buffer[32]
类型的全局变量,用于存储一些传感器和配置数据。每当总线主机读取或写入从机时,I2C-ISR 也会访问该数组。
由于通信是在硬件中驱动的,因此到 ram(我的 I2C 缓冲区变量)的传输是由中断触发的。
我知道由于 ISR 和我的主例程之间的竞争条件,不小心从 ISR 和主例程访问变量可能会导致数据损坏,但我不确定如何正确处理这个问题。 有人告诉我在 main 访问相关变量时禁用中断。 这将保护变量不被损坏,但另一方面这不会导致数据丢失吗? 如果主机在中断被禁用时尝试发送数据怎么办?
我猜,由于 I2C 接口仍处于启用状态,输入字节至少会写入 TWDR。那是对的吗? 如果是:有没有办法在主例程完成访问变量后立即触发 ISR?
并且:如果一个实例(ISR 或 main)仅读取而不写入缓冲区的特定部分,此问题是否仍然存在?
一般需要在主进程(main program)中创建临界区。当您的主程序访问共享变量时,您需要禁用中断。
您有一个现成的标准解决方案:
#include <util/atomic.h>
/* ....*/
ATOMIC_BLOCK(ATOMIC_FORCEON)
{
/* potentially non atomic opeartions */
}