2024-10-15 10:52 PM
Hi, I would like to know the procedure to execute specific functions from RAM.
I have tried __ramfunc at beginning of the function but it requires all the subsequent functions also to be run from RAM. This would require lot of manual code updates. Is there a way to do it from linker script? I tried placing the functions like below but it would not move the function from ROM to RAM.
place in RAM_region { readwrite,
block CSTACK,
block HEAP,
readonly object function1 // this is my expected function to run from RAM
};
Solved! Go to Solution.
2024-10-21 04:40 AM
Did you test the project I shared as it is and checked how it works?
Are you using an RTOS? if yes start with a simple code (without RTOS), then move on to a complex code.
For the interrupt, I suggested to follow the application note section: 2.2 Execute an interrupt handler from CCM SRAM.
2024-10-15 11:03 PM
What compiler /IDE? What MCU exactly?
2024-10-15 11:05 PM
2024-10-15 11:19 PM
MCU - STM32H573VI
IDE - IAR 9.30.1
2024-10-15 11:23 PM
Hi STTwo-32,
I am using STM32H573VI MCU and IAR 9.30.1 IDE. I went through the article but it did not contain the required information. There exists lot of code currently written by other over so many years and now we are facing timing issues. To increase the execution speed, we are tying to run specific functions only from RAM. How do I select those specific functions via Linker script and do not disturb the code base?
2024-10-15 11:43 PM
Hello @nagarasr ,
Please refer to this application note section 2: https://www.st.com/resource/en/application_note/an4296-use-stm32f3stm32g4-ccm-sram-with-iar-embedded-workbench-keil-mdkarm-stmicroelectronics-stm32cubeide-and-other-gnubased-toolchains-stmicroelectronics.pdf
2024-10-16 12:42 AM
Thank you for directing me to the section. I tried but now the code does not run properly with these settings. I get a pop up indicating there is a warning in flash loader and map file generates so many veneer sections (I have no clue about these). Below is the debug log for the same.
Wed Oct 16, 2024 13:05:28: IAR Embedded Workbench 9.30.1 (C:\Program Files\IAR
Systems\Embedded Workbench 9.1\arm\bin\armPROC.dll)
Wed Oct 16, 2024 13:05:28: Loaded macro file: C:\Program Files\IAR Systems\Embedded
Workbench 9.1\arm/config/debugger/ST/STM32H5xx.dmac
Wed Oct 16, 2024 13:05:28: Loaded macro file: C:\Program Files\IAR Systems\Embedded
Workbench 9.1\arm/config/debugger/ST/STM32H5xx_DBG.dmac
Wed Oct 16, 2024 13:05:28: Flash download warning: 18676 out of 18676 bytes from data
record CODE:[0x2009'0000,0x2009'48f3] will not be flashed
Wed Oct 16, 2024 13:05:28: There were warnings while generating flash loader input.
Wed Oct 16, 2024 13:05:28: See the Debug Log window for details.
Wed Oct 16, 2024 13:05:33: Device "CORTEX-M33" selected.
Wed Oct 16, 2024 13:05:33: JLINK command: ProjectFile = C:\BC\224usage\
cc_arm_phase1\apps\main_app\tools\ewarm\settings\main_app_debug.jlink, return = 0
Wed Oct 16, 2024 13:05:33: Device "STM32H573VI" selected.
Wed Oct 16, 2024 13:05:33: DLL version: V7.92g, compiled Sep 27 2023 15:35:10
Wed Oct 16, 2024 13:05:33: Firmware: J-Link V10 compiled Jan 30 2023 11:28:07
Wed Oct 16, 2024 13:05:33: Selecting SWD as current target interface.
Wed Oct 16, 2024 13:05:33: JTAG speed is initially set to: 1000 kHz
Wed Oct 16, 2024 13:05:33: InitTarget() start
Wed Oct 16, 2024 13:05:33: SWD selected. Executing JTAG -> SWD switching sequence.
Wed Oct 16, 2024 13:05:33: DAP initialized successfully.
Wed Oct 16, 2024 13:05:33: Enabling debug in 'Standby' & 'Stop' mode.
Wed Oct 16, 2024 13:05:33: Enabling stop of IWDG & WWDG in debug mode.
Wed Oct 16, 2024 13:05:33: InitTarget() end - Took 6.37ms
Wed Oct 16, 2024 13:05:33: Found SW-DP with ID 0x6BA02477
Wed Oct 16, 2024 13:05:33: DPIDR: 0x6BA02477
Wed Oct 16, 2024 13:05:33: CoreSight SoC-400 or earlier
Wed Oct 16, 2024 13:05:33: Scanning AP map to find all available APs
Wed Oct 16, 2024 13:05:33: AP[2]: Stopped AP scan as end of AP map has been reached
Wed Oct 16, 2024 13:05:33: AP[0]: APB-AP (IDR: 0x54770002)
Wed Oct 16, 2024 13:05:33: AP[1]: AHB-AP (IDR: 0x84770001)
Wed Oct 16, 2024 13:05:33: Iterating through AP map to find AHB-AP to use
Wed Oct 16, 2024 13:05:33: AP[0]: Skipped. Not an AHB-AP
Wed Oct 16, 2024 13:05:33: AP[1]: Core found
Wed Oct 16, 2024 13:05:33: AP[1]: AHB-AP ROM base: 0xE00FE000
Wed Oct 16, 2024 13:05:33: CPUID register: 0x410FD214. Implementer code: 0x41 (ARM)
Wed Oct 16, 2024 13:05:33: Feature set: Mainline
Wed Oct 16, 2024 13:05:33: Cache: No cache
Wed Oct 16, 2024 13:05:33: Found Cortex-M33 r0p4, Little endian.
Wed Oct 16, 2024 13:05:33: Cortex-M (ARMv8-M and later): The connected J-Link (S/N
50119442) uses an old firmware module that does not handle I/D-cache correctly. Proper
debugging functionality cannot be guaranteed if cache is enabled
Wed Oct 16, 2024 13:05:33: FPUnit: 8 code (BP) slots and 0 literal slots
Wed Oct 16, 2024 13:05:33: Security extension: not implemented
Wed Oct 16, 2024 13:05:33: CoreSight components:
Wed Oct 16, 2024 13:05:33: ROMTbl[0] @ E00FE000
Wed Oct 16, 2024 13:05:33: [0][0]: E00FF000 CID B105100D PID 000BB4C9 ROM Table
Wed Oct 16, 2024 13:05:33: ROMTbl[1] @ E00FF000
Wed Oct 16, 2024 13:05:33: [1][0]: E000E000 CID B105900D PID 000BBD21 DEVARCH
47702A04 DEVTYPE 00 Cortex-M33
Wed Oct 16, 2024 13:05:33: [1][1]: E0001000 CID B105900D PID 000BBD21 DEVARCH
47701A02 DEVTYPE 00 DWT
Wed Oct 16, 2024 13:05:33: [1][2]: E0002000 CID B105900D PID 000BBD21 DEVARCH
47701A03 DEVTYPE 00 FPB
Wed Oct 16, 2024 13:05:33: [1][3]: E0000000 CID B105900D PID 000BBD21 DEVARCH
47701A01 DEVTYPE 43 ITM
Wed Oct 16, 2024 13:05:33: [1][5]: E0041000 CID B105900D PID 001BBD21 DEVARCH
47724A13 DEVTYPE 13 ETM
Wed Oct 16, 2024 13:05:33: [1][6]: E0042000 CID B105900D PID 000BBD21 DEVARCH
47701A14 DEVTYPE 14 CSS600-CTI
Wed Oct 16, 2024 13:05:33: [0][1]: E0040000 CID B105900D PID 000BBD21 DEVARCH
00000000 DEVTYPE 11 TPIU
Wed Oct 16, 2024 13:05:33: Reset: Halt core after reset via DEMCR.VC_CORERESET.
Wed Oct 16, 2024 13:05:33: Reset: Reset device via AIRCR.SYSRESETREQ.
Wed Oct 16, 2024 13:05:33: Hardware reset with strategy 0 was performed
Wed Oct 16, 2024 13:05:33: Initial reset was performed
Wed Oct 16, 2024 13:05:33: Loaded debugee: C:\Program Files\IAR Systems\Embedded
Workbench 9.1\arm\config\flashloader\ST\FlashSTM32H57xx_Nsec.out
Wed Oct 16, 2024 13:05:33: Target reset
Wed Oct 16, 2024 13:05:38: Downloaded C:\BC\224usage\cc_arm_phase1\apps\
main_app\tools\ewarm\debug\Exe\main_app.out to flash memory.
Wed Oct 16, 2024 13:05:38: 542078 bytes downloaded into FLASH (55.55 Kbytes/sec)
Wed Oct 16, 2024 13:05:38: DMAC: DBGMCU_APB1LFZR was modified.
DBG_IWDG_STOP and DBG_WWDG_STOP bits are set.
Wed Oct 16, 2024 13:05:38: DMAC: DBGMCU_CR was modified. DBG_STOP and
DBG_STANDBY bits are set.
Wed Oct 16, 2024 13:05:38: DMAC: All active clocks and oscillators will not be disabled
during STOP/STANDBY modes.
Wed Oct 16, 2024 13:05:39: Loaded debugee: C:\BC\224usage\cc_arm_phase1\apps\
main_app\tools\ewarm\debug\Exe\main_app.out
Wed Oct 16, 2024 13:05:39: Memory map 'after startup completion point' is active
Wed Oct 16, 2024 13:05:39: Memory map 'before startup completion point' is active
Wed Oct 16, 2024 13:05:39: Reset: Halt core after reset via DEMCR.VC_CORERESET.
Wed Oct 16, 2024 13:05:39: Reset: Reset device via AIRCR.SYSRESETREQ.
Wed Oct 16, 2024 13:05:39: Hardware reset with strategy 0 was performed
Wed Oct 16, 2024 13:05:39: Download completed.
Wed Oct 16, 2024 13:05:39: Reset: Halt core after reset via DEMCR.VC_CORERESET.
Wed Oct 16, 2024 13:05:39: Reset: Reset device via AIRCR.SYSRESETREQ.
Wed Oct 16, 2024 13:05:39: Software reset was performed
Wed Oct 16, 2024 13:05:39: Target reset
Wed Oct 16, 2024 13:05:39: There were 1 error and 1 warning during the initialization of the
debugging session.
Wed Oct 16, 2024 13:05:42: Memory map 'after startup completion point' is active
Wed Oct 16, 2024 13:09:16: OnDisconnectTarget() start
Wed Oct 16, 2024 13:09:16: Resetting used DBGMCU registers.
Wed Oct 16, 2024 13:09:16: OnDisconnectTarget() end - Took 1.34ms
Wed Oct 16, 2024 13:09:16: IAR Embedded Workbench 9.30.1 (C:\Program Files\IAR
Systems\Embedded Workbench 9.1\arm\bin\armPROC.dll)
Wed Oct 16, 2024 13:09:17: Loading the J-Link Driver driver
2024-10-16 05:37 AM
Hello @nagarasr
As the designer of this article, the instructions (Case 1) given to place one or more functions in a SRAM region use the same method regardless of the development tools.
In your code, you will not be able to do otherwise than to rewrite the functions to be placed and executed in SRAM as I explain in the article. Just like GCC, any other IDE with its compiler and linker will always use specific directives to be integrated into the declarations of the functions concerned. This works in combination with the linker configuration.
Have you consulted the IAR EWARM help on the directives and how to create regions in the IAR linker .icf file?
IAR EWARM uses the #pragma location directive that can be applied to variables and functions.
I can suggest the following IAR help chapter:
Compiler reference > Efficient coding for embedded applications
In Controlling data and function placement in memory, there is the following chapter: Examples of placing functions in named sections
Best regards,
Romain
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2024-10-16 07:32 AM - edited 2024-10-17 08:04 AM
Hello,
Sorry I cannot help you about the log you shared but I created a project with IAR 9.40.1 in attachment inspired from the application note AN4296 section: 2.1.2 Executing one or more functions from CCM SRAM.
The project on H5 NUCLEO board and it is based on LED toggle example provided under github: https://github.com/STMicroelectronics/STM32CubeH5/tree/main/Projects/NUCLEO-H563ZI/Examples/GPIO/GPIO_IOToggle
Created an icf file where I split the RAM into two sections:
- RAM for data (RAM_Data_region) : 0x20000000 - 0x2008FFFF
- RAM for execution (RAM_EXEC_region) : 0x20090000 - 0x2009FFFF (64kB)
stm32h563xx_ram_flash.icf file:
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x08000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x08000000;
define symbol __ICFEDIT_region_ROM_end__ = 0x081FFFFF;
define symbol __ICFEDIT_region_RAM_DATA_start__ = 0x20000000; /* 576kB for data */
define symbol __ICFEDIT_region_RAM_DATA_end__ = 0x2008FFFF;
define symbol __ICFEDIT_region_RAM_EXEC_start__ = 0x20090000; /* 64kB for code */
define symbol __ICFEDIT_region_RAM_EXEC_end__ = 0x2009FFFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x400;
define symbol __ICFEDIT_size_heap__ = 0x200;
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define region RAM_Data_region = mem:[from __ICFEDIT_region_RAM_DATA_start__ to __ICFEDIT_region_RAM_DATA_end__];
define region RAM_EXEC_region = mem:[from __ICFEDIT_region_RAM_EXEC_start__ to __ICFEDIT_region_RAM_EXEC_end__];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
initialize by copy { readwrite, section .ram_exec };
do not initialize { section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region { readonly };
place in RAM_Data_region { readwrite,
block CSTACK, block HEAP };
place in RAM_EXEC_region {section .ram_exec};
in main.c:
#pragma location = ".ram_exec"
void Toggle_Led(void)
{
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_GPIO_TogglePin(LED1_GPIO_PORT, LED1_PIN);
/* Insert delay 100 ms */
HAL_Delay(100);
HAL_GPIO_TogglePin(LED2_GPIO_PORT, LED2_PIN);
/* Insert delay 100 ms */
HAL_Delay(100);
}
}
Note if you need to execute interrupts from the RAM, you have to follow the section 2.2 Execute an interrupt handler from CCM SRAM.
Hope it helps.
2024-10-21 04:30 AM
define symbol __ICFEDIT_region_RAM_CORE_end__ = 0x2009FFFF;
define region RAM_region = mem:[from __ICFEDIT_symbol_RAM_start__ to __ICFEDIT_symbol_RAM_end__];
place in RAM_CORE_region {section .ram_exec};
void scheduler_function1(){
// This runs in 40khz interrupt to increment the some counters
}
#pragma location = '.ramexec"
void scheduler_function2(){
// Code for scheduled functions. based on the counters updated in function1, the respective functions will be called. These functions are all not enabled to run from ramexec area. Are they also supposed to be placed in ramexec area?
}
When I try to download the image using these settings, I get the below error and the debug log contains similar to the log I posted in above.
After that When I proceed further, I get another pop with below message
and then if I clock on yes, the control stops at main. Now if I go for debug further, the control does not come to the "scheduler_function2" at all. It stops in "scheduler_function1" itself.