How can I REALLY tell which userX.bin is currently executing ?

sharkx
Posts: 29
Joined: Wed Jan 06, 2016 2:59 am

How can I REALLY tell which userX.bin is currently executing ?

Postby sharkx » Fri Jan 22, 2016 11:22 pm

Context : module has 512 Kb flash, and I'm trying to develop my own OTA sequence (2*256 Kb), based on the documents on the OTA and memory maps. The reason is that all modules are on a closed network without any PCs.

The problem : sometimes, especially when the new firmware has more changes than the previous version (I do a binary compare; don't care about the code itself), when writing to flash memory (usually at the first flash sector, and more frequently while writing to sector 0001 at 0x001000), the module crashes and it is unrecoverable unless I flash through serial port.

The error I get on the UART1 is a Fatal exception (28), followed by a couple of FE(3) then some FE(4). Sometimes it's a FE(9)... They all somehow seem flash-related (couldn't really find a proper documentation on this).

I'm investigating all possible causes, but so far I'm pretty sure I do write at the proper addresses and that it is the proper content, based on the return value of system_upgrade_userbin_check(). Besides, even if write garbage to the proper address space, it should crash on reset, NOT while writing to flash.

So one of the possibilities that I'm looking at is that I'm writing to the wrong address space; and by wrong I do not mean wrong according to the return value of system_upgrade_userbin_check(), but the REAL currently executing code.

Can anyone help find the answer to the question : how can I tell where my code is REALLY execution from ?
Something like getting the value of the IP register (either directly or through a CALL/POP trick like in the good ol' days)
I know it sounds strange, but I need this just to rule out this scenario.

Thanks in advance.

grt
Posts: 4
Joined: Mon Jan 25, 2016 2:42 pm

Re: How can I REALLY tell which userX.bin is currently executing ?

Postby grt » Mon Jan 25, 2016 5:44 pm

I had developed OTA program on ESP8266 these days.
I think system_upgrade_userbin_check() does not return the real current app address.
It just return some flag stored in the flash.
So you will program blank.bin to flash to set a initial state:
Boot launch 0x1000 and system_upgrade_userbin_check return 0x0.

sharkx
Posts: 29
Joined: Wed Jan 06, 2016 2:59 am

Re: How can I REALLY tell which userX.bin is currently executing ?

Postby sharkx » Mon Jan 25, 2016 11:27 pm

Thanks. Actually, that's what I'm afraid of... that the returned flag somehow does no longer match the real execution location.
But I have no clue on how to determine that for sure, so that I either rule out this as the cause for the OTA failure or find a way to fix it.

Here's what happens :
1. I build everything under the eclipse environment;
2. once everything is ok, i use the ubuntu VM to build the .bin files

The build environment is slightly modified :
1. the irom0_text in both LD files is increased to 0x30000 (192 Kb)
2. I removed the user input commands from the gen_build.sh, so that both user1/user2 files get built without other intervention

I flash the boot.bin and both user1/user2.bin to the module; no other flash areas are affected (user and system parameters, etc.). So the module will boot to what it last used.

Next, I try my OTA update. As I said in my previous post, sometimes it works, sometimes not. When it crashes, it is while writing to the address 0x010000 in flash, or immediately after, and the module becomes unusable unless I flash it again over serial.

Now, even if it sounds a bit sci-fi, one of the possible reasons I can think of is this :
1. the module gets updated with both user.bin files
2. it boots to the user2.bin
3. somewhere in the code, it executes an absolute jump (not sure if this exists in this chip, by the way)
4. code continues execution in the user1.bin
5. when it tries to update the user1.bin (according to the flag) it, naturally, crashes.

Of course this can happen because the user.bin files are not correctly built. Hence the question in the subject : how can I tell if this is the case ?

Because the fact that the module becomes unusable after crashing tells me I'm writing to the wrong spot in the flash. If I'm writing to the right user.bin area and it fails, the module should still use the good user.bin and still start.

Any ideas are welcome. Thanks.

ESP_Faye
Posts: 1646
Joined: Mon Oct 27, 2014 11:08 am

Re: How can I REALLY tell which userX.bin is currently executing ?

Postby ESP_Faye » Thu Jan 28, 2016 2:33 pm

Hi,

1. Please use the latest boot_v1.5.bin. If it tries to run user2.bin when power on, but user2.bin is broken and fails to run, it will jump to run user1.bin automatically.

2. Please always download blank.bin as initialization, if your OTA flag is wrong, maybe due to it.

Thanks for your interest in ESP8266 !

sharkx
Posts: 29
Joined: Wed Jan 06, 2016 2:59 am

Re: How can I REALLY tell which userX.bin is currently executing ?

Postby sharkx » Thu Jan 28, 2016 4:03 pm

Thanks. I just noticed the boot 1.5 in the 1.5.1 sdk. I'll give it a try.

jkvarela
Posts: 9
Joined: Sat Jul 04, 2015 12:36 am

Re: How can I REALLY tell which userX.bin is currently executing ?

Postby jkvarela » Fri Jan 29, 2016 6:02 am

Can we try to read address position of a constant in the flash to determine what portion we are using ???

I didn´t test this but can be like this for 512K flash:

uint8_t ICACHE_FLASH_ATTR slotBinCheck(){
const char ref[1] = {"r"};
char *p;
if ((unsigned long)p > 0x40000){// middle of flash(512K)
return 1;
}
return 0;
}

work?

jkvarela
Posts: 9
Joined: Sat Jul 04, 2015 12:36 am

Re: How can I REALLY tell which userX.bin is currently executing ?

Postby jkvarela » Fri Jan 29, 2016 6:02 am

Can we try to read address position of a constant in the flash to determine what portion we are using ???

I didn´t test this but can be like this for 512K flash:

uint8_t ICACHE_FLASH_ATTR slotBinCheck(){
const char ref[1] = {"r"};
char *p;
p = &ref;
if ((unsigned long)p > 0x40000){// middle of flash(512K)
return 1;
}
return 0;
}

work? How we can know a address of a constant var in the esp8266??
Last edited by jkvarela on Fri Jan 29, 2016 6:34 am, edited 2 times in total.

sharkx
Posts: 29
Joined: Wed Jan 06, 2016 2:59 am

Re: How can I REALLY tell which userX.bin is currently executing ?

Postby sharkx » Fri Jan 29, 2016 11:21 am

Good point. I'll try.

jkvarela
Posts: 9
Joined: Sat Jul 04, 2015 12:36 am

Re: How can I REALLY tell which userX.bin is currently executing ?

Postby jkvarela » Sun Jan 31, 2016 2:52 am

sharkx;

Maybe the pointer needs to be constant....like this:

const char *p;


dont forget to say to us the result, I am looking for one solution for this too....


Thanks;

Juliano

sharkx
Posts: 29
Joined: Wed Jan 06, 2016 2:59 am

Re: How can I REALLY tell which userX.bin is currently executing ?

Postby sharkx » Sun Jan 31, 2016 3:16 pm

It definitely has NOT to be a regular variable; these get their slot in RAM. Always.
I'll let you know.

Who is online

Users browsing this forum: No registered users and 17 guests