ESP8266 2MB + OTA

JulienInnovel
Posts: 7
Joined: Mon Jan 15, 2018 6:34 pm

ESP8266 2MB + OTA

Postby JulienInnovel » Tue Feb 06, 2018 1:01 am

Hello everyone,

I'm using an ESP-WROOM-02 (ESP8266 + 2MB of SPI flash).
I'm trying to do OTA tests with mode 512KB + 512KB, to have 1024KB of user data (I have some data do store into flash and I don't want to erase them with OTA, user data stored at @ 0x100000).

I build my first firmware (V1) with linker script "eagle.app.v6.new.2048.ld", option "16m" (not "16m-c1").
I flash my ESP with ESP FLASH TOOL with this parameters :
SPI speed : 40MHz
SPI mode : QIO
Flash size : 16m
and files :
boot_v1.7.bin @0x00000
user1.bin @0x01000
blank.bin @0x1fb000
esp_init_data_default.bin @0x1fc000
blank.bin @0x1fe000

My ESP start correctly (USART prompt ) :
ets Jan 8 2013,rst cause:2, boot mode:(3,7)
load 0x40100000, len 2592, room 16
tail 0
chksum 0xf3
load 0x3ffe8000, len 764, room 8
tail 4
chksum 0x92
load 0x3ffe82fc, len 676, room 4
tail 0
chksum 0x22
csum 0x22

2nd boot version : 1.7(5d6f877)
SPI Speed : 40MHz
SPI Mode : QIO
SPI Flash Size & Map: 16Mbit(512KB+512KB)
jump to run user1 @ 1000

rf cal sector: 507
freq trace enable 0
rf[112] : 00
rf[113] : 00
rf[114] : 01
w_flash

SDK ver: 2.1.0(116b762) compiled @ May 5 2017 16:08:55
phy ver: 1134_0, pp ver: 10.2


Now, I want to upgrade my ESP by OTA to firmware version 2 (same as version 1 but only version number has changed) :
It's working perfectly, reboot and prompt this :
ets Jan 8 2013,rst cause:2, boot mode:(3,6)
load 0x40100000, len 2592, room 16
tail 0
chksum 0xf3
load 0x3ffe8000, len 764, room 8
tail 4
chksum 0x92
load 0x3ffe82fc, len 676, room 4
tail 0
chksum 0x22
csum 0x22

2nd boot version : 1.7(5d6f877)
SPI Speed : 40MHz
SPI Mode : QIO
SPI Flash Size & Map: 16Mbit(512KB+512KB)
jump to run user2 @ 81000

rf cal sector: 507
freq trace enable 0
rf[112] : 00
rf[113] : 00
rf[114] : 01

SDK ver: 2.1.0(116b762) compiled @ May 5 2017 16:08:55
phy ver: 1134_0, pp ver: 10.2

Now, I want to upgrade to the firmware version 3 (same has others, but only version number changed to 3) :
GET /user1.bin HTTP/1.0
Connection: close

actual bin : UPGRADE_FW_BIN2
system_upgrade_start
upgrade_connect 45736
[OTA]Upgrading...
upgrade_connect_cb
pusrdata = HTTP/1.0 200 OK
Content-Type: application/octet-stream
Content-Length: 234820

sumlength = 234820
sec_block 58
..........................................................upgrade_get_sum_disconcb 45544


And nothing else.... Reboot it self and only print this :
ets Jan 8 2013,rst cause:2, boot mode:(3,7)
load 0x40100000, len 2592, room 16
tail 0
chksum 0xf3
load 0x3ffe8000, len 764, room 8
tail 4
chksum 0x92
load 0x3ffe82fc, len 676, room 4
tail 0
chksum 0x22
csum 0x22

2nd boot version : 1.7(5d6f877)
SPI Speed : 40MHz
SPI Mode : QIO
SPI Flash Size & Map: 16Mbit(512KB+512KB)
jump to run user2 @ 81000


And my ESP is broken...
I must erase all, and flash it again.

It seems like the firmware 2 is erasing itself or something else..

Any one have any idea ?
Thanks

AgentSmithers
Posts: 195
Joined: Sat Apr 01, 2017 1:21 am
Contact:

Re: ESP8266 2MB + OTA

Postby AgentSmithers » Wed Feb 07, 2018 2:36 am

I just went through some OTA troubleshooting with another member on the forum here. Want to do a skype chat and I can take a look and help you fix it? I have some cycles starting thursday night PST.

JulienInnovel
Posts: 7
Joined: Mon Jan 15, 2018 6:34 pm

Re: ESP8266 2MB + OTA

Postby JulienInnovel » Wed Feb 07, 2018 8:56 pm

Hi, thanks.
You can add me, my skype is j.reynaud_7

JulienInnovel
Posts: 7
Joined: Mon Jan 15, 2018 6:34 pm

Re: ESP8266 2MB + OTA

Postby JulienInnovel » Thu Feb 08, 2018 5:28 pm

If I use the linker for 1MB (512+512), it seems to work !
I have the bootloader for 16Mbit (512 + 512) and I can use OTA to flash firmware and automatically jump to user 1 or user 2, and have a user data flash at the end (from @0x100000 to @0x1FC000).

But, why I must use the 1MB linker ?
The linker for 2MB can't do 512+512 ?

Her Mary
Posts: 537
Joined: Mon Oct 27, 2014 11:09 am

Re: ESP8266 2MB + OTA

Postby Her Mary » Mon Feb 12, 2018 5:27 pm

Did you select the 16Mbit on your flash download tool while downing?
And you should note that the system parameter area is always the last 4 or 5 sectors of your flash (16Mbit), you should not save any user data there.

JulienInnovel
Posts: 7
Joined: Mon Jan 15, 2018 6:34 pm

Re: ESP8266 2MB + OTA

Postby JulienInnovel » Mon Feb 12, 2018 6:55 pm

Hi,

Yes, I select the 16Mbit flash when I download the firmware.
My user data selection is from @0x100000 to @0x1FC000 (like defined in the IOT SDK USER MANUAL).

AgentSmithers
Posts: 195
Joined: Sat Apr 01, 2017 1:21 am
Contact:

Re: ESP8266 2MB + OTA

Postby AgentSmithers » Sun Feb 18, 2018 2:03 pm

JulienInnovel wrote:Hi, thanks.
You can add me, my skype is j.reynaud_7


I added you but havent been accepted yet.

AgentSmithers
Posts: 195
Joined: Sat Apr 01, 2017 1:21 am
Contact:

Re: ESP8266 2MB + OTA

Postby AgentSmithers » Thu Dec 09, 2021 5:09 pm

I've dealt with some headaches with FOTA and the ESP8266 for some time, I wrote this little bit to host a webserver to upload firmware straight to the ESP. Maybe it will come in handy for someone in the future.

Code: Select all

#ifndef __httpPostFota__
#define __httpPostFota__

#include <upgrade.h>

//#define UPGRADE_DEBUG

#ifdef UPGRADE_DEBUG
#define UPGRADE_DBG os_printf
#else
#define UPGRADE_DBG
#endif

#define FOTAHTMLSIZE 8192

typedef void (*FOTAWebRecvFunctionCallback)(void *arg, char *pusrdata, unsigned short length);
FOTAWebRecvFunctionCallback FOTAWebRecvCallBack;
unsigned char * FOTAFormatedHTMLPageWithHttpHeader;
LOCAL struct espconn FOTAWebServerSocket;

static char *FOTAmsg_espconn_state[] =
{
      "NONE",
      "WAIT",
      "LISTEN",
      "CONNECT",
      "WRITE",
      "READ",
      "CLOSE"
};

char * FOTAHttpHeader = "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nConnection: close\r\n\r\n";
LOCAL void ICACHE_FLASH_ATTR FOTAHttpSendWithHeader(struct espconn * WifiScanConfigConnection, unsigned char * LFormatedHTMLPage) //This may be able to be merged
{
   FOTAFormatedHTMLPageWithHttpHeader = (unsigned char*)os_zalloc(FOTAHTMLSIZE);
   if (FOTAFormatedHTMLPageWithHttpHeader == 0x0)
   {
      os_printf("[%s][%s][%d] - Unable to Alloc memory, exiting\r\n", __FILE__ ,__func__, __LINE__);
      return;
   }
   os_printf("Attaching header and sending\r\n");
   os_memset(FOTAFormatedHTMLPageWithHttpHeader, 0, FOTAHTMLSIZE);
   os_printf("Attaching header and sending\r\n");
   os_sprintf(FOTAFormatedHTMLPageWithHttpHeader, FOTAHttpHeader, os_strlen(LFormatedHTMLPage));
   os_printf("Attaching header and sending\r\n");
   os_strcat(FOTAFormatedHTMLPageWithHttpHeader, LFormatedHTMLPage);
   os_printf("Attaching header and sending\r\n");
   espconn_send(WifiScanConfigConnection, (uint8*)FOTAFormatedHTMLPageWithHttpHeader, os_strlen(FOTAFormatedHTMLPageWithHttpHeader));
   os_printf("HTTP Response sent bytes: %d\r\n", os_strlen(LFormatedHTMLPage));
   os_free(FOTAFormatedHTMLPageWithHttpHeader);
}

LOCAL os_timer_t Firmware_Timer;

static ETSTimer http2spi_flash_reboot_timer;

LOCAL char* ICACHE_FLASH_ATTR http2spi_checkheader(void *buf, int which)
{
   os_printf("[%s]\r\n", __func__);
   uint8_t *cd = (uint8_t *)buf;
   uint32_t *buf32 = buf;
   os_printf("OTA hdr %p: %08lX %08lX %08lX %08lX\n", buf,
   (long unsigned int)buf32[0],
   (long unsigned int)buf32[1],
   (long unsigned int)buf32[2],
   (long unsigned int)buf32[3]);
   if (cd[0] != 0xEA) return "IROM magic missing";
   if (cd[1] != 4 || cd[2] > 3 || (cd[3]>>4) > 6) return "bad flash header";
   //if (cd[3] < 3 && cd[3] != which) return "Wrong partition binary";
   if (((uint16_t *)buf)[3] != 0x4010) return "Invalid entry addr";
   if (((uint32_t *)buf)[2] != 0) return "Invalid start offset";
   return NULL;
}

long gstaticContentLength = 0; //This keeps the Content length in mem for the life of the transactions
long gContentLength = 0; //This is a countdown of Binary Data left to transmit to the client, this includes the Mime header data! Anything after first CRLFCRLF basiclly
uint16 RemotePortsOpenedInDownload = 0; //Only One port at a time can upload a firmware
bool HeaderRead = false;
int dataparts = 0; //This track the file transfer progress in packets

char FOTAdatabuffer[4] = {0}; //Rolling Ring Buffer
uint32 FOTAdatabufferindex = 0;

uint32_t FOTAburnto = 0x0;
uint32_t gOffset = 0x0;

LOCAL void ICACHE_FLASH_ATTR FOTAWebServerConn_recv_callback(void *arg, char *pusrdata, unsigned short length)
{
   bool unloadafter = false;
   struct espconn * FOTApespconn = (struct espconn *) arg;
   //os_printf("[%s] Client recv'ed from port: ", __func__);
   /*
   uint16_printf(FOTApespconn->proto.tcp->remote_port);   
   os_printf(" - ");
   uint16_printf(FOTApespconn->proto.tcp->local_port);   
   /*
   //os_printf(FOTApespconn->proto.tcp->client_port);
   //os_printf(FOTApespconn->tcp.client_port); //How to identify which socket is triggering this WebServerCallback. What if multiple clients are connected?
   os_printf("\r\n");

   /*
   char* getpost = strstr(pusrdata, "POST /upload");
   if (getpost != NULL)
   {
      
   }
   */

   if (RemotePortsOpenedInDownload == FOTApespconn->proto.tcp->remote_port)
   {
      //os_printf("Incoming file data gcontentlength = %u lCurrentIncomming: %u\r\n", gContentLength, length);
      
      if (dataparts <= 6)
      {
         dataparts++;
         //os_printf(pusrdata);
         //hex_printf(pusrdata, length);
         //os_printf("\r\n-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\r\n");
      }
      char * Ptr = pusrdata;
      if (HeaderRead == false) //Move past the header
      {
         os_printf("Header removed\r\n");
         while (!strstarts(Ptr, "\r\n\r\n"))
         {
            Ptr++; //Increment Ptr
            //lengthleft--;
         }
         while (*Ptr == '\n' || *Ptr == '\r')
         {
            Ptr++; //Increment Ptr
            //lengthleft--;
         }

         os_printf("%u - %u!\r\n", Ptr, pusrdata);
         os_printf("Before %u!\r\n", length);
         length -= Ptr-pusrdata;
         gContentLength -= length;
         os_printf("After removing headers %u! Updating gContentLength(%u)\r\n", length, gContentLength);
         HeaderRead = true;
      }
      //os_printf("---");
      //os_printf(Ptr);
      //os_printf("gcontentlength(%d) - thispacketLength(%d) = %d remainding, DbufferIndex(%u)\r\n", gContentLength, length, (gContentLength - length), FOTAdatabufferindex);      

      unsigned short i,ii = 0;
      for (i=0; i<length; i++)
      {
         /*
         if (i == 0)
         {
            for (ii=0; ii<10; ii++)
            {
               os_printf("%x ", *(Ptr + ii));
            }
            os_printf("\r\n");
         }
         */

         if (gContentLength < 3000)
         {
            if (*(Ptr + i) == '-' && *(Ptr + i + 1) == '-' && *(Ptr + i + 2) == '-' && *(Ptr + i + 3) == '-' && *(Ptr + i + 4) == '-' && *(Ptr + i + 5) == '-')
            {
               //os_printf("Found Hyphens EOF -\r\n");
               char * ResponseToSend = "<!DOCTYPE html><html><head><meta http-equiv=\"refresh\" content=\"3;URL='/'\"></head><body>File Uploaded</body></html>";
               FOTAHttpSendWithHeader(FOTApespconn, ResponseToSend);   
               system_update_cpu_freq(80);
               return;
            }
         }

         //os_printf("i=%d", i);
         system_soft_wdt_feed();
         FOTAdatabuffer[FOTAdatabufferindex%4] = *(Ptr + i);
         FOTAdatabufferindex++;

         if (FOTAdatabufferindex%4 == 0)
         {
            system_soft_wdt_feed();
            if (spi_flash_write(gOffset, (uint32 *)&FOTAdatabuffer, 4) == SPI_FLASH_RESULT_OK)
            {
               if (gOffset % 0x10000 == 0)
               {
                  os_printf("%u of packet %u - %x %x %x %x Writen to offset 0x%x bin=0x%x bytesleft=%u!\r\n", i, length, FOTAdatabuffer[0], FOTAdatabuffer[1], FOTAdatabuffer[2], FOTAdatabuffer[3], gOffset, gOffset-FOTAburnto, gContentLength-FOTAdatabufferindex);
               }

               if (gstaticContentLength - FOTAdatabufferindex < 0x30)
               {
                  //os_printf("%u of packet %u - %x %x %x %x Writen to offset 0x%x bin=0x%x bytesleft=%u!\r\n", i, length, databuffer[0], databuffer[1], databuffer[2], databuffer[3], gOffset, gOffset-FOTAburnto, gContentLength-FOTAdatabufferindex);
               }
               
               if (FOTAdatabufferindex > gContentLength - 0x10 || FOTAdatabufferindex < 0x10 )// || i < 0x100 //This does for every packet
               {
                  //os_printf("%u of packet %u - %x %x %x %x Writen to offset 0x%x bin=0x%x bytesleft=%u\r\n", i, length, databuffer[0], databuffer[1], databuffer[2], databuffer[3], gOffset, gOffset-FOTAburnto, gContentLength-FOTAdatabufferindex);
               }
               
               gOffset += 4;
            }
            else
            {
               os_printf("failed writing length:%d\r\n", length);
            }
         }

         if (FOTAdatabufferindex > 60)
         {
            //return;
         }
      }

      gContentLength -= length;

      //os_printf("Packet Processed ContentLength(%u) of packet FOTAdatabufferindex(%u) Difference(%u)\r\n", gstaticContentLength, FOTAdatabufferindex, (gstaticContentLength - FOTAdatabufferindex));

      if (gContentLength == 0)
      {
         //espconn_disconnect(&FOTAWebServerSocket); //Webservers don't close sockets, clients do
         char * ResponseToSend = "<!DOCTYPE html><html><body>File Uploaded</body></html>";
         FOTAHttpSendWithHeader(FOTApespconn, ResponseToSend);   
      }
   }

   if (strstr(pusrdata, "POST /upload") != NULL)
   {
      system_update_cpu_freq(160);
      dataparts = 1;
      RemotePortsOpenedInDownload = FOTApespconn->proto.tcp->remote_port;
      os_printf(pusrdata);
      int index = 0;
      char * Ptr = pusrdata;
      
      while (!strstarts(Ptr, "Content-Length: "))
      {
         Ptr++; //Increment Potr
      }
      while (*Ptr != ' ')
      {
         Ptr++; //Increment Potr
      }
      Ptr++; //Increment to Content String

      char ContentLength[8] = {0};
      index = 0;
      while (*Ptr != '\r' && *Ptr != '\n')
      {
         ContentLength[index] = *Ptr;
         index++;
         Ptr++; //Increment Potr
      }
      os_printf(ContentLength);

      gContentLength = atoi(ContentLength);
      
      gstaticContentLength = gContentLength;
      
      Ptr = pusrdata; //Reset PTR
      while (!strstarts(Ptr, "Content-Type: multipart/form-data; boundary="))
      {
         Ptr++; //Increment Potr
      }
            
      while (*Ptr != '=')
      {
         Ptr++; //Increment Potr
      }
            
      Ptr++; //Increment to Content String
            
      char Boundary[64] = {0};      
            
      index = 0;
      
      while (*Ptr != '\r' && *Ptr != '\n')
      {
         Boundary[index] = *Ptr;
         index++;
         Ptr++; //Increment Ptr
         //os_printf("%u\r\n", Ptr);
      }
      Boundary[index] = 0; //This may not be needed by the way I declared boundary with = {0}
      os_printf(Boundary);
      os_printf("\r\n");

      
      while (!strstarts(Ptr, "\r\n\r\n"))
      {
         Ptr++; //Increment Ptr
         //os_printf("%u\r\n", Ptr);
      }
      Ptr += 4;
      
      os_printf("HEAD Content Length of file: %d\r\n", gContentLength); //Start erasing the flash at a given address

      if(system_upgrade_userbin_check() == 0)
      {
         FOTAburnto = 0x101000;
      }
      else
      {
         FOTAburnto = 0x1000;
      }
      gOffset = FOTAburnto;

      uint32_t poffset = 0x0;

      
      for (poffset=0x0; gContentLength-poffset>0; poffset++)
      {
         if ((FOTAburnto+poffset) % SPI_FLASH_SEC_SIZE == 0)
         {
            //os_printf("Erasing 0x%x\r\n", FOTAburnto+poffset);
            spi_flash_erase_sector((FOTAburnto+poffset)/SPI_FLASH_SEC_SIZE); //Doing it here may not be fast enough.
         }
      }
      
   
      HeaderRead = false; //SetHeader back to false to prep for incoming header to skip
      /*      
      os_printf("%u\r\n", Ptr);
      os_printf("%u\r\n", pusrdata);
      os_printf("%u\r\n", (Ptr-pusrdata));
      //os_printf("%u\r\n", (pusrdata-Ptr)); //This loops around the interger value giving a result back in the 4millons
      os_printf("Length: %u\r\n", length);
      os_printf("Logic:%u\r\n", length-(Ptr-pusrdata));
      //os_printf("%u\r\n", (&Ptr-&pusrdata)); //We don't really care about the addresses
      //os_printf("%u\r\n", (&pusrdata-&Ptr));
      */
      if(length-(Ptr-pusrdata) > 0) //It's possible data can be fragmented from the first packet
      {
         unsigned short packetlen = length-(Ptr-pusrdata);
         os_printf("Calling first packet remainding len:%u of %u\r\n", packetlen, length);
         FOTAWebServerConn_recv_callback(arg, Ptr, packetlen);//This function normally dosn't get called by chrome being predictable during development, This may change later sadly if IE frags the packets differently
      }
      else
      {
         //This is not normally called.
      }

   }

   if (strstr(pusrdata, "GET /favicon.ico HTTP/1.1") != NULL) //Skip FavIcon request
   {
      espconn_disconnect(&FOTAWebServerSocket);
      return;
   }

   if (strstr(pusrdata, "GET / HTTP/1.1") != NULL) //Display Config request
   {
      os_printf("[%s]\r\n", __func__);
      char * ResponseToSend = NULL;
      os_printf("[%s]s\r\n", __func__);
      if (system_get_userbin_addr() == 0x0)
      {
         os_printf("OTA Firmware is not detected, please load the OTA firmware\r\n");
         ResponseToSend = "<!DOCTYPE html><html><body>OTA Firmware is not detected, please load the OTA firmware</body></html>";
      }
      else
      {
         if(system_upgrade_userbin_check() == 0)
         {
            ResponseToSend = "<!DOCTYPE html><html><body><form action=\"upload\" method=\"post\" enctype=\"multipart/form-data\">Select image to upload to address 0x101000:<input type=\"file\" name=\"fileToUpload\" id=\"fileToUpload\"><input type=\"submit\" value=\"Upload Image\" name=\"submit\"></form></body></html>";
         }
         else
         {
            ResponseToSend = "<!DOCTYPE html><html><body><form action=\"upload\" method=\"post\" enctype=\"multipart/form-data\">Select image to upload to address 0x1000:<input type=\"file\" name=\"fileToUpload\" id=\"fileToUpload\"><input type=\"submit\" value=\"Upload Image\" name=\"submit\"></form></body></html>";
         }
      }
      os_printf("[%s]s1\r\n", __func__);
      //espconn_send(FOTApespconn, ResponseToSend, os_strlen(ResponseToSend));
      FOTAHttpSendWithHeader(FOTApespconn, ResponseToSend);
      os_printf("[%s]s2\r\n", __func__);
   }
}

LOCAL void ICACHE_FLASH_ATTR FOTAWebServerConn_connect_callback(void *arg)
{
   os_printf("[%s] Client Connected from port: ", __func__);
   struct espconn * FOTApespconn = (struct espconn *) arg;
   uint16_printf(FOTApespconn->proto.tcp->remote_port);   
   os_printf(" - ");
   uint16_printf(FOTApespconn->proto.tcp->local_port);   
   os_printf("\r\n");
   return;
   remot_info *premot = NULL;
   uint8 reter = espconn_get_connection_info(FOTApespconn,&premot,0);
   if (reter == ESPCONN_OK)
   {
      if(FOTApespconn->link_cnt)
      {
         os_printf("EspConn %u TCP connections:\r\n", FOTApespconn->link_cnt);
         int i = 0;
         while(i < FOTApespconn->link_cnt)
         {
            os_printf("%d) " IPSTR ":%u %s\r\n", i,  IP2STR(premot[i].remote_ip), premot[i].remote_port, FOTAmsg_espconn_state[premot[i].state] );
            i++;
         };
      }
   }
   else
   {
      os_printf("EspConn getting TCP connections failed: %d\r\n", reter);
   }
}

static ETSTimer http2spi_flash_reboot_timer;
void ICACHE_FLASH_ATTR FOTAWebServerConn_disconnect_callback(void *arg)
{
   os_printf("[%s] Client Disconnected from port: ", __func__);
   struct espconn * FOTApespconn = (struct espconn *) arg;
   uint16_printf(FOTApespconn->proto.tcp->remote_port);   
   os_printf(" - ");
   uint16_printf(FOTApespconn->proto.tcp->local_port);   
   os_printf("\r\n");

   if (RemotePortsOpenedInDownload == FOTApespconn->proto.tcp->remote_port)
   {
      os_printf("Last Status: gcontentlength(%d), DbufferIndex(%u)\r\n", gContentLength, FOTAdatabufferindex);

      uint32 Http2SPI_buf[8];
      spi_flash_read(FOTAburnto, Http2SPI_buf, sizeof(Http2SPI_buf));
      uint8 id = system_upgrade_userbin_check();
      char *err = http2spi_checkheader(Http2SPI_buf, 1-id);
      if (err != NULL) {
         os_printf("OTA Not a bootable bin, %s\n HTTP to SPI completed.\r\n", err);
         return -1;
      }

      os_printf("Reboot needed, rebooting...");
      // Schedule a reboot
      system_upgrade_flag_set(UPGRADE_FLAG_FINISH);
      os_timer_disarm(&http2spi_flash_reboot_timer);
      os_timer_setfn(&http2spi_flash_reboot_timer, (os_timer_func_t *)system_upgrade_reboot, NULL);
      os_timer_arm(&http2spi_flash_reboot_timer, 2000, 1);
   }
}

void ICACHE_FLASH_ATTR FOTAWebServerConn_sent_callback(void *arg)
{
   os_printf("[%s] Data Sent\r\n", __func__);
   espconn_disconnect(&FOTAWebServerSocket);
}

void ICACHE_FLASH_ATTR init_FOTAwebserver(uint16 port, void * LFOTAWebRecvCallBack(void *arg, char *pusrdata, unsigned short length)) //LFOTAWebRecvCallBack may need to point to the next pointer of the function and not the parent recv function
{
   os_printf("[%s]\r\n", __func__);
   //FOTAFormatedHTMLPageWithHttpHeader = (unsigned char*)os_zalloc(FOTAHTMLSIZE); //Never alloc on init. only when the far is used then free it asap!

   if (LFOTAWebRecvCallBack != NULL)
   {
      os_printf("Setting Callback for WebServer\r\n");
      FOTAWebRecvCallBack = LFOTAWebRecvCallBack;
   }
       FOTAWebServerSocket.type = ESPCONN_TCP;
       FOTAWebServerSocket.state = ESPCONN_NONE;
       FOTAWebServerSocket.proto.tcp = (esp_tcp *)os_zalloc(sizeof(esp_tcp));
      if (FOTAWebServerSocket.proto.tcp == 0x0)
      {
         os_printf("[%s][%s][%d] - Unable to Alloc memory, exiting\r\n", __FILE__ ,__func__, __LINE__);
         return;
      }
       FOTAWebServerSocket.proto.tcp->local_port = port;  // ESP8266 tcp port
       espconn_accept(&FOTAWebServerSocket);   // create tcp
   espconn_regist_connectcb(&FOTAWebServerSocket, FOTAWebServerConn_connect_callback);
       espconn_regist_recvcb(&FOTAWebServerSocket, FOTAWebServerConn_recv_callback); // register a tcp packet receiving callback
   espconn_regist_sentcb(&FOTAWebServerSocket, FOTAWebServerConn_sent_callback);
   espconn_regist_disconcb(&FOTAWebServerSocket, FOTAWebServerConn_disconnect_callback);
}

#endif



You can run the server with something like this
init_FOTAwebserver(9999, NULL);

Once ran, browse to the ESP's ip on that port and you should get prompted with a button to upload your OTA file. From what I recall I tested and valided this code a few years back.

FrenkR
Posts: 44
Joined: Thu Dec 04, 2014 9:25 am

Re: ESP8266 2MB + OTA

Postby FrenkR » Wed Oct 05, 2022 9:30 am

Hello,
I run into the same problem I believe. ESP-WROOM02 (16M, 512+512 OTA), bootloader 1.7, SDK 3.0.5, partition table:

Code: Select all

   #define SYSTEM_PARTITION_OTA_SIZE                     0x6A000
   #define SYSTEM_PARTITION_OTA_2_ADDR                     0x81000
   #define SYSTEM_PARTITION_RF_CAL_ADDR                  0x1fb000
   #define SYSTEM_PARTITION_PHY_DATA_ADDR                  0x1fc000
   #define SYSTEM_PARTITION_SYSTEM_PARAMETER_ADDR            0x1fd000
   #define SYSTEM_PARTITION_CUSTOMER_PRIV_PARAM_ADDR           0x7c000

I found following. Upgrade from user1 -> user2 works. When chip is running user2 code and I remove code "user1.bin" (OTA partition 1), system stops working and following error is displayed:

Code: Select all

Fatal exception (0):
epc1=0x40213e48, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000000, depc=0x00000000
Fatal exception (0):
epc1=0x40213e48, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000000, depc=0x00000000
Fatal exception (0):
epc1=0x40213e48, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000000, depc=0x00000000


0x40213e48 via disassembler points to following:

Code: Select all

40213e48 <init_bss_data>:
40213e48:   fffe61           l32r   a6, 40213e40 <print_system_param_sectors+0x18>
40213e4b:   fffe41           l32r   a4, 40213e44 <print_system_param_sectors+0x1c>
40213e4e:   050c         movi.n   a5, 0
40213e50:   07b467           bgeu   a4, a6, 40213e5b <init_bss_data+0x13>
40213e53:   004452           s8i   a5, a4, 0
40213e56:   441b         addi.n   a4, a4, 1
40213e58:   f79467           bne   a4, a6, 40213e53 <init_bss_data+0xb>
40213e5b:   f00d         ret.n
40213e5d:   00             .byte 00
40213e5e:   00             .byte 00
40213e5f:   00             .byte 00
40213e60:   08 90 fe 3f    
40213e64:   10 90 fe 3f    
40213e68:   cc 24 00 40    


It looks that even if OTA2 (user2.bin) firmware is running, something points to section in OTA1 and if user1.bin is not there, firmware will not run. Any idea what to check to fix this issue?
Rgds,
Frenk

FrenkR
Posts: 44
Joined: Thu Dec 04, 2014 9:25 am

Re: ESP8266 2MB + OTA

Postby FrenkR » Fri Oct 07, 2022 2:06 am

Issue resolved. If you have partition of size 1MB or 2MB, then "irom0_0_seg" address-es are the same for both partitions (looks like 0x1000 or 0x101000 are the same?). If you have 512KB partitions, then you must create LD script with different ROM addresses same way as is in LD files for 1024KB OTA partition segmentation(e.g.eagle.app.v6.new.1024.app1.ld, eagle.app.v6.new.1024.app2.ld).

If you don't do that, then uprading from app1 to app2 with the same bin will work, but if you will empty segment1, bin2 will stop working (which makes sense).

I hope that I saved 3 days of hard work "hunting" all those zillion of exceptions.
Rgds,
Frenk

Who is online

Users browsing this forum: No registered users and 227 guests