Ruffian Heng embedded: several methods of redirecting key functions to ram for execution in MDK development environment

Time:2021-9-14

Hello, I’m ruffian Heng, a serious technical ruffian. What ruffian Heng shared with you today isSeveral methods of redirecting key functions to ram for execution in MDK development environment

This key function redirects to ram to execute a series of articles, which has been written by ruffian HengIARMcuxpresso IDEToday, I wrote keil MDK and became a family bucket.

Write keil MDK at the end. In fact, ruffian Heng has a purpose. In the first article on IAR, we basically change the link file purely manually. The second part is about the MCU Xpress ide. In addition to manually changing the link file, we are also using its link file configuration automatic generation function. Now, when it comes to keil MDK, the IDE, like the mcuxpresso IDE, also supports automatic generation of link file configuration, but the specific function design has its own advantages. Let’s learn about it today:

  • Note: the Keil uVision software version used in this article is v5.31.0.0.

1、 Preparatory work

In order to describe the implementation of the following function redirection methods, we first make some preparations. The selected hardware platform is NXP mimxrt1170-evk. The main chip has 2MB ram, 16MB flash and two pieces of 32MB SDRAM. These storage devices map the address space in the chip system as follows:

NOR Flash: 0x30000000 - 0x30FFFFFF (16MB)
ITCM RAM:  0x00000000 - 0x0003FFFF (256KB)
DTCM RAM:  0x20000000 - 0x2003FFFF (256KB)
OCRAM:     0x20200000 - 0x2037FFFF (1.5MB)
SDRAM:     0x80000000 - 0x83FFFFFF (64MB)

Let’s randomly select a test routine: \ SDK_ 2.10.0_ EVK-MIMXRT1170\boards\evkmimxrt1170\demo_ apps\hello_ World \ CM7 \ MDK, where flexspi_ The nor project is the most typical code linking scenario (see mimxrt1176xxxxx_cm7_flexspi_nor.scf file). All readonly segments are allocated in 0x30000000 – 0x30ffffff space (in flash), and all readwrite segments are allocated in 0x20000000 – 0x2003fff space (in dtcm). The linked file is as follows:

LR_m_text 0x30002000 0x00FFE000 {
  VECTOR_ROM 0x30002000 FIXED 0x00000400 {
    * (.isr_vector,+FIRST)
  }
  ER_m_text 0x30002400 FIXED 0x00FFDC00 {
    * (InRoot$$Sections)
    .ANY (+RO)
  }
  RW_m_data 0x20000000 0x0003F800 {
    .ANY (+RW +ZI)
  }
  ARM_LIB_HEAP +0 EMPTY 0x00000400 {
  }
  ARM_LIB_STACK 0x20040000 EMPTY -0x00000400 {
  }
}

Now let’s create a new source file critical_ Code. C is used to sample key functions and add this source file to hello_ world_ demo_ Cm7.uvprojx project, critical_ There are only three test functions in the code. C file (they will be called in the main function):

void critical_func1(uint32_t n)
{
    PRINTF("Arg = %d .\r\n", n);
}
void critical_func2(uint32_t n)
{
    PRINTF("Arg * 2 = %d .\r\n", 2 * n);
}
void critical_func3(uint32_t n)
{
    PRINTF("Arg * 3 = %d .\r\n", 3 * n);
}

Compile and link the modified project, and then check its mapping file (hello_world_demo_cm7. Map) to find the critical_ The relevant contents of the code. C file are as follows, which is obviously critical_ The three functions in code. C will be linked in the flash space (all in the. Text section).

===============================================================================
Image Symbol Table
    Global Symbols
    Symbol Name                              Value     Ov Type        Size  Object(Section)
    critical_func1                           0x30005429   Thumb Code    28  critical_code.o(.text.critical_func1)
    critical_func2                           0x30005449   Thumb Code    32  critical_code.o(.text.critical_func2)
    critical_func3                           0x30005469   Thumb Code    36  critical_code.o(.text.critical_func3)
===============================================================================
Memory Map of the image
    Execution Region ER_m_text (Exec base: 0x30002400, Load base: 0x30002400, Size: 0x00003b68, Max: 0x00fbdc00, ABSOLUTE, FIXED)

    Exec Addr    Load Addr    Size         Type   Attr      Idx    E Section Name        Object
    0x30005428   0x30005428   0x0000001c   Code   RO           17    .text.critical_func1  critical_code.o
    0x30005444   0x30005444   0x00000004   PAD
    0x30005448   0x30005448   0x00000020   Code   RO           19    .text.critical_func2  critical_code.o
    0x30005468   0x30005468   0x00000024   Code   RO           21    .text.critical_func3  critical_code.o
    0x3000548c   0x3000548c   0x00000004   PAD
===============================================================================
Image component sizes
      Code (inc. data)   RO Data    RW Data    ZI Data      Debug   Object Name
        96         56          0          0          0        903   critical_code.o

2、 Redirect to ram method

What we have to do now is to put critical_ The functions in the code. C file are redirected to ram for execution, and the original link file mimxrt1176xxxxx_ cm7_ flexspi_ What is specified in nor.scf is dtcm to store the readwrite segment. Then we try to put the key functions in dtcm (if it needs to be changed to ITCM, ocram and SDRAM, the method is similar).

2.1 user defined section specifying function – for a single function

The first method is to use__ attribute__ ((section (“usersectionname”)) syntax to modify the function definition and put it into the custom program segment. This method is mainly applicable to redirecting a single key function. For example, we will use critical_ The func1() function is placed in a custom segment named. Criticalfunc:

__attribute__((section(".criticalFunc"))) void critical_func1(uint32_t n)
{
    PRINTF("Arg = %d .\r\n", n);
}
void critical_func2(uint32_t n)
{
    PRINTF("Arg * 2 = %d .\r\n", 2 * n);
}
void critical_func3(uint32_t n)
{
    PRINTF("Arg * 3 = %d .\r\n", 3 * n);
}

Then link the file mimxrt1176xxxxx in the project_ cm7_ flexspi_ Put the customized section. Criticalfunction into RW in nor.scf_ m_ In the data execution domain:

LR_ m_ text 0x30002000 0x00FFE000 {

Compile and link the modified project, and then check its mapping file (hello_world_demo_cm7. Map) to find the critical_ The relevant contents of the code. C file are as follows. At this time, critical_ Func1() has been placed in the custom segment. Criticalfunction, and this segment is linked to RAM (rw_m_data execution domain space) by the MDK underlying linker.

===============================================================================
Image Symbol Table
    Global Symbols
    Symbol Name                              Value     Ov Type        Size  Object(Section)
    critical_func1                           0x20000001   Thumb Code    28  critical_code.o(.criticalFunc)
    critical_func2                           0x30005429   Thumb Code    32  critical_code.o(.text.critical_func2)
    critical_func3                           0x30005449   Thumb Code    36  critical_code.o(.text.critical_func3)
===============================================================================
Memory Map of the image
    Execution Region RW_m_data (Exec base: 0x20000000, Load base: 0x30005f60, Size: 0x00000078, Max: 0x0003f800, ABSOLUTE)
    Exec Addr    Load Addr    Size         Type   Attr      Idx    E Section Name        Object
    0x20000000   0x30005f60   0x0000001c   Code   RO           17    .criticalFunc       critical_code.o

    Execution Region ER_m_text (Exec base: 0x30002400, Load base: 0x30002400, Size: 0x00003b60, Max: 0x00fbdc00, ABSOLUTE, FIXED)
    Exec Addr    Load Addr    Size         Type   Attr      Idx    E Section Name        Object
    0x30005428   0x30005428   0x00000020   Code   RO           19    .text.critical_func2  critical_code.o
    0x30005448   0x30005448   0x00000024   Code   RO           21    .text.critical_func3  critical_code.o
    0x3000546c   0x3000546c   0x00000004   PAD
===============================================================================
Image component sizes
      Code (inc. data)   RO Data    RW Data    ZI Data      Debug   Object Name
        96         56          0          0          0        903   critical_code.o

2.2 user defined section specified function – for multiple functions in the same file

The second method is to use #pragma syntax to modify the function definition (note that the syntax of AC5 compiler armcc and AC6 compiler armlang is different), and put multiple key functions in the same source file into the user-defined segment. For example, we will be critical_ Func1() and critical_ The func2() function is placed in a custom segment named. Criticalfunc:

  • Note: this method is generally not recommended, and the code portability is poor.

#Pragma Lang section text = ". Criticalfunction" / / applicable to AC6 compiler (start of scope)

Then it is also in the project link file mimxrt1176xxxxx_ cm7_ flexspi_ Put the customized section. Criticalfunction into RW in nor.scf_ m_ In the data execution domain:

LR_ m_ text 0x30002000 0x00FFE000 {

Compile and link the modified project, and then check its mapping file (hello_world_demo_cm7. Map) to find the critical_ The relevant contents of the code. C file are as follows. At this time, critical_ Func1 / 2() has been put into the custom segment. Criticalfunction, and this segment is linked to RAM (rw_m_data execution domain space) by the MDK underlying linker.

===============================================================================
Image Symbol Table
    Global Symbols
    Symbol Name                              Value     Ov Type        Size  Object(Section)
    critical_func1                           0x20000001   Thumb Code    28  critical_code.o(.criticalFunc)
    critical_func2                           0x20000021   Thumb Code    32  critical_code.o(.criticalFunc)
    critical_func3                           0x30005429   Thumb Code    36  critical_code.o(.text.critical_func3)
===============================================================================
Memory Map of the image
    Execution Region RW_m_data (Exec base: 0x20000000, Load base: 0x30005f50, Size: 0x0000009c, Max: 0x0003f800, ABSOLUTE)
    Exec Addr    Load Addr    Size         Type   Attr      Idx    E Section Name        Object
    0x20000000   0x30005f50   0x00000040   Code   RO           17    .criticalFunc       critical_code.o

    Execution Region ER_m_text (Exec base: 0x30002400, Load base: 0x30002400, Size: 0x00003b4c, Max: 0x00fbdc00, ABSOLUTE, FIXED)
    Exec Addr    Load Addr    Size         Type   Attr      Idx    E Section Name        Object
    0x30005428   0x30005428   0x00000024   Code   RO           19    .text.critical_func3  critical_code.o
    0x3000544c   0x3000544c   0x00000004   PAD
===============================================================================
Image component sizes
      Code (inc. data)   RO Data    RW Data    ZI Data      Debug   Object Name
       100         60          0          0          0        887   critical_code.o

2.3 for all functions in the source file

The first two redirection methods are for specific functions (if multiple key functions are scattered in multiple files, it is OK to add modifications one by one according to the method). However, if there are too many source files of a library and we want to redirect all the functions in these source files to ram, is there a more convenient method? Of course!

We will now be critical_ All functions in the code. C file are redirected, only in the project link file mimxrt1176xxxxx_ cm7_ flexspi_ Make the following changes in nor.scf:

LR_ m_ text 0x30002000 0x00FFE000 {

Compile and link the modified project, and then check its mapping file (hello_world_demo_cm7. Map) to find the critical_ The relevant contents of the code. C file are as follows. At this time, critical_ Func1 / 2 / 3 () is linked in RAM.

===============================================================================
Image Symbol Table
    Global Symbols
    Symbol Name                              Value     Ov Type        Size  Object(Section)
    critical_func1                           0x20000001   Thumb Code    28  critical_code.o(.text.critical_func1)
    critical_func2                           0x20000021   Thumb Code    32  critical_code.o(.text.critical_func2)
    critical_func3                           0x20000041   Thumb Code    36  critical_code.o(.text.critical_func3)
===============================================================================
Memory Map of the image
    Execution Region RW_m_data (Exec base: 0x20000000, Load base: 0x30005f30, Size: 0x000000c0, Max: 0x0003f800, ABSOLUTE)
    Exec Addr    Load Addr    Size         Type   Attr      Idx    E Section Name        Object
    0x20000000   0x30005f30   0x0000001c   Code   RO           17    .text.critical_func1  critical_code.o
    0x2000001c   0x30005f4c   0x00000004   PAD
    0x20000020   0x30005f50   0x00000020   Code   RO           19    .text.critical_func2  critical_code.o
    0x20000040   0x30005f70   0x00000024   Code   RO           21    .text.critical_func3  critical_code.o
===============================================================================
Image component sizes
      Code (inc. data)   RO Data    RW Data    ZI Data      Debug   Object Name
        96         56          0          0          0        903   critical_code.o

2.4 eliminated__ Ram keyword

The. Ramfunc section is built in the IAR and mcuxpresso IDE, using keywords__ Ramfunc or__ Ramfunc () to modify the function, you can directly put the function into the built-in. Ramfunc section, and you don’t need to change the linked file manually.

The early keil native compiler (CARM) did support similar features__ Ram to modify the function, but the feature is removed in AC5 / AC6. Users need to modify their own link file to complete it. For code compatibility, you can define a macro under MDK, and then put. Ramfunc into RW in the link file_ m_ Data execution domain.

#define __ramfunc __attribute__((section(".ramfunc")))

3、 Automatic generation of linked files

The methods described in Section 2 are based on the link files provided by the user. If you want to start the automatic link file generation function of MDK, you need toOption / LinkerLi JiangUse Memory Layout from Target DialogIf the option is checked, the mimxrt1176xxxxx provided by the user will be displayed_ cm7_ flexspi_ The nor.scf file is invalid, and the MDK will automatically generate a file named hello_ world_ demo_ Cm7.sct link file.

Auto generated hello_ world_ demo_ Cm7.sct link file configuration is very simple, in the projectOption / TargetRead / only memory areas and read / write memory areas are specified in. Here, only RO and RW segment space specifying settings are simply provided, and there are no separate settings for user-defined segments.

However, the feature is that memory assignment can be specified separately for a file in MDK, so that we can also redirect functions in the whole file as in Section 2.3.

4、 Start the copy process in the file

The three function redirection methods have been introduced. I wonder if you have ever wondered when and how these key function machine codes were copied from flash to ram? This starts from the project startup file startup_ MIMXRT1176_ CM7. S. In the reset function reset_ Handler finally calls the MDK built-in function. Main, there is a mystery in this function. We can find the function prototype in the arm CMSIS library. You should be able to find the mystery along the prototype.

Reset_Handler:
    cpsid   i
    .equ    VTOR, 0xE000ED08
    ldr     r0, =VTOR
    ldr     r1, =__Vectors
    str     r1, [r0]
    ldr     r2, [r1]
    msr     msp, r2
    ldr   r0,=SystemInit
    blx   r0
    cpsie   i
    ldr   r0,=__main
    bx    r0

So far, several methods of redirecting key functions to ram under MDK development environment have been introduced. Where are the applause~~~

Welcome to subscribe

The article will be published to me at the same timeBlog Park home pageCSDN home pageZhihu home pageWeChat official accountOn the platform.

Wechat search“Ruffian scale“Or scan the QR code below to see it for the first time on the mobile phone.