KEIL environment at how code running in RAM (rpm)

KEIL environment at how code running in RAM

Published: 2016-08-26

Source: ST community

Tags: KEIL Nucleo the STM32

share to:

 


 

Preface
frequently encountered someone using KEIL need to part or all of the program code into RAM problems when running, now its summarized in this article. By the STM32 F411 Nucleo an example of a method to introduce a program running in the RAM so that several.

We start ToggleLED functions in Flash execution start blinking. Here is ToggleLED function and its call situation. In while main function of (1) in calling ToggleLED.

void ToggleLED(void)
{ HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); /* Insert a 100ms delay */
HAL_Delay(100);
}

int main(void)
{ …… /*##-3- Toggle PA05 IO in an infinite loop ######*/
while (1) { ToggleLED(); }
}

Linker configuration shown below compilation environment:
the Flash starting address: 0x08000000
the RAM start address: 0x20000000

1

 

The compiler can see from the map file, ToggleLED and which calls to address HAL_GPIO_TogglePin and HAL_Delay function in FLASH.

2
LED will flip into the SRAM program execution
method: by #pragma arm section code = "RAMCODE" and #pragma arm section. Reference Example1 code.
In this manner, a plurality of functions can be simultaneously placed in the designated section. Specific methods are as follows:
1. Modify .sct files, the custom section RAMCODE called, the execution area on RW_IRAM1, address range 0x20000000 ~ 0x20020000.

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 0x00020000 { ; RW data
*.o(RAMCODE)
.ANY (+RW +ZI)
}
}

2. Using the previous modified files in the project .sct

3

3. #pragma arm section code = beginning "RAMCODE", #pragma arm section to the end. You will need to put all the functions RAMCODE section is included. Compile time, the compiler will automatically These functions into areas where RAMCODE 0x20000000 began.

#pragma arm section code = "RAMCODE"
void ToggleLED(void)
{ HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); /* Insert a 100ms delay */
HAL_Delay(100);
}

void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{ /* Check the parameters */
assert_param(IS_GPIO_PIN(GPIO_Pin));
GPIOx->ODR ^= GPIO_Pin;
}

uint32_t HAL_GetTick(void)
{ return tick;
}

void HAL_Delay(__IO uint32_t Delay)
{ uint32_t tickstart = 0;
tickstart = HAL_GetTick();
while((HAL_GetTick() - tickstart) < Delay)
{
}
}
#pragma arm section

4. From the map file, you can see these four functions have been placed in the SRAM.

4

Method two: by __attribute __ ((section ( "name ")))
by __attribute __ ((at (address) )) variable manner into the specified position in the KEIL.
By __attribute __ ((section ( "name "))) or a function variable manner into the specified location.

Let us look at how this way the program into SRAM executed.
1. Similarly, we need to modify .sct files, custom called section RAMCODE, and in the linker page of the project options, select defined .sct file. (See Step 2 of the method)

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 0x00020000 { ; RW data
*.o(RAMCODE)
.ANY (+RW +ZI)
}
}

2. Before the function of the RAM needs to be set, in the function declaration in RAMCODE section with __attribute __ ((section ( "RAMCODE"))). Note that this function calls to all functions have put in RAMCODE section.

__attribute__((section("RAMCODE")))
void ToggleLED(void)
{ HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); /* Insert a 100ms delay */
HAL_Delay(100);
}

__attribute__((section("RAMCODE")))
void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{ /* Check the parameters */
assert_param(IS_GPIO_PIN(GPIO_Pin));
GPIOx->ODR ^= GPIO_Pin;
}

__attribute__((section("RAMCODE")))
__weak uint32_t HAL_GetTick(void)
{ return uwTick; }

__attribute__((section("RAMCODE")))
__weak void HAL_Delay(__IO uint32_t Delay)
{ uint32_t tickstart = 0;
tickstart = HAL_GetTick();
while((HAL_GetTick() - tickstart) < Delay)
{ }
}

3. As can be seen from the map file compiled, ToggleLED and all the functions it calls to have been to the RAM.

00

Method II can override a method, which means that if you have both a method and a second method to do the same description of the implementation of regional function. The final work is the second method. It is illustrated by the above-mentioned code.
Modify .sct file. The SRAM is divided into two zones RW_IRAM1 execution and RW_IRAM2. Section RAMCODE1, RAMCODE2 are located at the beginning, two 64KB region and the start of 0x20010000 0x20000000.

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
*.o(RAMCODE1)
.ANY (+RW +ZI)
}

0x20010000 0x00010000 {RW_IRAM2
* .o (RAMCODE2)}
}

2. In the code, HAL_GetTick was put #pragma's scope is declared on RAMCODE1 section, at the same time with __attribute __ ((section ( "RAMCODE2"))) to be placed in the section RAMCODE2.

#pragma arm section code = "RAMCODE1"
void ToggleLED(void)
{ HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
/* Insert a 100ms delay */
HAL_Delay(100); }

void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{ /* Check the parameters */
assert_param(IS_GPIO_PIN(GPIO_Pin));
GPIOx->ODR ^= GPIO_Pin;
}

__attribute__( ( section ( "RAMCODE2" ) ) )
uint32_t HAL_GetTick(void)
{ return tick; }

void HAL_Delay(__IO uint32_t Delay)
{ uint32_t tickstart = 0;
tickstart = HAL_GetTick();
while((HAL_GetTick() - tickstart) < Delay) { }
}
#pragma arm section

3. After compilation, we take a look at the map file HAL_GetTick which was placed on the section.

5

You can see from the map, the final HAL_GetTick been placed in RAMCODE2 section.

** how to perform the entire program into SRAM
previously described methods one or more programs into the specified address executed. If you need to put more procedures specified address, we can also address these needs into the designated assembly into one or several C files, then these files generated C files placed in the target file .sct to the specified address.
Here, we will try to execute the entire program into SRAM. After the reset procedure starts from FLASH, SRAM will then perform all procedures. The following is the specific steps.
1. The interrupt vector table and interrupt handlers into the SRAM in
a new startup_stm32f411xe_ram.s file, into the starting position 0x20000000 (modified .sct file). Note that this is a new, rather than directly to the original file into the SRAM, why? You can think about. Defined in startup_stm32f411xe_ram.s in new SECTION, called the RESET_ram (there are other changes, please refer to the control codes). This position will RESET_ram into SRAM section beginning at the upper .sct later (see Step 3).

Vector Table Mapped to Address 0 at Reset
AREA RESET_ram, DATA, READONLY
EXPORT __Vectors_ram
EXPORT __Vectors_End_ram
EXPORT __Vectors_Size_ram
__Vectors_ram DCD 0 ; Top of Stack
DCD 0 ; Reset Handler
DCD NMI_Handler ; NMI Handler
……

2. in the interrupt vector table is set to the offset address SystemInit 0x20000000. Enable VECT_TAB_SRAM.

#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#else SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
#endif

3. Modify .sct files, all object files needed are put SRAM runtime execution region. Here interrupt vector table have the same two, one at the beginning of the location 0x08000000, 0x20000000 a position at the start.

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 0x00020000 { ; RW data
*.o (RESET_ram, +First)
startup_stm32f411xe_ram.o(+RO)
main.o(+RO +RW)
stm32f4xx_it.o(+RO +RW)
stm32f4xx_hal.o(+RO +RW)
stm32f4xx_hal_gpio.o(+RO +RW)
stm32f4xx_hal_rcc.o(+RO +RW)
stm32f4xx_hal_cortex.o(+RO +RW)
.ANY (+RW +ZI)
}
}

4. After compilation is complete, you can see from the map file or debug trace results. After the system reset, the main function from the start, all programs are run in RAM.
In addition, if your program is useful to the bottom of the ARM libraries can be added * armlib * (+ RO) in .sct file to be used in all libraries into the SRAM.

Published 30 original articles · won praise 21 · Views 140,000 +

Guess you like

Origin blog.csdn.net/oushaojun2/article/details/98184172
RAM