嵌入式技术论坛
直播中

申根换

8年用户 1681经验值
私信 关注
[经验]

使用ITCM给ART-Pi(STM32H7)加速代码简介

一、ITCM简介

ART-Pi 使用状态 STM32H750 在做控制。STM3H7 使用Cortex_M7 是架构,中自带了ITCM(紧耦合RAM)。下图可以看到ITCM 与Cortex_M7 内核直连,可实现0 等待。

TCM 与 CPU 是频频相同的,其他 AHB RAM 无法做到和 CPU 一样,所以使用 TCM 更好的性能。

TCM 的便利,但是他也有速度,例如 DTCM 不能使用 DMA1 DMA2,ITCM 作为指令 RAM。

要使用 ITCM 得先知道他的地址:

通过上图可以 ITCM 的区域通常是 0x000000000 - 0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000NULL营人情况下关注操作,建议从0x00000008地址开始使用。

二、ITCM 在不同编译器下的使用

如何将函数指定到ITCM ,其实函数链接地址设置在 ITCM 区域就可以了。

这里以ART-Pi-LED的示例代码来这个过程。

在 RTT Studio 中如何使用 ITCM

RTT Studio中使用的编译器为:GCC,所以直接按照GCC链接脚本的方式去定义就好了。

在 RTT Studio 中如何指定某个函数到指定地址,需要三个步骤:

第一步:在链接文件中增加一个 ITCM 的描述信息

MEMORY

{

ROM (rx) : ORIGIN =0x90000000,LENGTH =8192k

RAM (rw) : ORIGIN =0x24000000,LENGTH =512k

RxDecripSection (rw) : ORIGIN =0x30040000,LENGTH =32k

TxDecripSection (rw) : ORIGIN =0x30040060,LENGTH =32k

RxArraySection (rw) : ORIGIN =0x30040200,LENGTH =32k

ITCM (rx) : ORIGIN =0x00000008,LENGTH =64k

}

每一行增加了 ITCM 的最后描述信息

第二步:在链接文件中 SECTIONS 中添加 ITCM 的信息

SECTIONS

{

.ITCM :

{

. = ALIGN(4);

*(.ITCM)

(.ITCM. )

. = ALIGN(4);

} > ITCM = 0

.text :

{

. = ALIGN(4);

_stext = .;

KEEP(* (.isr_vector)) /* Startup code */

.

.

.

}

}

这里需要注意的是新增加的 .ITCM 必须是 .text 的前面

第三步,指定函数到 ITCM

attribute ((section(".ITCM")))int main(void)

{

rt_uint32_t count = 0;

rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT);

rt_kprintf("main adderss is 0x%08x
",main);

rt_thread_mdelay(500);

led_light();

}

在修改之后重新构建工程,查看地图文件

*(.ITCM)

.ITCM 0x00000008 0x3c ./applications/main.o

0x00000008 main

可以看到主要功能的地址已经被指定到 ITCM 的区域。

在 RTT Studio 中如何设置文件夹的所有函数到指定位置,需要的步骤:

第一步:在链接文件中增加一个 ITCM 的描述信息

MEMORY

{

ROM (rx) : ORIGIN =0x90000000,LENGTH =8192k

RAM (rw) : ORIGIN =0x24000000,LENGTH =512k

RxDecripSection (rw) : ORIGIN =0x30040000,LENGTH =32k

TxDecripSection (rw) : ORIGIN =0x30040060,LENGTH =32k

RxArraySection (rw) : ORIGIN =0x30040200,LENGTH =32k

ITCM (rx) : ORIGIN =0x00000008,LENGTH =64k

}

每一行增加了 ITCM 的最后描述信息

第二步:在链接文件中 SECTIONS 中添加 ITCM 的信息

SECTIONS

{

.ITCM :

{

. = ALIGN(4);

./applications/main.o (.text*)

*(.ITCM)

(.ITCM. )

. = ALIGN(4);

} > ITCM = 0

.text :

{

. = ALIGN(4);

_stext = .;

KEEP(* (.isr_vector)) /* Startup code */

.

.

.

}

}

这里将 ./application main.o .text 段都到了/ITCM

查看地图文件

.text.led_light

0x00000024 0x38 ./applications/main.o

0x00000024 led_light

.text.main 0x0000005c 0x3c ./applications/main.o

0x0000005c main

.text.vtor_config

0x00000098 0x1c ./applications/main.o

可以看到 main.c 中的文件都被定义到了 ITCM 段

在 MDK 中如何使用 ITCM

在MDK中也需要修改对用的链接文件

在 MDK 中如何指定某个函数到指定地址,需要两个步骤:

第一步,修改链接文件

LR_IROM1 0x90000000 0x00800000 { ; load region size_region

ER_IROM1 0x90000000 0x00800000 { ; load address = execution address

*.o (RESET, +First)

*(InRoot$$Sections)

.ANY (+RO)

.ANY (+XO)

}

RW_IRAM0 0x00000008 0x0000FFF8 { ; ITCM 64K

*(.ITCM)

}

RW_IRAM1 0x24000000 0x00080000 { ; AXI SRAM 512K

.ANY (+RW +ZI)

}

}

增加 ITCM 的描述

第二步,指定函数到 ITCM

attribute ((section(".ITCM"))) void led_light(void)

{

rt_kprintf("main adderss is 0x%08x
",led_light);

while(1)

{

rt_thread_mdelay(500);

rt_pin_write(LED_PIN, PIN_HIGH);

rt_thread_mdelay(500);

rt_pin_write(LED_PIN, PIN_LOW);

}

}

查看地图文件

led_light 0x00000009 Thumb Code 46 main.o

可以led_light看到你已经被放在 ITCM 区域

在 MDK 如何如何使用 C 文件的函数中指定地址,需要两个步骤:

第一步,修改链接文件

LR_IROM1 0x90000000 0x00800000 { ; load region size_region

ER_IROM1 0x90000000 0x00800000 { ; load address = execution address

*.o (RESET, +First)

*(InRoot$$Sections)

.ANY (+RO)

.ANY (+XO)

}

RW_IRAM0 0x00000008 0x0000FFF8 { ; ITCM 64K

*(.ITCM)

}

RW_IRAM1 0x24000000 0x00080000 { ; AXI SRAM 512K

.ANY (+RW +ZI)

}

}

增加 ITCM 的描述

第二步,指定某个函数到 ITCM

可以在这些函数的前面和结束之后的地方加上关键字,如下所示:

#pragma arm section code = ".ITCM"

void led_light(void)

{

rt_kprintf("main adderss is 0x%08x
",led_light);

while(1)

{

rt_thread_mdelay(500);

rt_pin_write(LED_PIN, PIN_HIGH);

rt_thread_mdelay(500);

rt_pin_write(LED_PIN, PIN_LOW);

}

}

int main(void)

{

rt_uint32_t count = 0;

rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT);

rt_kprintf("main adderss is 0x%08x
",main);

rt_thread_mdelay(500);

led_light();

return RT_EOK;

}

#pragma arm section

查看地图文件

led_light 0x00000009 Thumb Code

Super$main 0x00000037 Thumb Code

三、注意事项

大家都知道 RAM 的加速使用量是怎样的,这种方法如何在量产中呢?实际上使用更多的方法,MDK 很容易失去某种产品的功能将ROM中指定的任务拷贝继续到RAM中,

但是在RTT Studio中的执行函数中写到指定RAM中的释放函数,这样我会在RTT Studio中删除操作。

原作者:whj467467222

更多回帖

发帖
×
20
完善资料,
赚取积分