2025-09-04 11:30 AM
Hey all,
For reference I am enabling the https server using NetxDuo Stack for firmware update in my device.
Initially we were using Internal Flash but now we are interested in External Flash particularly SDRAM. I was able to boot the application code from SDRAM, however i am facing a problem, whenever i call a rest API like GET request a hardfault occurs where the stack traces shows it is originated over _nx_crypto_sha256_update() function in the nx_crypto_sha2.c file over the use the memcpy(). The strange thing is everything works with no hardfault when application work in Internal Flash.
Furthermore, I am able to run RTOS on SDRAM and i can ping my IP on ethernet as well.
Kindly someone help me out for this, i will be grateful.
Also if i should report this behavior somewhere else?
Thanks
Solved! Go to Solution.
2025-09-09 9:26 AM - edited 2025-09-09 9:27 AM
Ok, I am able to solve this issue by making the SDRAM region as cachable as well as bufferable through MPU.
I have one question why can i call MPU_Config in application in External Flash but not in SDRAM ?
Thanks
2025-09-04 12:26 PM
Perhaps show a register dump and code at the Fault
What memory addresses is the memcpy() acting on? Is it aligned?
An effective Hard Fault dump of registers, stack and opcodes will help get some action, as would a minimally buildable project illustrating the failure.
2025-09-04 12:32 PM - edited 2025-09-04 12:59 PM
The memcpy at the entry or exit?
How are you allocating the memory being used to store structures?
The memcpy's are typically acting on the context's buffer when the inputs are feed in blocks other than 64 byte multiples. Perhaps instrument the calling to see the flow dynamics prior to the hard fault failure. Perhaps you can use that to extract a minimally failing test case?
Check alignment of context buffer. Is that also in SDRAM ?
2025-09-05 9:42 AM
Here is the stack that is being shown when i do GET request:
Here is the mapping of the address to show the line number from where the error is triggering from:
using the arm-none-eabi-addr2line I have mapped these address to the line number
0xc070156e Function : HardFault_Handler, File: stm32h7xx_it.c Line: 94
0xc070093e Function : memcpy, File: ?, Line: ??
0xc0719e96 Function : _nx_crypto_sha256_update function, File: nx_crypto_sha2.c, Line: 268
> What memory addresses is the memcpy() acting on? Is it aligned?
Is there a better way to debug this ? and how to check if the memcpy() memory address is aligned ?
> The memcpy at the entry or exit?
Based on the line number, it is most probably the exit one.
> How are you allocating the memory being used to store structures?
Seems like this is being called by NetxDuo and is passed as a pointer are you saying I should track whether it is dynamically created ?
> Check alignment of context buffer. Is that also in SDRAM ?
I think it is aligned and not in SDRAM.
More Context
I tried running the same application by booting from External Flash as well and it worked fine there with no problem.
If booting the application from SDRAM, the https won't work because of this HardFault however the http still work with REST APIs. Only this crypto related file cause Hardfault in that case.
Also for the case of SDRAM, i removed the systemInit() function from the application startup script as it was causing error and the MPU configuration is disabled in application as it was already enabled and working in bootloader:
Here is my bootloader MPU configuration:
void MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_InitStruct = {0};
/* Disables the MPU */
HAL_MPU_Disable();
/** Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.BaseAddress = 0x0;
MPU_InitStruct.Size = MPU_REGION_SIZE_4GB;
MPU_InitStruct.SubRegionDisable = 0x87;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/** Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.BaseAddress = 0x24000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_128KB;
MPU_InitStruct.SubRegionDisable = 0x0;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/** Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Number = MPU_REGION_NUMBER2;
MPU_InitStruct.Size = MPU_REGION_SIZE_256B;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Region 4: External Flash (OCTOSPI, 0x90080000 - 0x907FFFFF) now with Full Access (readable & writable)
* This area is removed from Region 0 to apply the desired access rights here.
*/
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x90000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_8MB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; // Read/Write access
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER4;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; // If XIP (code execution) is desired; otherwise MPU_INSTRUCTION_ACCESS_DISABLE
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Configure the MPU attributes for SDRAM */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0xC0000000; // Start address of SDRAM Bank 1
MPU_InitStruct.Size = MPU_REGION_SIZE_8MB; // SDRAM size
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE; // Currently MPU_ACCESS_CACHEABLE causes incorrect data
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER3; // MPU region number
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Enables the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
Thanks a lot.
2025-09-05 10:18 AM
The "better" way is to instrument the code, perhaps put in sanity checks where you check the address range and alignment (with a mask), AND dump actionable data and registers from the fault.
The line number might help it you have the source to hand which the app was built from, but the MCU executes THUMB code, not C code.
Get some viable diagnostics coming out of an available serial port so you can observe dynamic behaviour in a less invasive way, and that you don't have to dig through structures manually. ie automate, so you might refine your ability to catch errant values prior to in faulting, when they are first seen to be wrong.
Adapt something like this to capture and report faulting condition without a debugger. The debugger can help determine source and line info, which otherwise you'll need to fish out of the .MAP or .LST files.
https://github.com/cturvey/RandomNinjaChef/blob/main/KeilHardFault.c
The line number suggests it's the exit memcpy, so check upstream to see how that code is passing blocks of data to the SHA2 update routine, and the integrity of the context passed in.
2025-09-09 9:26 AM - edited 2025-09-09 9:27 AM
Ok, I am able to solve this issue by making the SDRAM region as cachable as well as bufferable through MPU.
I have one question why can i call MPU_Config in application in External Flash but not in SDRAM ?
Thanks
2025-09-09 10:28 AM
>>I have one question why can i call MPU_Config in application in External Flash but not in SDRAM ?
I don't know, how exactly does it fail? Does it Fault, if so show register dump from fault to establish WHAT the MCU is objecting too.
Are you using the SDRAM for stack?
Changing how the MCU handles a specific memory, whilst running from that memory, strikes me as a recipe for issues. Bring the external memories up once, and then don't change them a second time, or the clocking, as this can be disruptive.