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 */
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 */
}

先设置为仿真环境,然后点击仿真的按钮,在对应的代码行加上断点就可以进行调试了
RTOS: 堆和栈_第1张图片
RTOS: 堆和栈_第2张图片
在调试过程中可以把对应变量添加到watch或者memory窗口进行查看
RTOS: 堆和栈_第3张图片
然后在单步运行的时候就可以看到对应的内存的变化,或者变量的变化了
RTOS: 堆和栈_第4张图片

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

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 */
}

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

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

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

对应代码在这里 cubeMx heap-stck

你可能感兴趣的:(RTOS,嵌入式,RTOS)