I have a bootloader / application setup on the S32k324. It ran well enough until we needed to change the map to scavenge ram. We are only using core0 at the moment. The second core is disabled.
When the linker files match (bootloader (0x400000)to application (0x420080)) there is no issue. I can redefine the offset for the application flash (currently at 0x420080) without issue. If I deviate from the initial sram/itcm/dtcm settings used in the bootloader to re-purpose the disabled Core1's ram, the application hardfaults. If I load the application from the bootloader (0x400000) offset the application works fine with the new linker file.
What would cause the issue?
Solved! Go to Solution.
We've found a possible solution and are testing.
Added the following to startup_cm7.s
/*GetCoreID*/
ldr r0, =0x40260004
ldr r1,[r0]
/*Disable mpu if enabled*/
movs r2, #0
mov.w r0, #3758153728 /* 0xe000e000 */
mov r1, r2
str.w r2, [r0, #3476] /* 0xd94*/
ldr r0, =MAIN_CORE
cmp r1,r0
beq SetCore0Stack
b SetCore1Stack
Hi @dtyree
Similar issues are usually caused by wrong or missing SRAM initialization. It is mandatory to initialize the SRAM as described in the S32K3 reference manual:
You can find initialization code in startup_cm7.s:
And the addresses are defined in linker file:
When the code crashes, you can check the SRAM content. If your debugger shows something like ‘XX‘ or ‘??’ instead of valid data, it’s caused by this SRAM initialization. You need to ensure that whole SRAM is initialized appropriately.
If you have bootloader and application or multicore application, you need to decide who and when will initialize the SRAM.
Regards,
Lukas
Is it possible for the application to re-initialize memory if the bootloader runs first?
My startup files are based on S32K3_RTD_2_0_0_D2203_ASR_REL_4_4_REV_0000_20220331 for both applications.
Yes, the application can re-initialize SRAM memory. But if it was already initialized by bootloader, it's unnecessary operation.
When we set the Base address of the application to 0x400000. It loads and runs.
When the application base address is set to 0x420080 and jumped to from the bootloader we get hard fault on memory that was not initialized by the bootloader on first use, or initialization.
I checked the rasr and rbar registers, and can see them being changed in ram.
Also see the values within ‘S32_MPU’ being updated with the rasr and rbar value, but have no way of telling if they are actually being applied.
However, I see MPU (memory protection unit) is already enabled before we attempt to reconfigure the memory. It then attempts to enable the MPU before reenabling the cache.
Do we need to set MPU->CTRL[0] to 0 before we can modify these values? I was unable to find a reference to that in the data sheet.
Dtyree,
MPU is ARM IP, and hence is documented in the armv7-m architecture reference
Does the generic linker (linker_flash_s32k324.ld) work for you? This does not reserve SRAM space for core 1:
MEMORY
{
int_pflash : ORIGIN = 0x00400000, LENGTH = 0x003D4000 /* 4096KB - 176KB (sBAF + HSE)*/
int_dflash : ORIGIN = 0x10000000, LENGTH = 0x00020000 /* 128KB */
int_itcm : ORIGIN = 0x00000000, LENGTH = 0x00008000 /* 32KB */
int_dtcm : ORIGIN = 0x20000000, LENGTH = 0x0000F000 /* 60KB */
int_stack_dtcm : ORIGIN = 0x2000F000, LENGTH = 0x00001000 /* 4KB */
int_sram : ORIGIN = 0x20400000, LENGTH = 0x0002FF00 /* 192KB, needs to include int_sram_fls_rsv */
int_sram_fls_rsv : ORIGIN = 0x2042FF00, LENGTH = 0x00000100
int_sram_no_cacheable : ORIGIN = 0x20430000, LENGTH = 0x0000FF00 /* 64KB, needs to include int_sram_results */
int_sram_results : ORIGIN = 0x2043FF00, LENGTH = 0x00000100
int_sram_shareable : ORIGIN = 0x20440000, LENGTH = 0x00004000 /* 16KB */
ram_rsvd2 : ORIGIN = 0x20444000, LENGTH = 0 /* End of SRAM */
}
Note that, ITCM and DTCM do not get extended, as these are local to each core.
I would try to link against this file instead of the C0, C1. It should be in the same eclipse/plugins/Platform_<version>/build_files/<compiler>/ as the c0 and c1 variants.
As for the MPU, It may be a good idea to disable this before configuration as this will prevent issues/faults during configuration itself. The only requirement to write these registers is privileged run mode (which is the default unless you are manually switching to user mode).
Best,
Bryan
We've found a possible solution and are testing.
Added the following to startup_cm7.s
/*GetCoreID*/
ldr r0, =0x40260004
ldr r1,[r0]
/*Disable mpu if enabled*/
movs r2, #0
mov.w r0, #3758153728 /* 0xe000e000 */
mov r1, r2
str.w r2, [r0, #3476] /* 0xd94*/
ldr r0, =MAIN_CORE
cmp r1,r0
beq SetCore0Stack
b SetCore1Stack