• RTOS: 堆和栈


    堆和栈

    概念

    堆:程序员手动分配(malloc/new)和释放(free/java不用手动释放,由GC回收),在堆上分配内存叫动态分配,一般硬件内存有多大堆内存就有多大

    栈:系统自动分配和释放,保存全局、静态、局部变量,在栈上分配内存叫静态分配,大小一般是固定的。

    这里是才cubeMX模板上采用 韦东山 老师的demo,这里需要把MX_GPIO_Init()和HAL_Init()先屏蔽,要不然会一直进入硬件中断中。

    /* USER CODE BEGIN 0 */
    char heap_buf[1024];
    int pos=0;
    
    void *my_malloc(int size)
    {
      int pre_pos=pos;
      pos += size;
      
      return &heap_buf[pre_pos];
    }
    /* USER CODE END 0 */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    int main(void)
    {
      /* USER CODE BEGIN 1 */
      char context = 'a';
      int size = 100;
      char *buf = my_malloc(size);
      /* USER CODE END 1 */
    
      /* MCU Configuration--------------------------------------------------------*/
    
      /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
      //HAL_Init();
    
      /* USER CODE BEGIN Init */
    
      /* USER CODE END Init */
    
      /* Configure the system clock */
      //SystemClock_Config();
    
      /* USER CODE BEGIN SysInit */
    
      /* USER CODE END SysInit */
    
      /* Initialize all configured peripherals */
      //MX_GPIO_Init();
      /* USER CODE BEGIN 2 */
      for(int i=0; i<size; i++)
      {
        buf[i] = context;
      }
      
      /* USER CODE END 2 */
      return 0;
      /* Infinite loop */
      /* USER CODE BEGIN WHILE */
      while (1)
      {
        /* USER CODE END WHILE */
    
        /* USER CODE BEGIN 3 */
      }
      /* USER CODE END 3 */
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    先设置为仿真环境,然后点击仿真的按钮,在对应的代码行加上断点就可以进行调试了
    在这里插入图片描述
    在这里插入图片描述
    在调试过程中可以把对应变量添加到watch或者memory窗口进行查看
    在这里插入图片描述
    然后在单步运行的时候就可以看到对应的内存的变化,或者变量的变化了
    在这里插入图片描述

    使用下面的代码来看栈的过程

    int a_func()
    {
      int a=0;
      a++;
      return a;
    }
    
    int b_func()
    {
      int b=0;
      b++;
      return b;
    }
    
    int c_func(int val)
    {
      int c;
      c += val;
      
      a_func();
      b_func();
        
      
      return c;
    }
    
    int main(void)
    {
      /* USER CODE BEGIN 1 */
      char context = 'a';
      int size = 100;
      char *buf = my_malloc(size);
      /* USER CODE END 1 */
    
      /* MCU Configuration--------------------------------------------------------*/
    
      /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
      //HAL_Init();
    
      /* USER CODE BEGIN Init */
    
      /* USER CODE END Init */
    
      /* Configure the system clock */
      //SystemClock_Config();
    
      /* USER CODE BEGIN SysInit */
    
      /* USER CODE END SysInit */
    
      /* Initialize all configured peripherals */
      //MX_GPIO_Init();
      /* USER CODE BEGIN 2 */
      //for(int i=0; i
      {
       // buf[i] = context;
      }
      c_func(10);
      /* USER CODE END 2 */
      return 0;
      /* Infinite loop */
      /* USER CODE BEGIN WHILE */
      while (1)
      {
        /* USER CODE END WHILE */
    
        /* USER CODE BEGIN 3 */
      }
      /* USER CODE END 3 */
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70

    在使用代码的时候,有可能无法打断点,这是因为编译器对代码进行了优化,可以在设置里面调整优化等级,这里设置为0(不做优化)就可以了。
    在这里插入图片描述
    这里借用韦东山老师的课堂笔记
    在这里插入图片描述

    每个函数在运行的时候都有自己的栈空间,来存储局部变量、LR(Link Register),LR用于保存子程序的返回地址,在调用函数的时候,会先lr压栈,在调用结束后根据lr在跳到对应的地址处(也就是调用子函数的下一句代码)

    lr就是连接寄存器(Link Register, LR),在ARM体系结构中LR的特殊用途有两种:一是用来保存子程序返回地址;二是当异常发生时,LR中保存的值等于异常发生时PC的值减4(或者减2),因此在各种异常模式下可以根据LR的值返回到异常发生前的相应位置继续执行。

    对应代码在这里 cubeMx heap-stck

  • 相关阅读:
    java对象深拷贝(Mapstruct)代码实现
    git基本使用
    StackExchange.Redis 高并发下timeout超时问题如何解决?
    聚星文社工具【聚星文社】Ai小说推文一键生成工具大更新:一键出图、一键改文、一键关键帧、MJ+SD推文神器
    竞赛选题 深度学习 python opencv 火焰检测识别 火灾检测
    为什么刀具数据库无法打开?
    当个 PM 式程序员「GitHub 热点速览」
    增强拉格朗日数字图像相关和跟踪研究(Matlab代码实现)
    vue+Vant,关闭Popup弹框,遮罩层并没有消失
    性能提升 25 倍:Rust 有望取代 C 和 C++,成为机器学习首选 Python 后端
  • 原文地址:https://blog.csdn.net/EngineerHe/article/details/127845406