这是描述信息

esp32 c6开发板乐鑫科技的代理商C语言程序堆和栈

esp32 c6开发板乐鑫科技的代理商C语言程序堆和栈

esp32 c6开发板乐鑫科技的代理商C语言程序堆和栈

esp32 c6开发板乐鑫科技的代理商C语言程序堆和栈

esp32

esp32 c6开发板乐鑫科技的代理商C语言程序堆和栈,程序运行时,C语言程序中的变量和数据可以存储在内存的静态存储区、栈或堆中。在程序编译阶段分配静态存储空间,静态存储空间的变量和数据在整个程序运行期间内有效。静态存储区中包含程序代码段和数据段。编译后生成的所有程序指令存储在代码段。


数据段包括只读数据段、已初始化的读/写数据段和未初始化段(BSS)三部分只读数据段是程序中使用的一些不会被更改的数据,放置在系统的 ROM 空间经const 修饰的变量,以及程序中使用的常数等常量通常存放在该段中。


已初始化数据段是在程序中声明,并且具有初值的变量。esp32 c6开发板乐鑫科技的代理商这些变量占用存储器有空间,位于可读/写的内存区域内,并且有初始值,以供程序运行时读/写。已经初始化的全局变量和静态(static)局部变量存放在该段中。


未初始化段(BSS)通常存放程序中未初始化的全局变量和静态变量,是可读/写内存区域。在系统启动的初始化阶段创建栈和堆的空间,栈保存程序中的局部和临时变量,堆为程序中动态申请的内存提供存储空间。因此,栈和堆常称为动态存储区。esp32 c6开发板乐鑫科技的代理商BSS 段、栈和堆空间的大小不会影响可执行程序文件的长度。执行函数时,函数内的局部恋量都可以在栈空间上分配存储单元。退出函数时这些存储单元将被自动释放。


运行时,程序中用 malloc 或 new 在堆中申请内存资源,用free 或 delete 释放动态申请的内存资源。动态内存的生存周期从用程序申请成功开始到在程序中释放结束。动态申请的内存必须在程序中释放,否则会出现内存泄漏。


在 C语言中,变量的作用域不仅影响变量的时效性,还影响变量在内存中的区域。在函数内部定义的变量称为局部变量(Local Variable),它的作用域也仅限于丽数内部,存储在栈空间中。在所有函数外部定义的变量称为全局变量(Global Varia-ble),它的默认作用域是整个程序,也就是所有的代码文件,包括源文件(.c 文件)和头文件(.h 文件)。如果给全局变量加上 static 关键字,则它的作用域就变成了当前文件。esp32 c6开发板乐鑫科技的代理商链接时在静态区中为全局变量分配内存空间。在示例 8.3 中,链接时将全局变量 status 和 value分配到静态存储区,其中 static 关键字限定变量能否被其他文件中的代码访问,而代码块域中的变量 t、ptr 和 local_st 则要根据不同的定义方法,分配到不同的区域,其中t和 ptr 是局部变量,存储在栈中;local_st 是静态变量,存储在静态存储区中。ptr 指向由 malloc 分配的空间。


示例 8.3:变量类型。

/ *main.c*/
# include <stdio.h>
# include <stdlib.h>
static int status;    //静态全局变量,静态存储区
int value;        //全局变量,静态存储区
int main(void)
{
intt = 0;        //局部变量,栈上申请
int *ptr = NULL;    //指针变量
static int local st = 0;    //静态变量
local st ++;
t= local_st;
ptr = (int *)malloc(sizeof(int));    //从堆上申请空间
if(ptr != NULL)
{
free(ptr);
ptr = NULL;    //free 后需要将 ptr 置空。
}
}


在运行 C语言用户程序前系统必须创建和分配栈和堆空间,确定内存中栈和堆的位置和太小。栈和堆的空间过小,可能导致程序运行错误。esp32 c6开发板乐鑫科技的代理商如果扩大栈和堆的空间,将增加对系统内存资源的要求。因此需要根据系统中程序的实际情况,设置栈和堆的大小。


通常,在编写系统启动程序时用宏定义,或者用序工程属性的“code”选项设置城和的大小。例如,在 ARM 处理器 s3c2410A 的启动程序 s3c2410A.s 中,用宏定以栈和堆的大小。


/*s3c2410A.s*/
UND Stack_Size EOU    0x00000000    //未定义异常模式
svc_Stack_Size EQU    0x00000008    /监督模式栈
ABT Stack_Size EQU    0x00000000    /读/写异常模式
FIQ_Stack_Size EQU    0x00000000    /快速中断模式
IRO Stack_Size EQU    0x00000080    /中断模式
USR Stack_Size EQU    0x00000400    /用户模式
Stack_Size EQU    (UND_Stack_Size + SVC_Stack Size + ABT_Stack_Size +    
\FIQ_Stack_Size + IRQ_Stack_Size + USR Stack_size)        //总空间
Heap_Size EQU    0x00000000    //堆空间大小
Heap_Size EQU    0x00000000Heap_Size    EQU 0x00000000


如图 8.4 所示为 SEGGER Embedded Studio for RISC-V 中,使用程序工程选项设置栈和堆大小的窗口。相应的链接脚本文件中的内容如下:

/*hello.ld*/
__HEAPSIZE__= 1024;
__STACKSIZE__=1024;


引导程序在进入C语言用户主程序 main()前设置栈和堆空间。
引导程序可以直接跳到用户 (main)函数,也可以先调用库函数“__main”,然后从函数“ __main”中跳到用户函数 main()。


Runtime Memory Area
.Heap Size    1024 bytes
.Stack Size    1024 bytes
图8.4堆栈大小设置选项


在riscv-crto.s 中,引导程序利用下列两行声明栈和堆段,链接器根据设置的栈和堆的大小创建栈和堆。esp32 c6开发板乐鑫科技的代理商引导程序将栈顶指针写入 sp 寄存器。堆的起始地址为“__stack_end__-__STACK_SIZE__-__HEAP_SIZE__”。

/*riscv-crt0.s*/
.section .stack, "wa",% nobits
.section .heap, "wa",% nobits
_start:
La sp,__stack_end__ //设置栈
......

地址:深圳市宝安区西乡街道麻布社区宝安互联网产业基地A区6栋7栋7706

邮箱:Sales@ferry-semi.com

版权所有©2020  深圳市飞睿科技有限公司  粤ICP备2020098907号    飞睿科技微波雷达wifi模块网站地图