【问题标题】:STM32F7: How to place selected modules' code to ITCM along with their readonly (const) data (IAR)?STM32F7:如何将选定模块的代码连同它们的只读(常量)数据(IAR)一起放置到 ITCM?
【发布时间】:2022-01-22 23:33:03
【问题描述】:

我想将部分代码放入 ITCM(使用 IAR)。我可以找到该手册(IAR ARM 开发指南),其中仅包含将所有代码放入 RAM 时的一般情况的说明。但是我的应用不适合 ITCM,所以我需要一种方法来指定哪些模块进入 RAM。

我找到了 AN4667 的示例,该示例对不同的配置进行了测试(名为“stm32f7_performances”的项目),其中之一是 CodeInITCM+DataInDTCM。这种情况下有一个 .icf 可以很好地编译。

但是,由于某种原因,如果某些模块包含放置在代码中的常量,它就会开始表现不佳。我隔离了以下最小 main.c 文件(见下文),该文件会在链接时产生警告,导致最终十六进制图像无法正常工作。我的项目仅包含以下示例中的 startup_stm32f756xx.s、main.c 和 5-RamITCM_rwRAM-DTCM.icf 链接器文件。尝试构建它时,我收到以下警告:

建筑:

Building configuration: Project - 5-RamITCM_rwRAM-DTCM 
main.c  
Linking 
Warning[Lp005]: placement includes a mix of sections with content (example "ro code section .text in main.o symbols: [SystemInit, main]") and sections without content (example "rw data section .rodata in main.o") 
Warning[Lp006]: placement includes a mix of writable sections (example "rw data section .rodata in main.o") and non-writable sections (example "ro code section .text in main.o symbols: [SystemInit, main]") 

Total number of errors: 0 
Total number of warnings: 2 

这是为了说明问题的最小情况,所以它缺少任何硬件初始化等。当我构建我的真实程序并尝试加载/执行它时,它无法正确加载,所以这些警告显然很关键。

如果我使用“place in Program_RAM_ITCM_region { ro };”将所有代码放入 Program_RAM_ITCM_region .icf 文件中的命令,它构建并运行良好,但我的真实应用程序的代码大小大于 ITCM 大小,所以我需要能够选择转到 ITCM 的模块。

谁能告诉我这种行为的原因以及如何解决这个问题?

弗拉基米尔


main.c 文件:

    void SystemInit(void) {}
    
    volatile static int iii = 0;    
    
    void Test(char *s)
    {
      for (int i = 0; i < 10; i++) iii = s[i] ? 1:0;
    }
    
    int main(void)
    {
      Test("=======================================================\r\n");
    }

5-RamITCM_rwRAM-DTCM.icf 文件:

/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x00200000;

/*= Code region(s) ===================================== */
/* -- Program region in internal Flash ----------------- */
define symbol __ICFEDIT_Program_In_FLASHTCM_start__    = 0x00200000;
define symbol __ICFEDIT_Program_In_FLASHTCM_end__      = 0x002FFFFF;
/* -- Program region in RAM ITCM ----------------------- */
define symbol __ICFEDIT_Program_In_RAM_ITCM_start__    = 0x00000000;
define symbol __ICFEDIT_Program_In_RAM_ITCM_end__      = 0x00003FFF;

/*= Data region(s) ===================================== */
/* RAM -- +RW +ZI region ------------------------------- */
/* The RW and Zero Initialized data will be in RAM-DTCM (0x4000 = 16k)
  All global variables will be located in this section. */
define symbol __ICFEDIT_region_RW_ZI_RAM_DTCM_start__  = 0x20000000;
define symbol __ICFEDIT_region_RW_ZI_RAM_DTCM_end__    = 0x20003FFF;

/* RAM -- STACK region --------------------------------- */
/* The Stack of the main application will be in RAM-DTCM (0x4000 = 16k)
 All internal variables of called functions will be located in this region. */
define symbol __ICFEDIT_region_STACK_RAM_DTCM_start__  = 0x20004000;
define symbol __ICFEDIT_region_STACK_RAM_DTCM_end__    = 0x20007FFF;

/* RAM -- HEAP region ---------------------------------- */
/* The Heap of the main application will be in RAM-DTCM (0x8000 = 32k)
 All dynamic allocations data got by malloc, realloc, calloc... will be located
 in this region.*/
define symbol __ICFEDIT_region_HEAP_RAM_DTCM_start__   = 0x20008000;
define symbol __ICFEDIT_region_HEAP_RAM_DTCM_end__     = 0x2000FFFF;

/*= STACK and Heap Sizes =============================== */
define symbol __ICFEDIT_size_cstack__ = 0x4000;  /* 16k */
define symbol __ICFEDIT_size_heap__   = 0x8000;  /* 32k */
/**** End of ICF editor section. ###ICF###*/

/*= Memory regions definition ========================== */
define memory mem with size = 4G;
define region Program_FlashAXI_region  = mem:[from __ICFEDIT_Program_In_FLASHTCM_start__ to __ICFEDIT_Program_In_FLASHTCM_end__];
define region Program_RAM_ITCM_region  = mem:[from __ICFEDIT_Program_In_RAM_ITCM_start__ to __ICFEDIT_Program_In_RAM_ITCM_end__];
define region RAM_DTCM_RW_ZI_region    = mem:[from __ICFEDIT_region_RW_ZI_RAM_DTCM_start__ to __ICFEDIT_region_RW_ZI_RAM_DTCM_end__];
define region RAM_DTCM_STACK_region    = mem:[from __ICFEDIT_region_STACK_RAM_DTCM_start__ to __ICFEDIT_region_STACK_RAM_DTCM_end__];
define region RAM_DTCM_HEAP_region     = mem:[from __ICFEDIT_region_HEAP_RAM_DTCM_start__ to __ICFEDIT_region_HEAP_RAM_DTCM_end__];

define block CSTACK    with alignment = 8, size = __ICFEDIT_size_cstack__   { };
define block HEAP      with alignment = 8, size = __ICFEDIT_size_heap__     { };

initialize by copy { readwrite, //ro
  /* Copy also the constants of these objects in RAM-ITCM */
    ro object  main.o
};               

do not initialize  { section .noinit };

place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };

place in Program_FlashAXI_region { readonly };

//place in Program_RAM_ITCM_region { ro };

place in Program_RAM_ITCM_region {
  section .text object main.o,
  /* Place also const data in ITCM-RAM. */
  section .rodata object main.o,
};

place in RAM_DTCM_RW_ZI_region  { readwrite };
place in RAM_DTCM_STACK_region  { block CSTACK };
place in RAM_DTCM_HEAP_region   { block HEAP }; 

【问题讨论】:

  • 您正在尝试解决某种 X-Y 问题。为什么要从 RAM 运行整个应用程序?在那里放置非常关键的例程是有意义的(例如,如果 FLASH 导致 4-5 个时钟的延迟很重要,则中断处理程序)否则根本没有意义
  • @0___________:我实际上写的是我不想把所有的代码都放在那里。链接器放置所有代码没有问题 - 在这种情况下它可以构建,但我没有那么多内存。即当我尝试进入 ITCM 仅 ISR 和主程序循环时,就会出现问题。是的,我想将所有不断执行的部分放入 RAM,相信我,这对我来说是有意义的)。

标签: stm32 iar


【解决方案1】:
define symbol __RAM_func_start__ = 0;  //ITC start
define symbol __RAM_func_end__ = 0x10000;//start + 64k
define region RAM_func_region = mem:[from __RAM_func_start__ to __RAM_func_end__];

define block RamCode {section .textrw};
place in RAM_func_region { block RamCode };
initialize by copy {readwrite};

例如标记函数__ramfunc

__ramfunc int main(void)
{
    /* ..... */
}

【讨论】:

  • 感谢您的建议!我将此添加到 .icf 并制作 main() 和 Test() __ramfuncs,它构建得几乎很好,但给出了“警告[Ta022]:可能的 rom 访问() 来自 __ramfunc 函数”。这显然是因为链接器没有将文字放在 RAM 中。是否可以强制它这样做?这种方法的另一个缺点是,如果我想在 RAM 中放置一些 HAL 函数,我需要修改 HAL 源。奇怪的是,您不能简单地说链接器放入 RAM 中只是需要的东西。
  • 您无法关闭此警告。发出此警告是因为 RAM 中的代码经常用于例如对 FLASH 进行编程,而此时 FLASH 不可用。它应该可以正常工作。
  • It is strange that you cannot simply say the linker to put in RAM just needed stuff 编译器怎么知道呢?你需要告诉他。我不会在必须从 RAM 运行的地方使用 HAL 函数。您应该在寄存器级别执行此操作。
  • 是的,我知道它应该可以工作,但我的意思是如果 IAR 将这些常量也放入 RAM 会更好。我可以以某种方式强制它吗?
  • "编译器怎么知道?" - 我的意思是他们(IAR)显然在 .icf 文件中有一些方法,而不是在源代码级别的 c/c++ 中。
猜你喜欢
  • 2021-04-26
  • 2020-03-07
  • 2017-05-16
  • 1970-01-01
  • 2017-06-24
  • 2013-02-20
  • 2014-10-16
  • 2018-04-10
  • 1970-01-01
相关资源
最近更新 更多