-
Notifications
You must be signed in to change notification settings - Fork 7.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NVS write crashes with "Cache disabled but cached memory region accessed" (IDFGH-8634) #10079
Comments
Are you compiling with -Os (optimization for size)? I once had a similar problem with the code for RMT. You could try to force inline all those low level functions called by the interrupt handler. For example i2c_ll_disable_intr_mask() is declared as:
"inline" alone does not force inlining, i.e. when compiling with -Os the compiler still keeps the function to save space. This is a bit misleading. The solution is to use
instead of just
Try it and tell us about the results. |
Thanks for the pointer. I actually ran into your issue #9487 which lead me down the same conclusion since the linked PR only touched RMT code. Heres code that triggers the crash: #include <stdio.h>
#include <string.h>
#include "driver/i2c.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "nvs_flash.h"
void task1() {
while (1) {
uint8_t i = 0x01;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (i << 1) | I2C_MASTER_WRITE, 1);
i2c_master_stop(cmd);
i2c_master_cmd_begin(I2C_NUM_0, cmd, 100 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
}
}
void task2() {
while (1) {
uint32_t crashme;
esp_flash_read(NULL, (void *)&crashme, 0, sizeof(crashme));
}
}
void app_main(void) {
i2c_config_t conf;
memset(&conf, 0, sizeof(conf));
conf.mode = I2C_MODE_MASTER;
conf.sda_io_num = 4;
conf.scl_io_num = 5;
conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
conf.master.clk_speed = 100000;
i2c_param_config(I2C_NUM_0, &conf);
i2c_driver_install(I2C_NUM_0, conf.mode, 0, 0, ESP_INTR_FLAG_SHARED | ESP_INTR_FLAG_IRAM);
xTaskCreatePinnedToCore(task1, "task1", 8192, NULL, 10, NULL, 0);
xTaskCreatePinnedToCore(task2, "task2", 8192, NULL, 10, NULL, 1);
} Declaring these two functions accordingly dosen't seem to affect the crash, whether compiled with Og, Os or O2. void __attribute__((always_inline)) inline i2c_hal_get_intsts_mask(i2c_hal_context_t *hal, uint32_t *mask)
{
*mask = i2c_ll_get_intsts_mask(hal->dev);
}
static __attribute__((always_inline)) inline uint32_t i2c_ll_get_intsts_mask(i2c_dev_t *hw)
{
return hw->int_status.val;
} |
@JustinOng Do you have |
|
You were right here! Can you please try following patch on your side? diff --git components/hal/i2c_hal.c components/hal/i2c_hal.c
index db2dd1a7e1..aec4e604cf 100644
--- components/hal/i2c_hal.c
+++ components/hal/i2c_hal.c
@@ -64,11 +64,6 @@ void i2c_hal_disable_intr_mask(i2c_hal_context_t *hal, uint32_t mask)
i2c_ll_disable_intr_mask(hal->dev, mask);
}
-void i2c_hal_get_intsts_mask(i2c_hal_context_t *hal, uint32_t *mask)
-{
- *mask = i2c_ll_get_intsts_mask(hal->dev);
-}
-
void i2c_hal_set_fifo_mode(i2c_hal_context_t *hal, bool fifo_mode_en)
{
i2c_ll_set_fifo_mode(hal->dev, fifo_mode_en);
diff --git components/hal/i2c_hal_iram.c components/hal/i2c_hal_iram.c
index 080d19c919..557a58c79b 100644
--- components/hal/i2c_hal_iram.c
+++ components/hal/i2c_hal_iram.c
@@ -67,3 +67,8 @@ void i2c_hal_get_txfifo_cnt(i2c_hal_context_t *hal, uint32_t *len)
{
*len = i2c_ll_get_txfifo_len(hal->dev);
}
+
+void i2c_hal_get_intsts_mask(i2c_hal_context_t *hal, uint32_t *mask)
+{
+ *mask = i2c_ll_get_intsts_mask(hal->dev);
+} |
Yep, that stops the PoC from crashing, thoughI'm not sure if the rest of the ISR has to be adjusted as well. |
i2c_isr_handler_default() calls i2c_master_cmd_begin_static() which calls i2c_ll_read_rxfifo(), i2c_cmd_is_single_byte(), i2c_ll_write_txfifo(), i2c_ll_write_cmd_reg(), i2c_ll_master_enable_tx_it() and i2c_ll_trans_start(), none of which are in IRAM or FORCE_INLINE_ATTR. I did not look any further. |
I did not find any other symbols from I2C ISR handler that would need IRAM placement. You may use following instructions to cross-check for any symbols that are placed in flash section but have callers in IRAM:
Alternatively, project |
I am also hitting this, see #10104 The Iram patch fixes my crash! 🎉🎉 |
@mahavirj You're right, |
@mahavirj do we have a timeline for getting this merged? It's too bad it did not make 4.4.3... |
@chipweinberger By the time this issue was filed, v4.4.3 testing had almost finished. Sorry but this fix shall be integrated soon and officially would come with 4.4.4. |
No problem. When it gets merged into the v4.4 branch, please let us know! |
@mahavirj |
We have reviewed the driver, and found that the fix is not required for the master branch (v5.1-dev) as the HAL layer has been refactored there. |
v4.3 fix: aac5297 |
Thanks for reporting, feel free to reopen. |
Answers checklist.
IDF version.
ESP-IDF v4.4.2-378-g9269a536ac
Operating System used.
Linux
How did you build your project?
Command line with idf.py
If you are using Windows, please specify command line type.
No response
Development Kit.
Custom board with ESP32-WROOM-32E-N8
Power Supply used.
External 3.3V
What is the expected behavior?
The NVS write should succeed.
What is the actual behavior?
Writing to NVS causes a (rare) crash
Steps to reproduce.
A little hard to share my full environment because it involves external hardware peripherals and I'm not sure what are the trigger conditions.
Debug Logs.
More Information.
Based on the crash, it appears to be related to the I2C peripheral, which is enabled with
i2c_driver_install(I2C_PORT, I2C_MODE_MASTER, 0, 0, ESP_INTR_FLAG_SHARED | ESP_INTR_FLAG_IRAM)
Is the issue here that
i2c_isr_handler_default
calls functions likei2c_hal_get_intsts_mask
which arn't placed in IRAM (and may not be inlined)?The text was updated successfully, but these errors were encountered: