When trying to enter deepsleep mode on the LPC54618 an HardFault occurs. Going through step by step with gdb the instruction
0x200058e0 <+0>: push {r4, r5, r6, r7, lr}
in the function relocMem.8033 causes the HardFault. The Main stack starts at 0x200044a8 and has Size 0x1000. I have tried calling POWER_EnterDeepSleep with arguments uint64_t(-1), 0, and
Context:
++ MbedOS Fault Handler ++
FaultType: HardFault
Context:
R 0: FFFFFFFF
R 1: FFFFFFFF
R 2: 00000000
R 3: 200058E1
R 4: 20002BC4
R 5: 00000008
R 6: 20005474
R 7: 000084A1
R 8: 200030C4
R 9: 00000001
R 10: 00021744
R 11: 00000000
R 12: 200058E0
SP : 20005438
LR : 000088A5
PC : 200058E0
xPSR : 610F0000
PSP : 200053D0
MSP : 20027FC0
CPUID: 410FC241
HFSR : 40000000
MMFSR: 00000001
BFSR : 00000000
UFSR : 00000000
DFSR : 00000000
AFSR : 00000000
Mode : Thread
Priv : Privileged
Stack: PSP
-- MbedOS Fault Handler --
++ MbedOS Error Info ++
Error Status: 0x80FF013D Code: 317 Module: 255
Error Message: Fault exception
Location: 0x200058E0
Error Value: 0x20005538
Current Thread: main Id: 0x20004460 Entry: 0x111A1 StackSize: 0x1000 StackMem: 0x200044A8 SP: 0x20005438
For more info, visit: https://mbed.com/s/error?error=0x80FF013D
-- MbedOS Error Info --
Solved! Go to Solution.
Hello,
i have solved the problem. In Order to call POWER_EnterDeepSleep in an mbed-os Program you have to create an mbed::ScopedRamExecutionLock inside the Scope that needs to execute from RAM. Otherwise the execution will cause a Hardfault because of the MemoryProtectionUnit. It might be similarly handled in other Real-Time-Operating-Systems.
This also seems to eliminate all Problems with the Interrupts.
Unfortunately it still HardFaults just at another address (due to the build being a different one) but the same instruction. Running the underlying function DeepSleepReloc directly does not cause a hard fault.
Hi,
As the following figure of LPC546xx memory map, the address 0x2000_xxxx are SRAM, for the error code:0x200058e0 <+0>: push {r4, r5, r6, r7, lr}, it appears that you allocate/execute the code in SRAM instead of Flash, while you allocate main stack in address 0x200044a8, as you see the code address(0x200058e0) and stack address(0x200044a8) are approaching, I guess that the code is overlapped with stack, that is why you get the hard-fault error, but it is only guess.
Pls try to allocate the application code in flash instead of SRAM or the other SRAM address and have a try.
BR
XiangJun Rong
Is it possible, that calling the function directly from flash, corrupts the system state and makes interrupts impossible?
Because after calling the function from Flash i cannot cause the chip to wake up from deepsleep.
Hi
As you know that the LPC546xx uses interrupt mechanism to wake-up the processor from deep-sleep state, so you have to set up the ISR of the waking-up source. I suggest you run all the code in flash.
Anyway, in SDK, NXP provides power_manager_lpc example, which is fully tested, If you run the power_manager_lpc example directly, do you have any issue?
BR
XiangJun Rong
Hello,
i have solved the problem. In Order to call POWER_EnterDeepSleep in an mbed-os Program you have to create an mbed::ScopedRamExecutionLock inside the Scope that needs to execute from RAM. Otherwise the execution will cause a Hardfault because of the MemoryProtectionUnit. It might be similarly handled in other Real-Time-Operating-Systems.
This also seems to eliminate all Problems with the Interrupts.
Hi,
If you run the power_manager_lpc example directly, do you have any issue?
This is the code in above example when you enter deep sleep:
#define APP_EXCLUDE_FROM_DEEPSLEEP \
(SYSCON_PDRUNCFG_PDEN_SRAMX_MASK | SYSCON_PDRUNCFG_PDEN_SRAM0_MASK | SYSCON_PDRUNCFG_PDEN_SRAM1_2_3_MASK)
case kPmu_Deep_Sleep: /* Enter deep sleep mode. */
POWER_EnterDeepSleep(APP_EXCLUDE_FROM_DEEPSLEEP);
break;
Pls have a try
BR
XiangJun Rong