Discuss here different C compiler set ups, and compiling executables for the ESP8266
User avatar
By Pato
#77999 Hi all !

I've the following test code that crashes right after boot with Fatal Exceptions depending on wether I link my code with the gc-option and if I link against some libs whoses functions are never called (no problem, not a signle line of my user code is even executed).

More interestingly, I noticed the crash only when I build my app for FOTA:
The simple code below runs as expected when compiled for non-FOTA. But when compiled for FOTA:

- If linked with gc-section option, works only if pwm_start() is commented out.
- If linked without gc-section option, works only if pwm_start() and espconn_secure_set_size() are commented out...

I strongly suspect some misaligned data.
The problem seems related to the influence of the order of the libs in the linker command (viewtopic.php?f=9&t=11972) but I can't see the logic to deduce the correct ordering, that seems to varies from an app to another.

Full of hope, I tried to force 4-byte alignment of the symbol _Pri_3_HandlerAddress, that is not aligned accorind to this post, as when I look into the disasembled code the very first instructions of user code seems to deal with NMI (viewtopic.php?f=6&t=4675&p=46002&hilit=linking+library+order#p46002)

This is making me crazy from weeks, would you have any idea ?

Code: Select all/*
 * Debuging app that crashes with fatal exception when compiled fo OTA.
 * Compiled fo non-OTA: works
 * Compiled for OTA (bootloader 1.7): fatal exception right after boot. Due to PWM lib ?
 */


#include "osapi.h"
#include "os_type.h"
#include "user_interface.h"
#include "gpio.h"
#include "pwm.h"
#include "espconn.h"
#include "driver/i2c_master.h"


void PostInitCb(void);
uint32 user_rf_cal_sector_set(void);
void user_init(void);




/**
 * @brief   Called when system is fully initialized.
 */
void PostInitCb(void)
{   
    os_printf("PostInitCb() !\n");
   
    /* Force references to functions from the libs without calling them */
    volatile bool tt = false;
    if(tt)
    {     
        pwm_start();                                      /* Uncommented: crash ! */
        gpio_init();                                      /* Uncommented or commented: ok  */
        espconn_secure_set_size(ESPCONN_CLIENT, 5120);    /* Uncommented or commented: depends on gc-section */
        i2c_master_gpio_init();                           /* Uncommented or commented: ok  */
    }
}




/**
 * @brief   Was present in IoT_Demo/user/user_main.c on which this code is based...
 */
uint32 ICACHE_FLASH_ATTR user_rf_cal_sector_set(void)
{
    os_printf("BB!\n");
   
    enum flash_size_map size_map = system_get_flash_size_map();
    uint32 rf_cal_sec = 0;
   

    switch (size_map) {
        case FLASH_SIZE_4M_MAP_256_256:
            rf_cal_sec = 128 - 5;
            break;

        case FLASH_SIZE_8M_MAP_512_512:
            rf_cal_sec = 256 - 5;
            break;

        case FLASH_SIZE_16M_MAP_512_512:
            rf_cal_sec = 512 - 5;
            break;
        case FLASH_SIZE_16M_MAP_1024_1024:
            rf_cal_sec = 512 - 5;
            break;

        case FLASH_SIZE_32M_MAP_512_512:
            rf_cal_sec = 1024 - 5;
            break;
        case FLASH_SIZE_32M_MAP_1024_1024:
            rf_cal_sec = 1024 - 5;
            break;

        case FLASH_SIZE_64M_MAP_1024_1024:
            rf_cal_sec = 2048 - 5;
            break;
        case FLASH_SIZE_128M_MAP_1024_1024:
            rf_cal_sec = 4096 - 5;
            break;
        default:
            rf_cal_sec = 0;
            break;
    }

    return rf_cal_sec;
}




/**
 * @brief   Main entry point of our programm
 */
void user_init(void)
{
    os_printf("AA!\n");
    system_init_done_cb(PostInitCb);   
}


My Xtensa compiler command looks like:
I then use esptool elf2image -version=2 to convert the elf to binaries.
(esp-open-sdk, NONOS-SDK 2.2, esp8266 with 2MBytes 512+512 flash map)
Code: Select allxtensa-lx106-elf-gcc *.c   -Wall -Wextra -Wconversion -Wshadow -Wcast-qual -Wdouble-promotion -Wcast-align -Wmissing-prototypes -std=c99 -pedantic -Wno-missing-braces -Wno-missing-field-initializers -mlongcalls -DICACHE_FLASH -ffunction-sections -fdata-sections -I. -isystem../ESP8266_NONOS_SDK-2.2.0/include -isystem../ESP8266_NONOS_SDK-2.2.0/driver_lib/include -nostdlib -Wl,-EL -mtext-section-literals -L../ESP8266_NONOS_SDK-2.2.0/lib -T../ESP8266_NONOS_SDK-2.2.0/ld/eagle.app.v6.new.1024.app1.ld -Wl,--no-check-sections -Wl,--gc-sections -u call_user_start -Wl,-static -Wl,--start-group -lc -lgcc -lphy -lpp -lmain -lwpa -lcrypto -llwip -lupgrade -lssl -lpwm -ldriver -lnet80211 -lm -Wl,--end-group -o debug_rom1.bin.elf


Many thanks !
User avatar
By Pato
#78010 Hello !

Actually I don't really need this option. I just pick it from the Makefiles provided by Espressif in their SDK, in case it would have had any influence...
But it doesn't: compiling with or without it does no change the bin (same MD5 checksum).

Adding -gc-section removes some kilobytes of code as excpected, and I have the vague feeling that the app is more likely to crash if it is compiled with (cf. the test in my first post).

But it really seems to be the presence or the absence of the unused libs that makes the crash occur :)

(PS: Wow, thanks for your reactivity !)
User avatar
By jcmvbkbc
#78047
Pato wrote:Actually I don't really need this option. I just pick it from the Makefiles provided by Espressif in their SDK, in case it would have had any influence...
But it doesn't: compiling with or without it does no change the bin (same MD5 checksum).

It shouldn't change the binary, but its presence suppresses linker warnings. But if removing it doesn't change anything -- ok, that doesn't add any clues.
Can you post the fatal exception message and the link map of the firmware that produced it? (Map file can be created with '-Map=map_file_name' added to the linker options).