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
相关推荐
得单片机的运3 小时前
STM32的以太网的搭建
stm32·单片机·嵌入式硬件·物联网·以太网·iot·w5500
酷飞飞4 小时前
RTC和看门狗基于GD32F407VE的天空星的配置
stm32·单片机·嵌入式硬件·mcu
qq_401700415 小时前
STM32的HardFault错误处理技巧
stm32
WD137298015576 小时前
WD5030A,24V降5V,15A 大电流,应用于手机、平板、笔记本充电器
stm32·单片机·嵌入式硬件·智能手机·汽车·电脑·51单片机
日更嵌入式的打工仔6 小时前
GPIO 中断通用配置指南
stm32·单片机·嵌入式硬件
平凡灵感码头6 小时前
基于 STM32 的智能门锁系统,系统界面设计
stm32·单片机·嵌入式硬件
Truffle7电子7 小时前
STM32理论 —— 存储、中断
stm32·嵌入式硬件·嵌入式·存储·中断
XiangrongZ9 小时前
江协科技STM32课程笔记(四)—定时器TIM(输入捕获)
笔记·科技·stm32
xyx-3v9 小时前
SPI四种工作模式
stm32·单片机·嵌入式硬件·学习
BreezeJuvenile11 小时前
实验二 呼吸灯功能实验
stm32·单片机·嵌入式系统·流水灯·实验