0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于 IAR Embedded Workbench 的自研 MCU 芯片软件函数与变量内存布局优化精控方法

安芯 来源:jf_29981791 作者:jf_29981791 2025-04-30 16:38 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

嵌入式软件开发领域,MCU芯片软件的架构设计与内存布局的精细规划对系统性能和稳定性起着关键作用。本文档聚焦于IAR Embedded Workbench环境下,为自研MCU芯片软件提供了一套详尽的函数和变量指定section放置方法与操作流程,兼具过程记录与详细说明,旨在打造一份实用的参考指南,助力开发者精准掌控程序的内存分布与执行逻辑。文档涵盖从默认section表的介绍,到多种放置手段的阐释,以及实际配置示例的展示,为后续的开发工作奠定坚实基础。

IAR Embedded Workbench作为一款广受认可的嵌入式开发工具,具备丰富的功能与灵活的配置选项。在该环境下,软件开发者可巧妙运用多种方法,将函数和变量精准放置于指定的section中。这一操作对于优化程序的内存使用效率、提升系统响应速度以及增强代码的可维护性具有重要意义。例如,通过将特定的代码或数据放置在合适的内存区域,可以充分利用MCU芯片的硬件特性,实现更高效的缓存利用、减少内存访问延迟等效果。

文档深入浅出地讲解了多种放置方式,包括使用@操作符、#pragma location命令、GCC风格的attribute属性以及#pragma default_variable_attributes和#pragma default_function_attributes命令等,开发者可根据实际需求灵活选择。同时,还提供了诸如as32x601_rom.icf、Port_MemMap.h和Port.c等实际配置示例,涵盖了从内存区域定义、section分配到函数与变量属性设置的完整流程,为开发者提供了直观且易于实践的参考。

默认section表

IAR Embedded Workbench中有很多默认的section用于放置对应的变量和函数:

除了用于您的应用程序的ELF部分之外,这些工具还出于多种目的使用许多其他ELF段:

  • 以.debug开头的段通常包含DWARF格式的调试信息。
  • 以.iar.debug开头的段包含IAR格式的补充调试信息
  • 以.comment开头的段包含用于构建文件的工具和命令行
  • 以.rel或.rela开头的段包含ELF重定位信息
  • 以.symtab开头的段包含文件的符号表
  • 以.strtab开头的段包含符号表中符号的名称
  • 以.shstrtab开头的段包含各段的名称。

将变量放到指定的section

使用@操作符

可以使用 @ 将变量放到指定的section:

staticuint32_t TaskCounter @".mcal_const_cfg" = 1;

使用 #pragma location 命令

可以使用 #pragma location命令将变量放到指定的section:

#pragma location = ".mcal_const_cfg"staticuint32_t TaskCounter = 1;

使用 GCC 风格的属性 attribute ((section ))

可以使用 GCC 风格的属性 attribute ((section ))将变量放到指定的section:

staticuint32_t TaskCounter attribute ((section (".mcal_const_cfg"))) = 1;

使用 #pragma default_variable_attributes 命令

上面的方法可以将单个变量放到指定的section,如果需要将多个变量放到指定的section,上面的方法会显得有点繁琐。可以使用 #pragma default_variable_attributes 命令将多个变量放到指定的section:

#pragma default_variable_attributes = @ ".mcal_const_cfg"staticuint32_t TaskCounter = 1; staticuint32_t TaskLedRedCounter = 2; #pragma default_variable_attributes =

将函数放到指定的section

使用@操作符

可以使用 @ 将函数放到指定的section:

voidStartTaskLedRed(void *argument) @ ".mcal_text";

使用 #pragma location 命令

可以使用 #pragma location命令将函数放到指定的section:

#pragma location = ".mcal_text"voidStartTaskLedRed(void *argument);

使用 GCC 风格的属性 attribute ((section ))

可以使用 GCC 风格的属性 attribute ((section ))将函数放到指定的section:

voidStartTaskLedRed(void *argument) attribute ((section (".mcal_text")));

使用 #pragma default_variable_attributes 命令

上面的方法可以将单个函数放到指定的section,如果需要将多个函数放到指定的section,上面的方法会显得有点繁琐。可以使用 #pragma default_function_attributes命令将多个函数放到指定的section:

#pragma default_function_attributes = @ ".mcal_text"voidStartTaskLedRed(void *argument); voidStartTaskLedGreen(void *argument); voidStartTaskLedBlue(void *argument); #pragma default_function_attributes =

使用示例

as32x601_rom.icf

/****************************************************************************** * FILE VERSION / define exported symbol _link_file_version_2 = 1; / * SPECIALS // * * MEMORY REGIONS / define symbol ICFEDIT_region_FLASH_start = 0x10000000; define symbol ICFEDIT_region_FLASH_end = 0x11FFFFFF; define symbol ICFEDIT_region_SRAM0_start = 0x20000000; define symbol ICFEDIT_region_SRAM0_end = 0x2001FFFF; define symbol ICFEDIT_region_SRAM1_start = 0x20020000; define symbol ICFEDIT_region_SRAM1_end = 0x2003FFFF; define symbol ICFEDIT_region_SRAM2_start = 0x20040000; define symbol ICFEDIT_region_SRAM2_end = 0x2005FFFF; define symbol ICFEDIT_region_SRAM3_start = 0x20060000; define symbol ICFEDIT_region_SRAM3_end = 0x2007FFFF; / * * SIZES / define symbol ICFEDIT_size_cstack = 0x2000; define symbol ICFEDIT_size_proc_stack = 0x0; define symbol ICFEDIT_size_heap = 0x2000; / * * BUILD FOR ROM *****************************************************************************/ keep symbol __iar_cstart_init_gp; define memory mem with size = 4G; define region ROM_region = mem:[from ICFEDIT_region_FLASH_start to ICFEDIT_region_FLASH_end ]; define region RAMCODE_region = mem:[from ICFEDIT_region_SRAM0_start to ICFEDIT_region_SRAM0_end ]; define region RAM_region = mem:[from ICFEDIT_region_SRAM1_start to ICFEDIT_region_SRAM1_end ] | mem:[from ICFEDIT_region_SRAM2_start to ICFEDIT_region_SRAM2_end ]; initialize by copy { readwrite }; do not initialize { section .noinit }; define block CSTACK with alignment = 16, size = CSTACK_SIZE { }; define block HEAP with alignment = 16, size = HEAP_SIZE { }; define block RW_DATA { rw section .data}; define block RW_DATA_INIT { ro section .data_init}; define block RW_BSS {rw section .bss}; define block RW_DATA_ALL with static base GPREL { block RW_DATA, block RW_BSS }; "STARTUP" : place at start of ROM_region { readonly section .init }; place in ROM_region { readonly, block RW_DATA_INIT }; place in ROM_region { readonly section .text, section .mcal_text, section .access_code_rom}; place in ROM_region { readonly section .rodata, section .mcal_const_cfg, section .mcal_const, section .mcal_const_no_cacheable}; place in RAMCODE_region { readwrite section .text, section .ramcode, block RW_DATA_ALL }; place in RAM_region { readwrite, block CSTACK, block HEAP }; place in RAM_region { section .mcal_data, section .dma_dest_buffer, section .mcal_shared_data }; place in RAM_region { section .mcal_bss, section .mcal_bss_no_cacheable, section .dma_dest_buffer_bss, section .mcal_shared_bss };

第13、14行:定义FLASH,起始地址和结束地址。 第41行:定义了ROM_region区域,起始地址和结束地址。 第63行:定义一个名为 ROM_region 的内存区域,并将三个只读代码段 .text、.mcal_text 和 .access_code_rom 放置在这个区域内。。

Port_MemMap.h

#define MEMMAP_MISSMATCH_CHECKER#if defined (_IAR_C_AS32x601_)#ifdef PORT_START_SEC_CODE#undef PORT_START_SEC_CODE#undef MEMMAP_MISSMATCH_CHECKER#pragma default_function_attributes = @ ".mcal_text"#endif#ifdef PORT_STOP_SEC_CODE#undef PORT_STOP_SEC_CODE#undef MEMMAP_MISSMATCH_CHECKER#pragma default_function_attributes =#endif#endif#ifdef MEMMAP_MISSMATCH_CHECKER#error"MemMap.h, No valid section define found."#endif

第1行:定义了一个宏 MEMMAP_MISSMATCH_CHECKER,用于检查包含的正确的符号。 第3行:定义了一个ifdef,当定义了 IAR_C_AS32x601 时,会执行下面的代码。 第5行:定义了一个ifdef,当定义了 PORT_START_SEC_CODE 时,会执行下面的代码。 第11行:定义了一个ifdef,当定义了 PORT_STOP_SEC_CODE 时,会执行下面的代码。 第19行:定义了一个ifdef,当定义了 MEMMAP_MISSMATCH_CHECKER 时,说明输入定义错误,将会抛出一个错误。

Port.c

#define PORT_START_SEC_CODE#include"Port_MemMap.h" FUNC(void, PORT_CODE) Port_Init(P2CONST(Port_ConfigType, AUTOMATIC, PORT_APPL_CONST) ConfigPtr) { #if (PORT_ENABLE_DEV_ERROR_DETECT == STD_ON)/* When PostBuild is used and #(Variants) > 1, the input parameter 'ConfigPtr' is mandatory to be different than NULL_PTR. * In case of error, return immediately and report DET errors. */#if (PORT_PRECOMPILE_SUPPORT == STD_ON)if (NULL_PTR != ConfigPtr) { #elseif (NULL_PTR == ConfigPtr) { #endif/* (PORT_PRECOMPILE_SUPPORT == STD_ON) *//* If development error detection for the Port module is enabled: * The function shall raise the error PORT_E_INIT_FAILED if the parameter ConfigPtr is Null Pointer.*/ (void)Det_ReportError((uint16)PORT_MODULE_ID, PORT_INSTANCE_ID, PORT_INIT_ID, PORT_E_INIT_FAILED); } else { #endif/* (PORT_ENABLE_DEV_ERROR_DETECT == STD_ON) */#if (PORT_PRECOMPILE_SUPPORT == STD_ON) l_PortConfig_ptr = &Port_PreCompileConfig_st; /* Avoid compiler warning */ (void)ConfigPtr; #else/* (PORT_PRECOMPILE_SUPPORT == STD_OFF) */ l_PortConfig_ptr = ConfigPtr; #endif/* (PORT_PRECOMPILE_SUPPORT == STD_ON) *//* Initializes the Port driver with the given configuration */ Port_LLDriver_Init(l_PortConfig_ptr); #if (PORT_ENABLE_DEV_ERROR_DETECT == STD_ON) } #endif/* (PORT_ENABLE_DEV_ERROR_DETECT == STD_ON) */ } #define PORT_STOP_SEC_CODE#include"Port_MemMap.h"

第1行:定义了一个宏 PORT_START_SEC_CODE,将会执行#pragma default_function_attributes = @ ".mcal_text",会将函数放置在.mcal_text区域。 第32行:定义了一个宏 PORT_STOP_SEC_CODE,会结束函数的默认属性设置。

效果示例

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • mcu
    mcu
    +关注

    关注

    147

    文章

    18604

    浏览量

    386594
  • IAR
    IAR
    +关注

    关注

    5

    文章

    400

    浏览量

    38333
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    通过优化代码来提高MCU运行效率

    内存访问优化 充分利用缓存:如果MCU有Cache,尽量保证代码和数据的局部性,即让相关的数据在内存中连续存放。 避免内存碎片:在动态
    发表于 11-12 08:21

    CW32 MCU用什么IDE开发?

    推荐使用IAR Embedded Workbench for ARM、Keil μVision for ARM等IDE开发CW32 MCU应用,其中新版本
    发表于 11-12 07:52

    如何在IAR Embedded Workbench for Arm中开发和调试Infineon MOTIX MCU

    Infineon MOTIX MCU集成了感应、控制和驱动电机的所有基本功能,支持继电器、半桥和全桥直流和 BLDC 电机应用,为先进的电机控制应用提供全面的解决方案[1]。
    的头像 发表于 11-08 14:24 7516次阅读
    如何在<b class='flag-5'>IAR</b> <b class='flag-5'>Embedded</b> <b class='flag-5'>Workbench</b> for Arm中开发和调试Infineon MOTIX <b class='flag-5'>MCU</b>

    如何在 IAR Embedded Workbench for ARM 开发环境中启用可配置数据闪存并设置大小?

    如何在 IAR Embedded Workbench for ARM 开发环境中启用可配置数据闪存并设置大小?
    发表于 08-26 07:49

    请问如何在 IAR Embedded Workbench for ARM 开发环境中启用可配置数据闪存并设置大小?

    如何在 IAR Embedded Workbench for ARM 开发环境中启用可配置数据闪存并设置大小?
    发表于 08-20 06:23

    Arm CEO:公司正在芯片

    据外媒路透社报道,Arm CEO Rene Haas透露,Arm正在投资开发自有芯片,并计划将部分利润投资于制造自己的芯片和其他组件。与之对应的是Arm预测的下一财季经营业绩也会因为
    的头像 发表于 07-31 11:49 456次阅读

    「芯生态」杰发科技AC7870携手IAR开发工具链,助推汽车电子全栈全域智能化落地

    IAR Embedded Workbench for Arm已全面支持杰发科技AutoChips车规级MCU AC7870,为其提供涵盖开发、调试、
    的头像 发表于 07-22 12:06 480次阅读
    「芯生态」杰发科技AC7870携手<b class='flag-5'>IAR</b>开发工具链,助推汽车电子全栈全域智能化落地

    高端芯片,服务器芯片传来好消息!

    电子发烧友网报道(文/黄晶晶)当前,处理器已经跨过了能用的阶段,逐渐走向好用,但无论是消费级还是服务器级都面临着如何在性能上接近国外高端产品,以及生态上如何更加完善的问题。国内厂商对于服务器芯片
    的头像 发表于 05-18 09:25 7426次阅读
    高端<b class='flag-5'>芯片</b><b class='flag-5'>自</b><b class='flag-5'>研</b>,服务器<b class='flag-5'>芯片</b>传来好消息!

    MCU芯片闪存驱动的实现:OpenOCD详细过程记录与操作指南

    功能强大的开源调试工具,广泛应用于嵌入式系统开发中,为系统调试与程序烧录提供了重要支持。 随着MCU芯片项目的不断推进,如何实现其与OpenOCD的无缝对接成为关键问题之一。而闪存
    的头像 发表于 05-08 10:51 1913次阅读
    <b class='flag-5'>自</b><b class='flag-5'>研</b><b class='flag-5'>MCU</b><b class='flag-5'>芯片</b>闪存驱动的实现:OpenOCD详细过程记录与操作指南

    IAR全面支持芯驰科技车规MCU芯片E3650

    2025年4月22日,全场景智能车芯引领者芯驰科技与全球嵌入式软件开发解决方案领导者IAR正式宣布,IAR Embedded Workbench
    的头像 发表于 04-23 15:45 1204次阅读

    如何将项目从IAR迁移到Embedded Studio

    本文描述如何将IAR EWARM项目迁移到SEGGER Embedded Studio(简称SES)中。
    的头像 发表于 02-25 17:11 1050次阅读
    如何将项目从<b class='flag-5'>IAR</b>迁移到<b class='flag-5'>Embedded</b> Studio

    传DeepSeek芯片,厂商们要把AI成本打下来

    电子发烧友网报道(文/黄晶晶)日前业界消息称,DeepSeek正广泛招募芯片设计人才,加速芯片布局,其
    的头像 发表于 02-16 00:09 3886次阅读
    传DeepSeek<b class='flag-5'>自</b><b class='flag-5'>研</b><b class='flag-5'>芯片</b>,厂商们要把AI成本打下来

    FRED应用:LED发光颜色优化

    ” 色度值优化函数定义 X和y色度坐标优化函数需要彩色图像计算他们的值。输入变量g_ana 是分析面“屏幕”的节点数。这里,只有中心像素点
    发表于 01-17 09:39

    IAR与紫光同芯合作,全面支持THA6系列汽车芯片

    近日,全球领先的嵌入式系统开发软件解决方案提供商IAR与业内知名的芯片及解决方案提供商紫光同芯携手宣布,最新版本的IAR Embedded
    的头像 发表于 12-27 11:46 1592次阅读

    苹果计划2025年起采用蓝牙Wi-Fi芯片

    近日,据最新报道,苹果公司为了减少对博通(Broadcom)的依赖,并进一步提升其设备的性能和能效,已经制定了一项重要的芯片计划。据悉,从2025年开始,苹果将正式启用
    的头像 发表于 12-18 14:22 1434次阅读