espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.64k stars 7.29k forks source link

spi_flash working? #82

Closed jolivepetrus closed 7 years ago

jolivepetrus commented 7 years ago

We are working in SPIFFS. Things go well, using SPIFFS in our Lua RTOS, with file system access from Lua. But some times we received exceptions, and I think that some dead locks running on multicore. It seems that not happens using uni core.

I try to reproduce this in the attached code (tested, I think that flash address are on my flash bounds). In our build we receive this exception:

Guru Meditation Error: Core   0 panic'ed (Interrupt wdt timeout on CPU0)
Register dump:
PC      :  40007c78  PS      :  00060e34  A0      :  80007d16  A1      :  3ffb3770  
A2      :  00800000  A3      :  3ffbaa20  A4      :  8008175c  A5      :  3ffbaa20  
A6      :  0000018d  A7      :  0000000d  A8      :  3ff40000  A9      :  000000d0  
A10     :  00800000  A11     :  3ff4001c  A12     :  8008170c  A13     :  3ffbaa00  
A14     :  00000000  A15     :  3ffae270  SAR     :  00000017  EXCCAUSE:  00000005  
EXCVADDR:  00000000  LBEG    :  00000000  LEND    :  00000000  LCOUNT  :  00000000  
Rebooting...

Sorry, I don't have more information about this, I haven't a JTAG for know more about this ... but something happens with spi_flash function and multicore ....

Sample code:

#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "nvs_flash.h"

#include "esp_spi_flash.h"

void spi_flash_task(void *pvParameter)
{
    char buff[4096];
    int ret;

    uint32_t base = 0x00180000;
    uint32_t page = 4096;
    uint32_t size = 0x80000 - page;
    uint32_t addr = base;

    for(;;) {
        addr = base;

        while(addr < base + size - page) {      
            ret = spi_flash_read(addr, buff, page);
            if (ret != 0)
                printf("oops 1\r\n");

            ret = spi_flash_erase_sector(addr >> 12);
            if (ret != 0)
                printf("oops 2\r\n");

            addr += page;       
        }
    }

    vTaskDelete(NULL);
}

void app_main()
{
    nvs_flash_init();
    system_init();
    xTaskCreate(&spi_flash_task, "spiftask", 1024*10, NULL, 5, NULL);
}
igrr commented 7 years ago

Thanks, I'll try to reproduce this tomorrow. Could you please attach sdkconfig file you have used for this test?

jolivepetrus commented 7 years ago

Of course:

sdkconfig.txt

igrr commented 7 years ago

I think my flash chip now has a nice hole in this region, as the test is running for about an hour already. Unfortunately I haven't been able reproduce the issue so far.

jolivepetrus commented 7 years ago

Thanks for your test. I will try to do more tests, and start the buy process for a new flash ship :) ... In my tests, exeption is raised after a few seconds to start it.

jolivepetrus commented 7 years ago

Have you tested with the attached sdkconfig in the previous comments? I have tested again and fails. If I test with sdkconfig attached to this comment don't fail. This sdkconfig has the WDT disabled. sdkconfig.txt

igrr commented 7 years ago

Yes, i have tested with sdkconfig you have provided above. Which commit of ESP-IDF have you been testing this with?

jolivepetrus commented 7 years ago

This is the comit (git rev-parse HEAD):

c8a43508e5a08737b5e4eb0c1e43a374cb84ddb7

jolivepetrus commented 7 years ago

Sorry, I know that this is not suitable for this, but I need email to some one of the esp-idf developers. I think that we are working in an interesting thing and maybe part of our work will be useful for you. Our work have key parts that need FreeRTOS changes ...

Here is my email: jolive@iberoxarxa.com

jolivepetrus commented 7 years ago

I think that this issue is related with something wrong with one of our UART interrupt handler, where the following code is running, and intensive spi_flash access (read) is done from another task. When interrupt is processed, then we give panic.

.... .... compute byte calling functions on IRAM .... .... xQueueSendFromISR(q, &byte, &xHigherPriorityTaskWoken); ..... ..... if (xHigherPriorityTaskWoken) { portYIELD_FROM_ISR(); }

I'm trying to set up JTAG. I hope to provide more information about this in the following days.

jolivepetrus commented 7 years ago

This issue was caused because we don't crear the interrupt flag on the right place in our UART interrupt handler.

Sorry for the inconvenience.