STM32H7 - IAR 将局部变量放入“保留内存”(0x1FF20000 - 0x1FFFFFFF)
Posted
技术标签:
【中文标题】STM32H7 - IAR 将局部变量放入“保留内存”(0x1FF20000 - 0x1FFFFFFF)【英文标题】:STM32H7 - IAR Placing Local Variables into 'Reserved Memory' (0x1FF20000 - 0x1FFFFFFF) 【发布时间】:2019-06-07 12:24:33 【问题描述】:我使用 STM32H7 开始了一个新项目,目前使用 IAR EWARM V8,使用 STM32CUBEMX 生成配置代码,并开始进行初始项目。
我完成了几个 CUBEMX eval 项目,以使一些硬件得到验证和工作,并且能够很好地单步执行代码。
但是发生了一些奇怪的事情,特别是对于变量,如果您将它们分配为函数中的局部变量,IAR 会以某种方式将它们放入“系统保留”内存范围...
即在0x1FF20000
- 0x1FFFFFFF
内
例如... STM提供的项目示例'FMC_NOR',是测试我们的NOR flash等的测试代码。
他们在main.c
文件的顶部创建了这两个小数组作为全局变量。
(buffer_size
是 0x1000)
uint16_t aTxBuffer[BUFFER_SIZE] = 0;
uint16_t aRxBuffer[BUFFER_SIZE] = 0;
在全局空间时,它们被分配在 DTCM 区域 (0x2000:0000)
当作为本地变量移动时,它们会被分配到“保留空间”中...
发生的情况是,当 IAR 遇到这样的任何数组时,处理器会出现“不精确的数据访问”硬件故障。
初始化 JPEG 模块的代码也会出现同样的错误,因为它试图加载霍夫曼表数组等...
使用 TrueStudio 时不会出现此问题... CubeMX 会为您使用的任何编译器自动生成链接器文件。
我没有在链接器文件中特别看到任何指向保留内存地址的内容。
所以不确定会发生什么?我是使用这个处理器的新手,所以我才刚刚开始了解它的内存映射。
感谢您的任何帮助或建议,我想弄清楚 IAR,因为到目前为止我比 TrueStudio 更喜欢它。
【问题讨论】:
您的“小阵列”每个为 8192 B。你的堆栈大小可能是 512B。您尝试将 16KB 的数据放入大概 0.5kB 的空间。如果堆栈位于 RAM 段的顶部,则数组的起始地址将在该段之外。因此,如果您尝试访问它,则会遇到严重错误。基于 gcc 的启动将堆栈放在 RAM 段的底部。所以你只是默默地溢出堆栈 是的,所以我认为堆栈是这些数组的问题... 但是 JPEG 模块初始化也会出现同样的问题......在全局内存中声明了一堆 const Huffman 表......但是在 IAR 下,这个 jpeg 初始化会抛出相同的“不精确的数据访问” ' 在这个位置: if(JPEG_Set_HuffEnc_Mem(hjpeg, (JPEG_ACHuffTableTypeDef *)acLum_huffmanTableAddr, (JPEG_DCHuffTableTypeDef *)dcLum_huffmanTableAddr, (JPEG_ACHuffTableTypeDef *)acChrom_huffmanTableAddr, (JPEG_DCHuffTableTypeDef *)dcChrom_huffmanTableTypeDef) != HAL_TABLECode HAL_OK) hjpeError返回 HAL_ERROR; 我没有对这个例程做任何修改,所以无论 IAR 在做什么,这些数组要么未对齐,要么再次位于不正确的内存位置? 好的,我发现了问题...绝对是 CubeMX 及其 IAR 生成代码的问题.. 他们的链接器文件将堆栈大小设置为 1k (0x400)... 他们的 JPEG 初始化函数 (JPEG_ACHuff_BitsVals_To_SizeCodes ) 对于他们的 huff init 数组来说,需要的不仅仅是堆栈上的东西......所以在这些数组的初始化过程中,他们会直接越过 JPEG 实例的句柄,然后把所有东西都炸毁......我可能会让 STM 知道他们可能应该在 IAR 的代码生成中解决这个问题...... 【参考方案1】:我解决了我自己的问题...所以不再需要这方面的帮助...
这是在 STM CUBEMX 为 STM32H7 生成的“stm32h743xx_flash.icf”中...
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x400;
define symbol __ICFEDIT_size_heap__ = 0x200;
/**** End of ICF editor section. ###ICF###*/
将“size_cstack”提高到 2k (0x800),一切都很好......
【讨论】:
另外,只是为了添加更多细节,这就是我所说的“IAR vs True Studio”TrueStudio 在他们的链接器文件中有一个“最小堆栈”和“最小堆”大小,所以很明显当他们运行 gcc 编译器,它根据书面代码所需的内存调整堆栈......而 IAR 只是严格按照“size_cstack”编译它,即使书面代码需要更多......它只是让编译后的代码运行它结束了...所以这就是为什么现在两者之间的一切都有意义..以上是关于STM32H7 - IAR 将局部变量放入“保留内存”(0x1FF20000 - 0x1FFFFFFF)的主要内容,如果未能解决你的问题,请参考以下文章
STM32H7第16章 ThreadX原装任务统计分析功能实现(含IAR的ThreadX插件使用)
STM32H7第16章 ThreadX原装任务统计分析功能实现(含IAR的ThreadX插件使用)
STM32H7教程第14章 STM32H7的电源,复位和时钟系统
STM32H7的DSP教程第32章 STM32H7的实数FFT的逆变换(支持单精度和双精度)