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
相关推荐
打地基的小白8 小时前
软件I2C-基于江科大源码进行的原理解析和改造升级
stm32·单片机·嵌入式硬件·通信模式·i2c
Echo_cy_9 小时前
STM32 DMA+AD多通道
stm32·单片机·嵌入式硬件
朴人9 小时前
【从零开始实现stm32无刷电机FOC】【实践】【7.2/7 完整代码编写】
stm32·单片机·嵌入式硬件·foc
追梦少年时9 小时前
STM32中断——外部中断
stm32·单片机·嵌入式硬件
bai_lan_ya9 小时前
stm32定时器中断和外部中断
stm32·单片机·嵌入式硬件
玄奕子9 小时前
GPT对话知识库——在STM32的平台下,通过SPI读取和写入Flash的步骤。
stm32·单片机·gpt·嵌入式·嵌入式驱动
py.鸽鸽10 小时前
王者农药更新版
stm32
星汇极客10 小时前
【星汇极客】单片机竞赛之2024睿抗机器人大赛-火线速递赛道(持续更新)
stm32·单片机·嵌入式硬件·机器人
Daemon.Chen11 小时前
【STM32开发之寄存器版】(五)-窗口看门狗WWDG
stm32·单片机·嵌入式硬件
嵌入式杂谈13 小时前
STM32中断编程详解:配置外部中断和中断服务例程
stm32·单片机·嵌入式硬件