How can I store my data into flash?
Posted:
Thu Dec 18, 2014 4:29 pm
by nnylyj
Environment: FreeRTOS SDK
In Memory Map, I saw a 32k user-defined storage at 0x40002000 mapped to flash, but when I use memcpy((char*)(0x40002000), something) esp8266 threw an Exception 29.
I looked up xtensa document, it means StoreProhibitedCause. And I tried spi_flash_write(0x3C000, buffer, size), the same exception was threw.
The problem is how can i store my data into flash, and what is its size?
Sorry for my poor English, hope you can understand the text.
Re: How can I store my data into flash?
Posted:
Thu Dec 18, 2014 4:45 pm
by rekod
You may look at example code in
at_baseCmd.c from
at_v0.20_on_SDKv0.9.3code for load some parameters:
Code: Select all/******************************************************************************
* FunctionName : user_esp_platform_load_param
* Description : load parameter from flash, toggle use two sector by flag value.
* Parameters : param--the parame point which write the flash
* Returns : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
user_esp_platform_load_param(void *param, uint16 len)
{
struct esp_platform_sec_flag_param flag;
spi_flash_read((ESP_PARAM_START_SEC + ESP_PARAM_FLAG) * SPI_FLASH_SEC_SIZE,
(uint32 *)&flag, sizeof(struct esp_platform_sec_flag_param));
if (flag.flag == 0) {
spi_flash_read((ESP_PARAM_START_SEC + ESP_PARAM_SAVE_0) * SPI_FLASH_SEC_SIZE,
(uint32 *)param, len);
} else {
spi_flash_read((ESP_PARAM_START_SEC + ESP_PARAM_SAVE_1) * SPI_FLASH_SEC_SIZE,
(uint32 *)param, len);
}
}
code for save parameters:
Code: Select all/******************************************************************************
* FunctionName : user_esp_platform_save_param
* Description : toggle save param to two sector by flag value,
* : protect write and erase data while power off.
* Parameters : param -- the parame point which write the flash
* Returns : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
user_esp_platform_save_param(void *param, uint16 len)
{
struct esp_platform_sec_flag_param flag;
spi_flash_read((ESP_PARAM_START_SEC + ESP_PARAM_FLAG) * SPI_FLASH_SEC_SIZE,
(uint32 *)&flag, sizeof(struct esp_platform_sec_flag_param));
if (flag.flag == 0) {
spi_flash_erase_sector(ESP_PARAM_START_SEC + ESP_PARAM_SAVE_1);
spi_flash_write((ESP_PARAM_START_SEC + ESP_PARAM_SAVE_1) * SPI_FLASH_SEC_SIZE,
(uint32 *)param, len);
flag.flag = 1;
spi_flash_erase_sector(ESP_PARAM_START_SEC + ESP_PARAM_FLAG);
spi_flash_write((ESP_PARAM_START_SEC + ESP_PARAM_FLAG) * SPI_FLASH_SEC_SIZE,
(uint32 *)&flag, sizeof(struct esp_platform_sec_flag_param));
} else {
spi_flash_erase_sector(ESP_PARAM_START_SEC + ESP_PARAM_SAVE_0);
spi_flash_write((ESP_PARAM_START_SEC + ESP_PARAM_SAVE_0) * SPI_FLASH_SEC_SIZE,
(uint32 *)param, len);
flag.flag = 0;
spi_flash_erase_sector(ESP_PARAM_START_SEC + ESP_PARAM_FLAG);
spi_flash_write((ESP_PARAM_START_SEC + ESP_PARAM_FLAG) * SPI_FLASH_SEC_SIZE,
(uint32 *)&flag, sizeof(struct esp_platform_sec_flag_param));
}
}
some definitions:
Code: Select all#define ESP_PARAM_START_SEC 0x3C
#define ESP_PARAM_SAVE_0 1
#define ESP_PARAM_SAVE_1 2
#define ESP_PARAM_FLAG 3
struct esp_platform_sec_flag_param {
uint8 flag;
uint8 pad[3];
};
From here:
https://github.com/esp8266/esp8266-wiki/wiki/Memory-Mapwe may see the following about SPI Flash memory:
This area is readable as data with aligned 4-byte reads.
As you may see, esp_platform_sec_flag_param structure is 4-byte aligned.
Is the buffer in your code spi_flash_write(0x3C000, buffer, size) 4-byte aligned?
Re: How can I store my data into flash?
Posted:
Fri Dec 19, 2014 4:41 am
by nnylyj
rekod wrote:You may look at example code in at_baseCmd.c from at_v0.20_on_SDKv0.9.3
code for load some parameters:
Code: Select all/******************************************************************************
* FunctionName : user_esp_platform_load_param
* Description : load parameter from flash, toggle use two sector by flag value.
* Parameters : param--the parame point which write the flash
* Returns : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
user_esp_platform_load_param(void *param, uint16 len)
{
struct esp_platform_sec_flag_param flag;
spi_flash_read((ESP_PARAM_START_SEC + ESP_PARAM_FLAG) * SPI_FLASH_SEC_SIZE,
(uint32 *)&flag, sizeof(struct esp_platform_sec_flag_param));
if (flag.flag == 0) {
spi_flash_read((ESP_PARAM_START_SEC + ESP_PARAM_SAVE_0) * SPI_FLASH_SEC_SIZE,
(uint32 *)param, len);
} else {
spi_flash_read((ESP_PARAM_START_SEC + ESP_PARAM_SAVE_1) * SPI_FLASH_SEC_SIZE,
(uint32 *)param, len);
}
}
code for save parameters:
Code: Select all/******************************************************************************
* FunctionName : user_esp_platform_save_param
* Description : toggle save param to two sector by flag value,
* : protect write and erase data while power off.
* Parameters : param -- the parame point which write the flash
* Returns : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
user_esp_platform_save_param(void *param, uint16 len)
{
struct esp_platform_sec_flag_param flag;
spi_flash_read((ESP_PARAM_START_SEC + ESP_PARAM_FLAG) * SPI_FLASH_SEC_SIZE,
(uint32 *)&flag, sizeof(struct esp_platform_sec_flag_param));
if (flag.flag == 0) {
spi_flash_erase_sector(ESP_PARAM_START_SEC + ESP_PARAM_SAVE_1);
spi_flash_write((ESP_PARAM_START_SEC + ESP_PARAM_SAVE_1) * SPI_FLASH_SEC_SIZE,
(uint32 *)param, len);
flag.flag = 1;
spi_flash_erase_sector(ESP_PARAM_START_SEC + ESP_PARAM_FLAG);
spi_flash_write((ESP_PARAM_START_SEC + ESP_PARAM_FLAG) * SPI_FLASH_SEC_SIZE,
(uint32 *)&flag, sizeof(struct esp_platform_sec_flag_param));
} else {
spi_flash_erase_sector(ESP_PARAM_START_SEC + ESP_PARAM_SAVE_0);
spi_flash_write((ESP_PARAM_START_SEC + ESP_PARAM_SAVE_0) * SPI_FLASH_SEC_SIZE,
(uint32 *)param, len);
flag.flag = 0;
spi_flash_erase_sector(ESP_PARAM_START_SEC + ESP_PARAM_FLAG);
spi_flash_write((ESP_PARAM_START_SEC + ESP_PARAM_FLAG) * SPI_FLASH_SEC_SIZE,
(uint32 *)&flag, sizeof(struct esp_platform_sec_flag_param));
}
}
some definitions:
Code: Select all#define ESP_PARAM_START_SEC 0x3C
#define ESP_PARAM_SAVE_0 1
#define ESP_PARAM_SAVE_1 2
#define ESP_PARAM_FLAG 3
struct esp_platform_sec_flag_param {
uint8 flag;
uint8 pad[3];
};
From here: https://github.com/esp8266/esp8266-wiki/wiki/Memory-Map
we may see the following about SPI Flash memory:
This area is readable as data with aligned 4-byte reads.
As you may see, esp_platform_sec_flag_param structure is 4-byte aligned.
Is the buffer in your code spi_flash_write(0x3C000, buffer, size) 4-byte aligned?
yes, its size is 64 bytes.
spi_flash_write worked in 0.9.3 SDK but does not work in RTOS SDK, I tried erase , it works fine, but write function always threw a Exception 29
Fatal exception (29):
epc1=0x4000bf1b
epc2=0x00000000
epc3=0x40243069
epcvaddr=0x00000000
depc=0x00000000
Re: How can I store my data into flash?
Posted:
Fri Dec 19, 2014 3:22 pm
by nnylyj
I tried and tried all day, but nothing useful got.