Skip to main content
Associate II
November 7, 2025
Question

Unhandled exception when enabling compiler optimization (-O2) on SPC58NH92 multicore project

  • November 7, 2025
  • 1 reply
  • 230 views

Hi everyone,

I’m working on a project using the SPC58NH92 MCU with SPC5 LLD (RLA) drivers.
The setup runs FreeRTOS on Core2 and bare-metal code on Core0.

Both cores share data through a dedicated RAM region, with synchronization handled by SEMA4 for access control and cache invalidate/flush operations to maintain data coherence.

The application works perfectly when compiled without optimization (-O0). However, when I build with optimization level -O2, the system throws an unhandled exception during runtime.

I’m using FreeGCC as the compiler (SPC5Studio environment).

Has anyone faced a similar issue on SPC58 multicore systems?
Are there any additional recommendations or known considerations regarding shared memory, cache management, or compiler optimization in this setup?

Thanks in advance for any help or insights!

1 reply

November 7, 2025

The crash at -O2 happens because compiler optimizations reorder shared-memory accesses between cores.
:white_heavy_check_mark: Fix: mark shared variables as volatile, add memory barriers (__sync_synchronize()), and ensure proper cache flush/invalidate around shared data.

Associate II
November 11, 2025

Hi James!

Thank you very much for your reply.

Here's a small snippet of code that accesses shared memory.

Even with __sync_synchronize(), I'm still getting an unhandled exception.

__attribute__((section(".RamShared"))) volatile AEC_ADCConv_t sharedCoreADC;

#define SHARED_CORE_ADC_ADDR ((uint32_t)&sharedCoreADC)
#define SHARED_CORE_ADC_SIZE ((uint16_t)sizeof(sharedCoreADC))
#define DMA_CACHE_INVALIDATE_BUFFER(ptr, len) cache_invalidate_range((uint32_t)(ptr), (len))
#define DMA_CACHE_FLUSH_BUFFER(ptr, len) cache_flush_range((uint32_t)(ptr), (len))

__attribute__((section(".RamFunc"))) bool_t AEC_SetSharedCoreADC(AEC_ADCConv_t adc)
{
 bool_t errorFlag = FALSE;

 if(sema4_lock(semADC) == SEMA4_NO_ERROR)
 {
 memcpy((void*)&sharedCoreADC, (const void*)&adc, sizeof(AEC_ADCConv_t));

 // Flush and synchronize data
 DMA_CACHE_FLUSH_BUFFER(SHARED_CORE_ADC_ADDR, SHARED_CORE_ADC_SIZE);
 __sync_synchronize();

 sema4_unlock(semADC);
 }
 else
 {
 errorFlag = TRUE;
 }
 return (errorFlag);
}

__attribute__((section(".RamFunc"))) bool_t AEC_GetSharedCoreADC(AEC_ADCConv_t* adc)
{
 bool_t errorFlag = FALSE;

 if(sema4_lock(semADC) == SEMA4_NO_ERROR)
 {
 // Invalidate and synchronize data
 __sync_synchronize();
 DMA_CACHE_INVALIDATE_BUFFER(SHARED_CORE_ADC_ADDR, SHARED_CORE_ADC_SIZE);

 memcpy((void*)adc, (const void*)&sharedCoreADC, sizeof(AEC_ADCConv_t));
 sema4_unlock(semADC);
 }
 else
 {
 errorFlag = TRUE;
 }
 return (errorFlag);
}