RT-Thread-Nano使能动态内存Heap后,程序无法运行

RT-Thread-Nano移植

  • [1. 动态内存堆](#1. 动态内存堆)
    • [1.1 问题](#1.1 问题)
    • [1.2 解决](#1.2 解决)
  • [3. 问题根源](#3. 问题根源)

1. 动态内存堆

1.1 问题

按照官方文档:在 RT-Thread Studio 上使用 RT-Thread Nano,新建nano工程后,可以正常运行。

但是开启内存管理后,系统无法正常启动,串口没有任何输出。

1.2 解决

参考详细说明:RT-Thread Nano 移植原理

原因是没有指定动态内存堆的起始地址和结束地址,需要在board.c中指定。有两种方法:

  • 方法1:使用数组作为动态内存堆。如果要使用Finsh组件,RT_HEAP_SIZE 设置尽量大一些
c 复制代码
board.c文件中添加:
#if defined(RT_USING_HEAP)
#define RT_HEAP_SIZE 1024*4
static uint32_t rt_heap[RT_HEAP_SIZE];
RT_WEAK void *rt_heap_begin_get(void)
{
    return rt_heap;
}

RT_WEAK void *rt_heap_end_get(void)
{
    return rt_heap + RT_HEAP_SIZE;
}
#endif
  • 方法2:指定系统HEAP,把空余RAM全部作为动态内存heap使用
    • 使用 RAM ZI 段结尾处作为 HEAP 的起始地址
    • 使用 RAM 的结尾地址作为 HEAP 的结尾地址

不同编译器的内存标识不一样,不同环境下的获取方式:

  1. MDK环境下,栈结束地址的获取:
c 复制代码
extern unsigned char Image$$ER_IROM1$$Limit;       // 获取RW段在FLASH中的加载地址
extern unsigned char Image$$RW_IRAM1$$Base;        // 获取RW段在RAM中的运行地址    
extern unsigned char Image$$RW_IRAM1$$RW$$Limit;   // 获取RW段在RAM中的结束地址
extern unsigned char Image$$RW_IRAM1$$ZI$$Limit;   // 获取ZI段在RAM中的结束地址
  1. IAR环境下,栈结束地址的获取:
c 复制代码
#pragma section="CSTACK"
#define HEAP_BEGIN      (__segment_end("CSTACK"))
  1. GCC环境下,栈结束地址的获取。RT-Thread Studio用的就是GCC编译环境:
c 复制代码
extern int __bss_end;
#define HEAP_BEGIN      ((void *)&__bss_end)
c 复制代码
#define STM32_SRAM1_START              (0x20000000)
#define STM32_SRAM1_END                (STM32_SRAM1_START + 20 * 1024)   // 结束地址 = 0x20000000(基址) + 20K(RAM大小)

#if defined(__CC_ARM) || defined(__CLANG_ARM)
extern int Image$$RW_IRAM1$$ZI$$Limit;                   // RW_IRAM1,需与链接脚本中运行时域名相对应
#define HEAP_BEGIN      ((void *)&Image$$RW_IRAM1$$ZI$$Limit)
#endif

#define HEAP_END                       STM32_SRAM1_END

3. 问题根源

RT-Thread Studio使用的是GCC编译器,使能动态内存后,在drv_common.h文件中,定义了heap的开始和结束地址

  • HEAP_BEGIN:堆的起始地址,
  • HEAP_END:堆的结束地址
  • 可以看到,这里把SRAM中空闲的内存,全部用作heap空间
  • 在link.lds中,定义了栈分配地址。(对应stm32 在 KEIL MDK 开发环境下的链接脚本文件 xxx.sct,散列文件)

因为我在新建项目的时候选择的是STM32F103ZGT6(flash1G,SRAM 96K),而实际的芯片是STM32F103ZGT6(flash 512M,SRAM 64K),所以HEAP地址错误,导致使能动态内存后,程序无法找到内存空间,系统无法正常运行。

参考:

  1. RT-Thread Nano 移植原理
  2. RT-Thread 堆区大小设置
  3. _sbrk: undefined reference to `end' problem
相关推荐
笨笨饿7 小时前
30_泰勒级数
c语言·stm32·嵌入式硬件·线性代数·机器学习·自动化·概率论
季鹏EthanJ7 小时前
VCC上电慢导致STM32无法复位
stm32·单片机·嵌入式硬件·上电复位故障·bor
LCG元8 小时前
STM32实战:基于STM32F103的智能体重秤(HX711+OLED)
stm32·单片机·嵌入式硬件
12.=0.12 小时前
【stm32_3】嵌入式软件系统架构
stm32·单片机·嵌入式硬件
会编程的小孩12 小时前
优先级与抢占实验
stm32·单片机
風清掦13 小时前
【江科大STM32学习笔记-10】I2C通信协议 - 10.1 软件I2C读写MPU6050
笔记·stm32·单片机·嵌入式硬件·物联网·学习
BackCatK Chen14 小时前
STM32保姆级入门教程|第6章:定时器中断原理 + 精准LED闪烁(1s_2s_3s)实战(功能超详细+CubeIDE手把手)
stm32·stm32cubeide·定时器中断·嵌入式入门·tim2·led精准闪烁·中断回调函数
橙露14 小时前
STM32 定时器与 PWM 输出:电机调速、LED 呼吸灯实战
stm32·单片机·嵌入式硬件
youcans_15 小时前
【FOC-MBD】(19)反 Park 坐标变换链路
stm32·单片机·嵌入式硬件·simulink·代码生成
Full Stack Developme16 小时前
Java Simple Serial Connector 教程
java·stm32·单片机