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
相关推荐
Hello_Embed4 小时前
STM32HAL 快速入门(二十):UART 中断改进 —— 环形缓冲区解决数据丢失
笔记·stm32·单片机·学习·嵌入式软件
清风6666667 小时前
基于STM32的APP遥控视频水泵小车设计
stm32·单片机·mongodb·毕业设计·音视频·课程设计
小莞尔15 小时前
【51单片机】【protues仿真】基于51单片机数控直流稳压电源系统
c语言·stm32·单片机·嵌入式硬件·51单片机
小莞尔15 小时前
【51单片机】【protues仿真】基于51单片机密码锁系统
c语言·stm32·单片机·嵌入式硬件·51单片机
黑不拉几的小白兔15 小时前
stm32教程:USART串口通信
stm32·单片机·嵌入式硬件
田甲20 小时前
【STM32】串口的阻塞、中断、DMA收发
stm32·单片机·嵌入式硬件
一支闲人1 天前
带你了解STM32:GPIO通用输入输出口
stm32·基础知识·适用于新手小白
WD137298015571 天前
WD5030A 芯片,12V降5V,输出电流12A,电路设计
stm32·单片机·嵌入式硬件·汽车
白掰虾1 天前
STM32N6&AI资料汇总
人工智能·stm32·嵌入式硬件·stm32n6·stm32ai
星空的资源小屋1 天前
Digital Clock 4,一款免费的个性化桌面数字时钟
stm32·单片机·嵌入式硬件·电脑·excel