堆与栈的概念(RTOS)

目录

       

#堆在RTOS的概念

#相关代码表示

#堆相关特点

#栈在RTOS中的概念

#栈的代码表示

#栈的相关特点

#为什么每个RTOS任务都要有自己的栈


       

前言:本篇参考韦东山老师的RTOS,连接放在最后

#堆在RTOS的概念

       本文所指的堆与栈并不是数据结构中,的堆与栈,实时操作系统(RTOS)中,堆(Heap)是一个动态内存分配区域,用于存储程序运行过程中大小未知或可变的数据结构。堆内存不像栈内存那样由操作系统自动管理,它是由程序员申请和释放的。用户可以根据需要请求一段连续的内存空间,并在程序执行过程中随着数据的变化而增长或减小。

         堆与栈经常混着用,而栈是RTOS的基础,所为堆就是一块内存,我们可以管理内存,从内存中使用一部分,用完之后在把他释放回去。

#相关代码表示

        代码里定义了heap_buf[1024]数组,作为内存空间,定义void *my_malloc(int size);这个函数在main()里面去使用,数组的内存空间,这个过程就是申请内存空间的堆,使用堆作为存储数据的存在,同样可以使用函数,对已经定义使用的,内存空间去进行释放。

char heap_buf[1024];//这里定义一个堆
int pos = 0;
void *my_malloc(int size);
int main()//主函数
{
    char ch = 65;
    char *buf = my_malloc(100);//调用函数占用内存
    unsigned char uch = 200;
   
    for(i = 0; i<26;i++)
    buf[i] = 'A'+i;

    return 0;
}
void *my_malloc(int size)//定义函数使用堆
{
    int old_pos = pos;
    pos+=size;
    return &heap_buf[old_pos];
}
#堆相关特点

动态分配进程可以在运行时根据需要动态地向堆中申请内存,不需要预先指定固定大小。

无预定义大小堆的大小没有固定限制,直到系统内存不足或者达到预设的内存阈值才会停止分配。

内存管理程序员负责堆内存的分配和释放,如果忘记释放已不再使用的内存,可能导致内存泄漏。

性能开销由于堆内存管理通常比栈内存复杂,可能会引入一定的性能开销,尤其是在频繁大块分配或回收时。

        总结:堆是程序中的内存分配区域,用于存储变量等,这个空间由代码申请或者释放。

#栈在RTOS中的概念

        栈在RTOS中非常重要,RTOS操作系统,没有文件功能,因为只有内核,仅支持多任务的要求,而栈也是一块内存空间,CPU的SP寄存器指向栈,可以用于函数调用·,局部变量,多任务系统保存现场空间。

#栈的代码表示

void a_func(volatile int a);//定义函数声明
void b_func(volatile int a);//定义函数声明
void c_func(volatile int a);//定义函数功能
int g_cnt = 0;//定义变量声明
int main()//主函数
{
    char ch = 65;
    char *buf = my_malloc(100);//调用函数占用内存
    unsigned char uch = 200;
    volatile int i = 99;
    for(i = 0; i<26;i++)
    buf[i] = 'A'+i;

    a_funct(i);
    return 0;
}
void a_func(volatile int a)//定义函数功能
{
    g_cnt =  b_funct(a);
    c_funct(g_cnt);
}
void b_func(volatile int a)//定义函数功能
{
    a+=2;
    return a;
}
void c_func(volatile int a)//定义函数功能
{
    a+=2;
    return a;
}
void *my_malloc(int size)//定义函数使用堆
{
    int old_pos = pos;
    pos+=size;
    return &heap_buf[old_pos];
}

        在这个程序里面,main()里面调用a_func  ,a_func里面调用了b_func和c_func,这里面有一个层层调用的关系,对应的汇编代码如下。

        main()里面a_func ,调用指令。在使用BL汇编指令,进行函数调用的时候,BL指令的功能是,LR=0x8000154,同时PC=0x8000154,这个地址就是调用函数a_func在寄存器中的地址,同时调用,在执行调用函数的时候,会保存返回地址,PUSH {r0,r1}  所以C语言调用函数的本质是使用BL指令main()函数中转跳执行函数的时候,下面一些语句还没有执行,需要执行,在执行完调用函数的时候就需要返回,转跳位置,重新进行执行。

        在最后调用的函数c_func(),执行完之后,lr寄存器的值,会被弹出,里面保存的是a_func()函数的地址,从而跳转到c_func()被调用的地方,继续执行下面的语句,同理当a_func()执行完成的时候,lr寄存器里面的值保存的是main()里面a_func()跳转的部分,从而继续执行下面的语句。

        在main()函数/自定义函数,的汇编语言中第一条语句,通常是保存 r0  r1  r2  r3 这些寄存器  LR返回地址  局部变量 这些数据会被保存RAM的栈中,在函数的调用结束之后,局部便令,LR在栈中分配的内存空间会被释放。

#栈的相关特点

         在实时操作系统(RTOS)中,栈(Stack)是一个特殊的内存区域,主要用于存储程序执行过程中的局部变量、函数参数和函数调用的返回地址。它是按照后进先出(Last In, First Out,LIFO)的原则工作的,类似于生活中的堆叠物品。

        每当程序进入一个新的函数或遇到递归调用时,系统会在栈顶分配空间来保存这些信息。当函数执行完毕并返回时,相关的数据会被弹出栈,以便让控制权回到调用该函数的地方。栈的空间大小通常是有限的,如果栈溢出(超过其预设的最大限制),可能会导致严重的运行时错误,甚至影响系统的稳定性。

        RTOS中的任务调度和中断处理也常常利用栈,因为它们涉及快速响应和切换。每个任务或中断服务都会有自己的私有栈,这样即使在中断处理过程中,主任务的执行不会被打断,保证了操作的连续性和实时性。

#为什么每个RTOS任务都要有自己的栈

        在RTOS环境下,有任务A和任务B,在多任务系统下,A与B切换运行,由定时器发生中断进行切换任务。

        每次函数进行切换的时候,需要保存现场,恢复现场,指的是保存A函数的寄存器,恢复保存B函数的寄存器,这里(A函数切换B函数为例)反之,则相反。

        这些保存的现场,保存的就是函数使用的寄存器,局部变量,LR,等等。这些数据会被保存在内存的的位置,所以说每一个任务都需要有自己的栈。

                                欢迎指正,最后希望对你有所帮助!!!

[3-3-2]_栈的概念_函数调用_哔哩哔哩_bilibili

  • 17
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值