Hello Community,
I'm working on a bootloader for a custom PCB with the S32K118 processor. Here i communicate al the data of the hexfile through the CAN communication and write each flash sector to the following address and upwards: 0x20000.This bootloader successfully flashes the communicated data to the flash of the MCU. And if i jump to the application that is flashed it seems to work fine.
But when i change the optimization level of my bootloader code from none to for example -O3 like below in my build settings:

Something strange happens in on of my methods:
status_t abs_Flash_Write_Sector(uint32_t address, uint32_t size, uint8_t* sourceBuffer, uint32_t bufferSize)
{
status_t ret = STATUS_SUCCESS;
uint32_t failAddress = 0;
INT_SYS_DisableIRQGlobal();
/* Set callback function before a long time consuming flash operation
* (ex: erasing) to let the application code do other tasks while flash
* in operation. In this case we use it to enable interrupt for
* Flash Command Complete event */
flash_callback_t pCallBack = (flash_callback_t)CCIF_Callback;
flashSSDConfig.CallBack = pCallBack;
/* Erase the specific PFlash sector */
/* Configure address, size to erase sector function. For example on S32K144 */
size = FEATURE_FLS_PF_BLOCK_SECTOR_SIZE;
ret = FLASH_DRV_EraseSector(&flashSSDConfig, address, size); <----------- HERE MY CODE CRASHES (more info below)
DEV_ASSERT(STATUS_SUCCESS == ret);
/* Disable Callback */
flashSSDConfig.CallBack = NULL_CALLBACK;
/* Verify the erase operation at margin level value of 1, user read */
ret = FLASH_DRV_VerifySection(&flashSSDConfig, address, size / FTFx_DPHRASE_SIZE, 1u);
DEV_ASSERT(STATUS_SUCCESS == ret);
/* Write some data to the erased PFlash sector */
ret = FLASH_DRV_Program(&flashSSDConfig, address, bufferSize, sourceBuffer);
DEV_ASSERT(STATUS_SUCCESS == ret);
/* Verify the program operation at margin level value of 1, user margin */
ret = FLASH_DRV_ProgramCheck(&flashSSDConfig, address, bufferSize, sourceBuffer, &failAddress, 1u);
DEV_ASSERT(STATUS_SUCCESS == ret);
INT_SYS_EnableIRQGlobal();
return ret;
}
When this method is called the and i run the debug with my Universal Multilink Debug probe its shows that is crashes and goes to the default ISR. And when i place a breakpoint the FLASH_DRV_EraseSector() returns a STATUS_ERROR.

When i unplug the debug probe restart the pcb and run my code without debug. The same fault seems to happen when i start to flash my hexfile to the device. Because is can see it stops working on the same spot.
I'm not sure why this is happening. I've read that uninitialized variables can cause this behavior, but i made sure that everything i could think of is initialized.
Does anybody have a clou what can be the cause of this? Any help is greatly appriciated.
Below my linker file of the bootloader:
/* Entry Point */
ENTRY(Reset_Handler)
HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x00000200;
STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x00000200;
/* If symbol __flash_vector_table__=1 is defined at link time
* the interrupt vector will not be copied to RAM.
* Warning: Using the interrupt vector from Flash will not allow
* INT_SYS_InstallHandler because the section is Read Only.
*/
M_VECTOR_RAM_SIZE = DEFINED(__flash_vector_table__) ? 0x0 : 0x00C0;
/* Specify the memory areas */
MEMORY
{
/* Flash */
m_interrupts (RX) : ORIGIN = 0x00000000, LENGTH = 0x000000C0
m_flash_config (RX) : ORIGIN = 0x00000400, LENGTH = 0x00000010
m_text (RX) : ORIGIN = 0x00000410, LENGTH = 0x0001FFFF - 0x00000410 /* 16KB - 0x10*/
/* SRAM_L */
m_custom (RW) : ORIGIN = 0x1FFFFC00, LENGTH = 0x00000400
/* SRAM_U */
m_data (RW) : ORIGIN = 0x20000000, LENGTH = 0x000030C0
m_data_2 (RW) : ORIGIN = 0x200030C0, LENGTH = 0x00002740
m_exchange_info (RW) : ORIGIN = 0x20005800, LENGTH = 0x00000010
}
/* Define output sections */
SECTIONS
{
/* The startup code goes first into internal flash */
.interrupts :
{
__VECTOR_TABLE = .;
__interrupts_start__ = .;
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
__interrupts_end__ = .;
. = ALIGN(4);
} > m_interrupts
.flash_config :
{
. = ALIGN(4);
KEEP(*(.FlashConfig)) /* Flash Configuration Field (FCF) */
. = ALIGN(4);
} > m_flash_config
/* The program code and other data goes into internal flash */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
*(.init) /* section used in crti.o files */
*(.fini) /* section used in crti.o files */
*(.eh_frame) /* section used in crtbegin.o files */
. = ALIGN(4);
} > m_text
/* Section used by the libgcc.a library for fvp4 */
.ARM :
{
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} > m_text
__etext = .; /* Define a global symbol at end of code. */
__DATA_ROM = .; /* Symbol is used by startup for data initialization. */
.interrupts_ram :
{
. = ALIGN(4);
__VECTOR_RAM__ = .;
__RAM_START = .;
__interrupts_ram_start__ = .; /* Create a global symbol at data start. */
*(.m_interrupts_ram) /* This is a user defined section. */
. += M_VECTOR_RAM_SIZE;
. = ALIGN(4);
__interrupts_ram_end__ = .; /* Define a global symbol at data end. */
} > m_data
__VECTOR_RAM = DEFINED(__flash_vector_table__) ? ORIGIN(m_interrupts) : __VECTOR_RAM__ ;
__RAM_VECTOR_TABLE_SIZE = DEFINED(__flash_vector_table__) ? 0x0 : (__interrupts_ram_end__ - __interrupts_ram_start__) ;
.data : AT(__DATA_ROM)
{
. = ALIGN(4);
__DATA_RAM = .;
__data_start__ = .; /* Create a global symbol at data start. */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(4);
__data_end__ = .; /* Define a global symbol at data end. */
} > m_data
__DATA_END = __DATA_ROM + (__data_end__ - __data_start__);
__CODE_ROM = __DATA_END; /* Symbol is used by code initialization. */
.code : AT(__CODE_ROM)
{
. = ALIGN(4);
__CODE_RAM = .;
__code_start__ = .; /* Create a global symbol at code start. */
__code_ram_start__ = .;
*(.code_ram) /* Custom section for storing code in RAM */
. = ALIGN(4);
__code_end__ = .; /* Define a global symbol at code end. */
__code_ram_end__ = .;
} > m_data
__CODE_END = __CODE_ROM + (__code_end__ - __code_start__);
__CUSTOM_ROM = __CODE_END;
/* Custom Section Block that can be used to place data at absolute address. */
/* Use __attribute__((section (".customSection"))) to place data here. */
/* Use this section only when MTB (Micro Trace Buffer) is not used, because MTB uses the same RAM area, as described in S32K Reference Manual. */
.customSectionBlock ORIGIN(m_custom) : AT(__CUSTOM_ROM)
{
__customSectionStart = .;
__customSection_start__ = .;
KEEP(*(.customSection)) /* Keep section even if not referenced. */
__customSection_end__ = .;
} > m_custom
__CUSTOM_END = __CUSTOM_ROM + (__customSection_end__ - __customSection_start__);
__rom_end = __CUSTOM_END;
/* Uninitialized data section. */
.bss :
{
/* This is used by the startup in order to initialize the .bss section. */
. = ALIGN(4);
__BSS_START = .;
__bss_start__ = .;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
__BSS_END = .;
} > m_data_2
/* Put heap section after the program data */
.heap :
{
. = ALIGN(8);
__end__ = .;
__heap_start__ = .;
PROVIDE(end = .);
PROVIDE(_end = .);
PROVIDE(__end = .);
__HeapBase = .;
. += HEAP_SIZE;
__HeapLimit = .;
__heap_limit = .;
__heap_end__ = .;
} > m_data_2
/* Initializes stack on the end of block */
__StackTop = ORIGIN(m_data_2) + LENGTH(m_data_2);
__StackLimit = __StackTop - STACK_SIZE;
PROVIDE(__stack = __StackTop);
__RAM_END = __StackTop;
.stack __StackLimit :
{
. = ALIGN(8);
__stack_start__ = .;
. += STACK_SIZE;
__stack_end__ = .;
} > m_data_2
.ARM.attributes 0 : { *(.ARM.attributes) }
/* Memory validation */
ASSERT(__rom_end <= (ORIGIN(m_text) + LENGTH(m_text)), "Region m_text overflowed!")
ASSERT(__StackLimit >= __HeapLimit, "region m_data_2 overflowed with stack and heap")
}