当前位置: 首页 > wzjs >正文

兰州网站seo分析网站建设 源码

兰州网站seo分析,网站建设 源码,No酒店网站建设,有帮忙做儿童房设计的网站吗freertos入门—栈的概念 1 栈的概念 栈也是一块内存空间,CPU的SP寄存器指向它,它可以用于函数调用、局部变量、多任务系统里保存现场。栈对于多任务系统非常的重要,每个任务都有自己的栈,我们只有深入理解栈的作用,才…

freertos入门—栈的概念

1 栈的概念

  栈也是一块内存空间,CPU的SP寄存器指向它,它可以用于函数调用、局部变量、多任务系统里保存现场。栈对于多任务系统非常的重要,每个任务都有自己的栈,我们只有深入理解栈的作用,才能深入理解多任务系统。

2 函数调用

  我们首先编写一个程序,程序流程为:在主函数中调用函数a_func(),在a_func()中调用b_func()与c_func()。

#include "stm32f10x.h" int g_cnt;int b_func(volatile int a)
{a += 2;return a;
}int c_func(volatile int a)
{a += 3;return a;
}void a_func(volatile int a)
{g_cnt = b_func(a);g_cnt = c_func(g_cnt);
}int main(void)
{char ch = 65;volatile int i = 99;a_func(i);return 0;
}

  接着利用下述方法生成反汇编码:
在这里插入图片描述
在这里插入图片描述

fromelf --text -a -c --output=test.dis  .\Objects\点亮一个LED灯.axf

  打开生成的反汇编码,将反汇编码显示如下:
在这里插入图片描述
  函数调用的本质就是使用 BL 指令,但是我们main函数调用 a_func 函数时,我们设置了LR。然后我们在 a_func 函数里调用 b_func 函数时,又使用同样的 BL 指令设置 LR 等于另外一个值,那么我们的 LR 不就是被覆盖了吗?由此我们引出以下问题:

  1. LR被覆盖了,怎么办?
  2. 局部变量在栈中如何分配?
  3. 为何每个RTOS任务中都有自己的栈?

  在函数调用过程中,我们调用函数a,我们设置了 LR 等于函数 a 执行完后的返回地址,在函数 a 中我们马上去调用函数 b,BL 指令同时会去设置 LR,会把之前的 LR 覆盖掉,那么显然在 LR 被覆盖前会去保存 LR。
在这里插入图片描述
  同样在函数 b 中,我们不管三七二十一,也是先把 LR 保存下来,后面我们可能不会去修改 LR ,但是为了以防万一,或者说编译器为了统一处理,在函数入口处会保存 LR。
在这里插入图片描述
  接着我们把函数调用时栈的分配具体讲解:

  1. 假设一开始,寄存器指向某一位置,我们调用 main 函数,保存 r3 以及 lr 。
    在这里插入图片描述

  2. main 函数调用函数 a,会去保存 lr 和 r0。
    在这里插入图片描述

  3. 函数 a 调用函数 b ,函数 b 里也去保存两个寄存器。
    在这里插入图片描述

  4. 接着我们调用函数 c ,那么函数 c 的栈是在 函数 b 的栈下面吗?答案是否定的,我们调用完函数 b 后,函数 b 的栈就被回收了,所以当函数 b 的栈被回收后,我们才开始分配函数 c 的栈。
    在这里插入图片描述

  所以,在每一个c函数的入口,会划分出自己的栈,保存 LR 进栈里,保存局部变量。

2 局部变量

  对于局部变量的讲解,我们从下面 main 函数中的局部变量开始分析:
在这里插入图片描述
  一进入 main 函数时,就入栈了若干个寄存器:
在这里插入图片描述
  我们分析 MOVS r2,#0x41 ,0x41是65,那么我们的 r2 寄存器其实就是局部变量 ch ,所以说局部变量有可能保存寄存器中,不一定保存在内存里,当我们加上 volatile 后它就保存在内存里了,或者说寄存器不够用时也保存在内存里。
在这里插入图片描述
  继续分析 MOVS r0,#0x63 , 0X63 是99,那么 r0 是 i 变量,接着将 r0 写入[sp,#0]中,所以变量i是保存在栈中。
在这里插入图片描述
  所以 main 函数一进来的时候他就划分了栈,在栈中保存了一些寄存器,它使用保持寄存器的方式给我们划分出了一块空间,这块空间在后面代码我们分析了知道 [sp,#0] 对应的是 i 。
  我们继续分析 MOVS r4,#0xc8 ,0xc8 是 200 ,那么 r4 是 uch 变量。该变量保存在寄存器中而不是内存中。
在这里插入图片描述

3 RTOS如何使用栈

  为什么每一个 RTOS 任务都要有一个属于自己的栈?我们以下面函数 b 为例,在函数中它会将变量 a 加 2 ,然后返回这个新的值。
在这里插入图片描述
  现在假设有两个任务,Task_A 中定义一个变量 cnt ,然后定义一个死循环,在这个死循环中不断的去累加这个 cnt ,任务 b 也是一样。
在这里插入图片描述
  那么这两个任务如何运行呢?任务A运行一阵子发生切换,然后任务B运行一阵子再发生切换,接着再发生切换,这个切换在哪发生我们根本无法控制。
在这里插入图片描述
  我们来看下面一个场景,函数 a 调用函数 b ,他可能辛辛苦苦才执行到 ADDS r0,r0,#2 ,这个数值还未返回就发生了切换:
在这里插入图片描述
  在任务A发生切换时会先保存A的现场然后恢复B,任务B发生切换时会先保存B的现场然后恢复A。
在这里插入图片描述
&emsps; 以人为例,这个人要看两本书,一本是语文一本是数学。他的脑子只有一个,只能先读语文再读数学,学腻之后再看语文再看数学。一开始的时候语文读到了100页,读累了想看数学了,那得在100页加入书签。看了200页数学也看累了,那得在200页处加入书签,然后从前面语文100页处继续看。这加书签就是保存现场,从书签那里继续看就是恢复现场。
在这里插入图片描述
  任务A运行到黑线这个位置,辛辛苦苦把 r0 加上了2,但是很不幸在这里我们还没有使用这个新结果呢,我就被切换出去了,那怎么办?我们辛辛苦苦算出的结果不能够浪费,在这个场景里是 r0 ,在其他的场景里可能是 r1 或者 r2 ,所以干脆把所有的寄存器都保存下来。那么这些寄存器保存在什么位置,我们分析下处理器架构。
在这里插入图片描述
  保存的寄存器只能保存在内存里。假设任务A一开始的时候我们给它分配了一块内存,我们让sp寄存器指向addr a,分配 Task_A 函数的栈,接着 Task_A 函数调用 b 函数,分配 b 函数的栈,任务 A 发生切换时是被内核的定时器中断函数来切换,定时器中断函数需要保存任务 A 的现场,保存切换瞬间所有的寄存器到任务A的栈里面。
在这里插入图片描述
  当保存现场完成后sp指向最后,并且将sp记录到任务A的结构体中。为什么需要在任务A的结构体中记录sp,因为以后切换的时候我们需要先找到任务A的结构体,从这结构体中我们才可以找到sp,把sp赋给硬件的寄存器。
  接着我们应该讲解任务 B 的恢复,但是任务 B 的恢复与任务 A 的恢复一样,因此我们以任务 A 的恢复进行讲解。恢复任务 A 首先找到任务 A 的结构体得到 A 的sp。得到任务 A 的sp后我们就可以把保存的寄存器值全部恢复到硬件上,恢复到 cpu 里。这样虽然在 ADDS r0,r0,#2 发生了切换,但是恢复现场后寄存器的值都能被恢复到cpu中,因此可以继续执行下面的程序。
  所以RTOS中每个任务有不同的栈是因为:1.有不同的调用关系  2.有自己的局部变量  3.保存现场

http://www.dtcms.com/wzjs/542098.html

相关文章:

  • 北京网站制作推广cocos游戏开发
  • 成都用设计公司网站免费小程序模板
  • 知名网站建设联系电话网站建设玖金手指谷哥十
  • 网站设计目标怎么写游戏代理平台免费版
  • 响应式网站 产品轮播代码去哪个网站做农产品推广
  • 什么是网站架构天河营销型网站建设
  • wordpress 代码模块排名优化推广
  • 广州seo网站营销大连旅顺口景点介绍
  • 闵行网站开发seo网站优化代码
  • 附近小程序定制公司保定seo
  • 台州seo网站排名优化国家反诈中心app下载安装
  • 网站开发前后端做视频解析网站是犯法的么
  • 廊坊网站建设制作电话免费做产品画册的网站
  • 网站建设都有什么功能做视频网站都需要什么软件
  • 最火爆的国际贸易网站广州网站设计开发公司
  • cms网站怎么做上海网站建设 虹口
  • 网站如何做百度推广方案wordpress后台图片无法显示
  • 网站建设代码标签大全深圳高端品牌网站建设
  • 如何建设好英文网站网络营销案例题
  • 南京 网站建站wordpress装修主题
  • 北京微信网站设计报价室内设计多少钱
  • 北京工商局网站怎么做增资预约网免费建站流程
  • js图片展示网站网站不用工具开发建设
  • 网络课程网站建设小程序注册之后怎么开发
  • 免费网站免费雄安网站制作多少钱
  • 做外贸网站特色东营哪里有做网络推广的
  • asp网站检查商业网点消防规范
  • 网站建设公司介绍ppt做商城的网站程序
  • 杭州市建设职业中心网站软文撰写案例
  • 如何自己开发一个网站网站开发课题背景