sdk flash access fails when passing address higher than 512KB

renze
Posts: 3
Joined: Wed Jan 21, 2015 1:58 am

sdk flash access fails when passing address higher than 512KB

Postby renze » Sun Sep 27, 2015 7:57 am

Dear Espressif developers,

I have been trying to develop some code that can store configuration values for my firmware on the flash chip.
I am using the latest sdk release (1.4).
My configuration is: COMPILE=gcc BOOT=new APP=1 SPI_SPEED=40 SPI_MODE=QIO SPI_SIZE_MAP=6

I am under the impression that when using size map 6 the user parameter storage resides at sector 0xFC through sector 0xFF.
This fits in the 1st megabyte of flash memory and it is thus memory mapped at 0x40200000 by default. I can indeed access the flash on that address.

Now the problem:
When using spi_flash_... api found in the sdk the commands fail if any sector / flash address higher than 512KB is passed the functions return with error status.

For example the command "spi_flash_erase_sector(0xFC);" which should erase the first sector of the user params area on the flash chip returns with an error. I think this is a bug in the SDK.


My guess is that you (the developers at espressif) built in a check to see if the sector passed is indeed a valid sector but forgot to adapt it for use with bigger flash configurations.

I would extremely appriciate it if you (the developers at espressif) could release the source code responsible for the flash read and write commands, in my opinion this would have no effect on your IP but it would help me and possibly others a great deal with developing software for the esp8266.

Also: in my pursuit of finding ways to access the flash I found out about the undocumented function "Cache_Read_Enable(odd_even, mb_count, 1);" which allows me to choose which 1MB part of the flash is mapped to memory. Using this function I was able to at least implement my own flash read command. However I do not understand what the last parameter is. The sdk seems to be passing a 1 to this parameter but I do not understand what it means. Please do explain.




So in short: I would like you guys to fix the flash access functions and if possible release the source for them. A broken sdk that has even the most basic functions in closed source parts makes working with the esp8266 much harder than it should be.

Greetings,
Renze

eriksl
Posts: 159
Joined: Fri May 22, 2015 6:22 pm

Re: sdk flash access fails when passing address higher than 512KB

Postby eriksl » Sun Sep 27, 2015 3:26 pm

+1!

BTW how do you manage to switch the FLASH window when it's running code from there? Or do you do it from iram?

renze
Posts: 3
Joined: Wed Jan 21, 2015 1:58 am

Re: sdk flash access fails when passing address higher than 512KB

Postby renze » Sun Sep 27, 2015 5:24 pm

I run the flash read functions from iram and switch back before returning to any code that runs from flash:

Code: Select all

/* Bankswitching: Choose which 1MB part of flash is mapped to 0x40200000-0x40300000 */
/* Note: Always switch back before calling any sdk function!! */
void flash_switch(uint8_t which)
{
  uint8 odd_even = 0;
  uint8 mb_count = 0;
  if (which==1) { odd_even = 1; }
  if (which==2) { mb_count = 1; }
  if (which==3) { odd_even = 1; mb_count = 1; }
  Cache_Read_Enable(odd_even, mb_count, 1);
}[

/* Read sector: Reads <amount> bytes from the sector <sector> of the flash mapped to the CPU into <buffer>. */
/* Using remap the 1MB area mapped to the CPU can be set to a different area */
void flash_read_sector_switch(uint32 sector, char* buffer, uint16 amount, uint8_t remap)
{
  uint32 addr;
  addr = sector * SPI_FLASH_SEC_SIZE + 0x40200000;
  if ( remap!=FLASH_MAP_INITIAL_VALUE ) flash_switch( remap );
  os_memcpy( buffer, addr, amount );
  if ( remap!=FLASH_MAP_INITIAL_VALUE ) flash_switch( FLASH_MAP_INITIAL_VALUE );
}

/* Read sector: Reads <amount> bytes from the sector <sector> of the flash into <buffer>. */
/* Automatically maps the right area to the CPU */
void flash_read_sector(uint32 sector, char* buffer, uint16 amount)
{
  if (sector<0x100) { flash_read_sector_switch(sector, buffer, amount, 0); }
  if ((sector>=0x100)&&(sector<0x200)) { flash_read_sector_switch(sector-0x100, buffer, amount, 1); }
  if ((sector>=0x200)&&(sector<0x300)) { flash_read_sector_switch(sector-0x200, buffer, amount, 2); }
  if (sector>=0x300) { flash_read_sector_switch(sector-0x300, buffer, amount, 3); }
}


Not all code is in flash, so some commands like "os_memcpy()" work while flash is switched. You should always switch back before attempting to run any code from flash or when trying to run a sdk function. Should you forget to do this the cpu will crash because it tries to run code from the wrong flash location.

The FLASH_MAP_INITIAL_VALUE constant is the 1MB part that is mapped by default. In a 4MB flash and size map 6 the part of flash that should be mapped is the first MB (0) when running user1 and the second MB (1) when running user2. For more info have a look at this file "https://www.rnplus.nl/wp-content/uploads/2015/09/memorymap.pdf". It contains a colorcoded version of the flash mapping. The green part is activated with "flash_switch(0);", the yellow and part of the purple "user data" area are mapped with flash_switch(1);", a whole megabyte of user data is mapped when selecting flash_switch(2);", and the last part of user storage and the system params storage are selected with flash_switch(3);".


I still hope an espressif engineer will answer my initial question: please fix the flash access sdk functions and if possbile give us the source code of the flash sector erase and flash write functions.

blubb
Posts: 116
Joined: Mon Jun 22, 2015 5:35 am

Re: sdk flash access fails when passing address higher than 512KB

Postby blubb » Sun Sep 27, 2015 7:08 pm

How do you flash the binary onto the module? Esptool? Parameters?

renze
Posts: 3
Joined: Wed Jan 21, 2015 1:58 am

Re: sdk flash access fails when passing address higher than 512KB

Postby renze » Sun Sep 27, 2015 10:00 pm

I use esptool.py like this:

Code: Select all

python2 ~/esptool.py write_flash 0x00000 ../bin/boot_v1.4\(b1\).bin 0x01000 ../bin/upgrade/user1.4096.new.6.bin 0xFC000 user_params.bin


I can read the contents of user_params.bin using my flash read function. The SDK functions can not read sector 0xFC, which is at address 0xFC000.

I do not see why the way I flash my binary matters? The SDK functions should always work the same.

For completeness: the make command I use is:

Code: Select all

make COMPILE=gcc BOOT=new APP=1 SPI_SPEED=40 SPI_MODE=QIO SPI_SIZE_MAP=6

blubb
Posts: 116
Joined: Mon Jun 22, 2015 5:35 am

Re: sdk flash access fails when passing address higher than 512KB

Postby blubb » Sun Sep 27, 2015 10:20 pm

You need to add -fs and -ff parameters to esptool depending on your flash size and speed. Esptool changes the binary before flashing!! Omitting the parameters results in default settings, i.e. 512 kB flash for example. My guess is that access beyond 512 kB will not work then.

(I know this is stupid, but it is how it is with esptool)

Who is online

Users browsing this forum: No registered users and 27 guests