ESP8266 / Arduino:为什么有必要将ICACHE_RAM_ATTR宏添加到从那里调用的ISR和函数中?

问题描述 投票:0回答:1

[我在ESP8266的Arduino代码中读到need to add the ICACHE_RAM_ATTR macro to interrup service routines (ISRs) and to every function that is called from there以防止随机崩溃。我也找到了an explanation of what the macro ICACHE_RAM_ATTR does,尽管我不确定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();
}

第二个问题:我是否需要将ICACHE_RAM_ATTR宏添加到被强制内联的函数中?

arduino esp8266 arduino-esp8266 isr
1个回答
0
投票

ICACHE_RAM_ATTR和ICACHE_FLASH_ATTR是链接器属性。编译完草图后,您可以说该功能是否应存储在RAM或FLASH中(通常不设置任何内容:无缓存)。

ESP8266是多任务处理,ESP32具有2个内核。因此,您可以将代码作为多线程执行-因为它使用RTOS。

现在是问题:整个闪存都用于程序和存储。只能通过1个线程完成对Flash的读写。如果尝试同时通过2个不同的线程访问Flash,则ESP可能会崩溃。

这是因为您可以将函数放在RAM中而不是闪存中。因此,即使您正在向EEPROM或闪存中写入内容,也可以在不访问闪存的情况下调用此功能。

使用ICACHE_RAM_ATTR将功能放在RAM上。

使用ICACHE_FLASH_ATTR,您将功能放在闪存上(以节省RAM)。

中断功能应使用ICACHE_RAM_ATTR。经常调用的函数不应使用任何缓存属性。

重要提示:切勿在中断内访问闪存!中断可能会在访问闪存期间发生,因此,如果您尝试同时访问闪存,则会崩溃(有时会在使用设备后1-2小时内发生)。

由于您只有32kb的IRAM(指令RAM),因此即使可能,您也应尝试仅将中断功能放入RAM,而不是所有功能。

第二个问题:不,绝对不!内联是另一个编译器标志,因此编译器将尝试将整个函数放在调用者函数中=>将函数调用转换为main内部的c ++代码。这并不意味着编译器会这样做,只需尝试一下即可。如果在编译草图后该功能不再存在,则不能要求将该功能放入RAM。

© www.soinside.com 2019 - 2024. All rights reserved.