C语言在STM32中的内存分配

发布时间:2024-01-25  

01前言


不说废话,先上示例代码



uint8_t num_byte[4];

uint32_t num_word;

const uint32_t num_word_const = 0x1234;

uint32_t *point_heap;

int main(void)

{

  uint8_t num_byte_stack;

  static uint8_t num_byte_static;

  

  point_heap = (uint32_t *)malloc(4);

  *point_heap = 0x3421;

  free(point_heap);

  

  num_byte_stack = 0x11;

  

#pragma section = "CSTACK"

  char *pbeginstk = __section_begin("CSTACK");

#pragma section = "HEAP"

  char *pbeginheap = __section_begin("HEAP");    

  

  printf("CSTACK addr is 0x%x

",pbeginstk);

  printf("HEAP addr is 0x%x

",pbeginheap);

  

  printf("num_byte addr is 0x%x

",&num_byte);

  printf("num_word addr is 0x%x

",&num_word);

  printf("num_word_const addr is 0x%x

",&num_word_const);

  printf("point_heap addr is 0x%x

",&point_heap);

  printf("point_heap is 0x%x

",point_heap);

  printf("num_byte_stack addr is 0x%x

",&num_byte_stack);

  printf("num_byte_static addr is 0x%x

",&num_byte_static);

}

打印如下


STACK addr is 0x20000320

HEAP addr is 0x20000720

num_byte addr is 0x20000308

num_word addr is 0x2000030c

num_word_const addr is 0x8002a44

point_heap addr is 0x20000310

point_heap is 0x20000728

num_byte_stack addr is 0x200006f8

num_byte_static addr is 0x20000318

先说结论:


num_byte、num_word、num_byte_static和point_heap存储在内部RAM中。


num_byte_stack存贮在栈中。


point_heap申请到的内存在堆中。


num_word_const在内部flash中。


如果是有同学对这个了然于胸,可以出门左转了,如果有些同学有兴趣,可以进一步往下看。


02大小端


因为后面的内容涉及到大小端问题,这里先说下大小端问题。


大端(Big-endian):数据的高位字节存放在地址的低端低位字节存放在地址高端;


小端(Little-endian):数据的高位字节存放在地址的高端低位字节存放在地址低端;


例如:


数据0x12345678存储格式


大端格式


低地址高地址


小端格式


低地址高地址


C语言在STM32中的内存分配

其中的地址,一般由编译器分配,也可在程序中自行指定。从上表中,可以清晰的看到,大小端是以字节为单位进行数据储存的方式。大端通俗的理解就是赋值数从左自右;小端则是从右自左。


我们常用的X86结构是小端模式,而KEILC51则为大端模式。很多的ARM,DSP都为小端模式,本文使用的平台STM32F207就是小段模式。


03逐步分析


如果有同学对这部分不是很熟悉,建议先看一下我之前的推文《C语言的内存分配》,先把C语言的堆栈,内存等概念先熟悉下。


先说关于堆栈的问题,下面代码可以打印出IAR平台下STM32的堆栈起始位置。


#pragma section = "CSTACK"

  char *pbeginstk = __section_begin("CSTACK");

#pragma section = "HEAP"

  char *pbeginheap = __section_begin("HEAP");

打印的结果如下


STACK addr is 0x20000320

HEAP addr is 0x20000720

这个地址是否正确,我们可以在IARdebug时,使用Disassembly窗口查看。


C语言在STM32中的内存分配

关于堆栈大小问题,如下


C语言在STM32中的内存分配

可以查到栈的终止位置是0x20000720,堆的终止位置是0x20000920。注意:这里计算牵扯到大小端的问题。


通过计算:


栈的大小=0x20000720-0x20000320=0x400。


堆的大小=0x20000920-0x20000720=0x200。


这和我们在IAR中的堆栈配置是一样的。


C语言在STM32中的内存分配

接下来就先说一下分配在内存的变量。


通过打印看出,num_byte、num_word、num_byte_static和point_heap并不在堆栈中,它们存储在内部RAM中。


使用Disassembly窗口查看如下

C语言在STM32中的内存分配

这也验证了static关键字,在修饰函数内的局部变量时,这个变量将和全局变量一样存储在内部ram中。


同时也说明了,STM32内部分配内存时候,是先分配全局变量(和static修饰的局部变量),再分配栈,最后再分配堆的。


对于栈的内存分配,局部变量,也就是num_byte_stack是存储在栈的范围内。


num_byte_stack addr is 0x200006f8

它的地址空间在栈中。因为在代码中num_byte_stack =0x11;使用Disassembly窗口查看到对应的地址数值是0x11。

C语言在STM32中的内存分配

关于栈,再说一句,栈不仅仅保存了局部变量,它会在函数切换,中断发生时保存现场,保存ARM内核的寄存器,这些不是这篇文章的讨论重点,这里先挖个坑,等以后有空再写篇文章专门说说这个部分。


堆的问题,简单来说:malloc申请的内存都在堆中。point_heap指针指向的内存地址就在堆的范围内。


point_heap is 0x20000728

代码中*point_heap= 0x3421;在Disassembly窗口查看到对应的地址数值是0x3421。

C语言在STM32中的内存分配

最后一个num_word_const,const修饰的变量是存储在内部flash中的,它的地址在内部flash范围内。


在代码中也有对应的赋值操作,constuint32_t num_word_const = 0x1234;在Disassembly窗口查看到对应的地址数值是0x1234。

C语言在STM32中的内存分配


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

相关文章

    ,这种方式和我们学习C语言时,使用malloc和free函数来申请内存和内存释放类似,malloc用于申请内存,free用于释放内存。本文我们就来介绍一种简单的内存管理方式:分块内存......
    什么是Bootloader 浅谈STM32中bootloader的内存分配;1. 什么是Bootloader Bootloader是硬件启动的引导程序,是运行操作系统的前提。在操......
    C语言常见问题;1、嵌入式与单片机的区别 从软件上,行业里经常把芯片中不带MMU(Memory  Management  Unit内存管理单元)从而不支持虚拟地址,只能裸奔或运行RTOS(实时......
    内容: 内存的管理单元 获取内存的方法 获取高端内存 内核内存的分配方式 总结   1. 内存的管理单元 内存最基本的管理单元是页,同时按照内存地址的大小,大致分为3个区。 1.1 页 页的......
    C语言在STM32中的内存分配;01前言 不说废话,先上示例代码 uint8_t num_byte[4]; uint32_t num_word; const uint32_t......
    关于STM32存储的堆栈地址;由c/C++编译的程序占用的内存分为以下几个部分 1、栈区(stack)—由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。 2......
    块已经被占用,其数值则代表被连续占用的内存块数。比如某项值为 10,那么说明包括本项对应的内存块在内,总共分配了 10 个内存块给外部的某个指针。内寸分配方向如图所示,是从顶到底的分配方向。即首先从最末端开始找空内存......
    管理技术,只能采用实存储器管理策略。系统使用分页内存分配方式,在启动时对实际存储器进行分页。系统对内存的访问是直接的,操作系统对内存空间没有保护,多个进程可共享一个运行空间,所以,即使......
    STM32大小端序与堆栈及其增长方向分析;  在开源电子中看到一篇文章讲的是栈增长和大端/小端问题。学C语言的时候,我们知道堆栈的区别:   (1)栈区(stack):由编译器自动分配和释放,存放......
    、vmalloc等内存分配函数结合使用,来实现这种动态分配,所以有人也把零长度数组称为柔性数组。 如何具体实现结构体动态内存分配? 在Linux内核或其他C语言编写的底层系统中,零长......

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>