In certain scenarios, it may be desirable to run only specific functions from RAM on an APM32 microcontroller to enhance execution speed for critical code sections without the need to load the entire application into RAM. This article provides a step-by-step guide on how to achieve this using the Keil development environment.
Preliminary PreparationsBefore starting, ensure that you have completed the following preparations:
- Installed the Keil MDK development environment.
- Have the APM32 microcontroller hardware development board.
- Installed the Keil support package and startup code for APM32.
Open Keil uVision and create a new project, selecting the APM32 microcontroller as the target device. After creating the project, Keil will automatically generate a basic startup code template.
Step 2: Define a RAM Execution Section in the Linker ScriptTo run specific functions from RAM, you need to create a separate section in the linker script for RAM execution. Here's how to modify the scatter file (e.g., *.sct
):
LR_IROM1 0x08000000 0x00080000 { ; load region size_region
ER_IROM1 0x08000000 0x00080000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x20000000 0x00010000 { ; RW data
.ANY (+RW +ZI)
}
RW_RAM_CODE 0x20010000 0x00008000 { ; RAM code section
.ANY (+RAM_CODE)
}
}
In this configuration:
LR_IROM1
defines the entire memory layout.ER_IROM1
is the main code section in Flash.RW_IRAM1
is the main RAM section for read/write data.RW_RAM_CODE
is a new section specifically for code that should run from RAM.
To specify which functions should run from RAM, use the __attribute__((section(".ram_code")))
directive in your code. For example:
__attribute__((section(".ram_code")))
void critical_function(void) {
// Critical code to run from RAM
}
Step 4: Initialize RAM Code Section in C Runtime InitializationTo ensure that the RAM section is correctly initialized, modify the startup code or the C runtime initialization to copy the RAM code section from Flash to RAM during startup. Here is an example modification for the startup code (typically in system_APM32.c
or similar):
extern uint32_t __ram_code_load_start__;
extern uint32_t __ram_code_start__;
extern uint32_t __ram_code_end__;
void SystemInit(void) {
uint32_t* src = &__ram_code_load_start__;
uint32_t* dst = &__ram_code_start__;
uint32_t* end = &__ram_code_end__;
while (dst < end) {
*dst++ = *src++;
}
// Other system initialization code
}
Ensure the linker script provides these symbols:
assembly
Copy code
__ram_code_load_start__ = LOADADDR(RW_RAM_CODE);
__ram_code_start__ = ADDR(RW_RAM_CODE);
__ram_code_end__ = ADDR(RW_RAM_CODE) + SIZEOF(RW_RAM_CODE);
assembly
Copy code
__ram_code_load_start__ = LOADADDR(RW_RAM_CODE);
__ram_code_start__ = ADDR(RW_RAM_CODE);
__ram_code_end__ = ADDR(RW_RAM_CODE) + SIZEOF(RW_RAM_CODE);
Step 5: Compile and Download CodeAfter completing the above configurations, save all changes and compile the project. If there are no errors, download the code to the target board. The startup code will copy the specified functions from Flash to RAM, and they will execute from RAM as intended.
ConclusionBy following these steps, you can configure the APM32 microcontroller in the Keil environment to run specific functions from RAM. This selective approach allows for optimizing the performance of critical code sections without the overhead of loading the entire application into RAM, providing a balanced solution for performance and resource management in embedded development.
Comments
Please log in or sign up to comment.