x-r*_*ray 10 arduino isr esp8266 arduino-esp8266
我读到我需要将 ICACHE_RAM_ATTR 宏添加到中断服务例程 (ISR) 以及在我的 ESP8266 Arduino 代码中从那里调用的每个函数,以防止随机崩溃。我还找到了对宏 ICACHE_RAM_ATTR 的作用的解释,尽管我不确定该解释是否适用于 Espressif ESP8266 SDK,也适用于 ESP8266 上的 Arduino。我不明白为什么我需要将宏添加到 ISR。
第一个问题:为什么我需要将 ICACHE_RAM_ATTR 宏添加到 ISR 以及从那里调用的所有函数?
下一个问题是,如果我强制内联从 ISR 调用的函数会发生什么:
inline void doStuff() __attribute__((__always_inline__)) { // <-- necessary to add ICACHE_RAM_ATTR here?
// no more function calls here
}
void ICACHE_RAM_ATTR handleInterrupt() {
doStuff();
}
Run Code Online (Sandbox Code Playgroud)
第二个问题:我是否需要将 ICACHE_RAM_ATTR 宏添加到强制内联的函数中?
Adr*_*ano 19
ICACHE_RAM_ATTR 和 ICACHE_FLASH_ATTR 是链接器属性。一旦你编译你的草图,你就可以说这个函数应该存储在 RAM 还是 FLASH 中(通常你不设置任何东西:没有缓存)。
ESP8266 是多任务处理,ESP32 有 2 个内核。因此,您可以将代码作为多线程执行 - 因为它使用 RTOS。
现在的问题是:整个闪存都用于程序和存储。读取和写入闪存只能通过 1 个线程完成。如果您尝试通过 2 个不同的线程同时访问闪存,您的 ESP 可能会崩溃。
这是因为您可以将函数放在 RAM 中而不是闪存中。所以即使你在 EEPROM 或 flash 中写东西,也可以在不访问 flash 的情况下调用这个函数。
随着ICACHE_RAM_ATTR你把功能放在 RAM 上。
随着ICACHE_FLASH_ATTR你把功能放在FLASH上(以节省RAM)。
中断函数应该使用 ICACHE_RAM_ATTR。经常调用的函数不应使用任何缓存属性。
重要提示:切勿在中断内访问您的闪存!中断可能发生在闪存访问期间,因此如果您尝试同时访问闪存,则会发生崩溃(有时在您使用设备后 1-2 小时后会发生这种情况)。
由于您只有 32kb 的 IRAM(指令 RAM),您应该尝试仅将中断函数放入 RAM 中,而不是所有函数,即使有可能这样做。
第二个问题: 不,绝对不!inline 是另一个编译器标志,因此编译器会尝试将整个函数放在调用者函数中 => 将函数调用转换为 main 中的 C++ 代码。这并不意味着编译器会这样做,只是尝试一下。如果编译草图后该函数不再存在,则不能要求将该函数放入 RAM 中。
| 归档时间: |
|
| 查看次数: |
13976 次 |
| 最近记录: |