【FreeRTOS】估算栈的大小

news2024/11/16 6:03:04

参考《FreeRTOS入门与工程实践(基于DshanMCU-103).pdf》

目录

  • 估算栈的大小
    • 回顾
    • 简介
    • 计算说明
    • 估计函数用到的栈有多大
      • 合计


估算栈的大小

回顾

上一篇文章链接:http://t.csdnimg.cn/Cc8b4
传送门: 上一篇文章


上一篇文章创建的三个任务

  /* 创建任务:声 */
  // 先创建一个动态分配内存的任务
  ret = xTaskCreate(                //加返回值是 判断任务有没有创建成功
            PlayMusic,          //孤勇者的函数
            "SoundTask",        //声音任务
            128,                //栈大小
            NULL,               //无传入的参数
            osPriorityNormal,   //优先级默认
            & xSoundTaskHandle  //任务句柄
            );

  
  /* 创建任务:光 */ 
  // 创建一个静态分配内存的任务
  xLightTaskHandle = xTaskCreateStatic(
            Led_Test,           //LED测试函数,PC13以500ms间隔亮灭一次
            "LightTask",        //光任务
            128,                //栈大小,这里提供了栈的大小(长度)
            NULL,               //无传入的参数
            osPriorityNormal,   //优先级默认
            g_pucStackOfLightTask,  // 静态分配的栈,一个buffer,这里只提供了首地址,长度就是栈的大小,最开始栈的类型不对,栈的类型uint32_t
            &g_TCBofLightTask       // 取址TCB
  );
  


  /* 创建任务:色 */ 
  xColorTaskHandle = xTaskCreateStatic(
            ColorLED_Test,           //LED测试函数,PC13以500ms间隔亮灭一次
            "ColorTask",        //光任务
            128,                //栈大小,这里提供了栈的大小(长度)
            NULL,               //无传入的参数
            osPriorityNormal,   //优先级默认
            g_pucStackOfColorTask,  // 静态分配的栈,一个buffer,这里只提供了首地址,长度就是栈的大小
            &g_TCBofColorTask       // 取址TCB
  );


简介

上一篇文章的任务,要么是动态分配,分配指定大小的栈,要么提供一个数组,得告诉函数这个数组有多大

那么 — 栈的大小如何选取

栈里会保存什么

  1. 返回地址,其他寄存器Reg — 取决于函数调用深度(函数调用关系)
  2. 局部变量 — 取决char buf[x] ,数组的大小x
  3. 现场 - 16个寄存器,16*4=64byte

选取最复杂的调用关系

举个例子

函数A调用函数B,函数B调用函数C,函数C调用函数D,函数D调用函数E

  • 调用关系 A > B > C > D > E

每一级调用里,需要保存哪些寄存器?
去反汇编看一看

这里保存了4个寄存器

  • R2 R3 R4 LR

在这里插入图片描述

这里保存了4个寄存器

  • R4 R5 R6 LR
    在这里插入图片描述

这里保存了5个寄存器

  • R4 R5 R6 R7 LR
    在这里插入图片描述

理论上保存几个寄存器?最多能保存几个寄存器

在这里插入图片描述

理论上需要保存 R4~R11、LR这些寄存器,一共需要保存9个寄存器,称为被调用者寄存器


计算说明

  • 每一级函数都需要9*4=36字节来保存寄存器

  • 5级调用 * 9个寄存器 * 4字节

  • 调用深度越深,用到的栈越大

在这里插入图片描述

但是用到栈最大的情况,并不一定在最深的调用关系出现
如下图,A调用F,但是F函数里定义了一个巨大的布局变量
在这里插入图片描述

所以得看代码,找到使用局部变量最多的函数


估计函数用到的栈有多大

以音乐播放的任务为例子

调用关系
在这里插入图片描述

  • 局部变量 两个2字节的变量 = 4byte
    在这里插入图片描述

  • 4层调用

在这里插入图片描述

这个函数里定义了一个结构体

TIM_OC_InitTypeDef sConfig = { 0 };

在这里插入图片描述

调到结构体里,看看这个结构体有多大 7*4 = 28 byte

/**
  * @brief  TIM Output Compare Configuration Structure definition
  */
typedef struct
{
  uint32_t OCMode;        /*!< Specifies the TIM mode.
                               This parameter can be a value of @ref TIM_Output_Compare_and_PWM_modes */

  uint32_t Pulse;         /*!< Specifies the pulse value to be loaded into the Capture Compare Register.
                               This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */

  uint32_t OCPolarity;    /*!< Specifies the output polarity.
                               This parameter can be a value of @ref TIM_Output_Compare_Polarity */

  uint32_t OCNPolarity;   /*!< Specifies the complementary output polarity.
                               This parameter can be a value of @ref TIM_Output_Compare_N_Polarity
                               @note This parameter is valid only for timer instances supporting break feature. */

  uint32_t OCFastMode;    /*!< Specifies the Fast mode state.
                               This parameter can be a value of @ref TIM_Output_Fast_State
                               @note This parameter is valid only in PWM1 and PWM2 mode. */


  uint32_t OCIdleState;   /*!< Specifies the TIM Output Compare pin state during Idle state.
                               This parameter can be a value of @ref TIM_Output_Compare_Idle_State
                               @note This parameter is valid only for timer instances supporting break feature. */

  uint32_t OCNIdleState;  /*!< Specifies the TIM Output Compare pin state during Idle state.
                               This parameter can be a value of @ref TIM_Output_Compare_N_Idle_State
                               @note This parameter is valid only for timer instances supporting break feature. */
} TIM_OC_InitTypeDef;

任务要是切换出去的话要用到64字节


合计

在这里插入图片描述

估算栈大小 = 4层调用 + 局部变量 + 现场
= 4层调用 + 4 + 28 + 现场
= 4*36 + 32 +64
= 144+32+64
= 240 Byte

我们提供的栈是128个字,128*4 = 512 Byte

512大于240,这么估算栈的大小是够用的!

现在只是粗略的计算,后面会学习精确计算栈的大小的方法~

在这里插入图片描述

这节视频的链接:【FreeRTOS入门与工程实践 --由浅入深带你学习FreeRTOS(FreeRTOS教程 基于STM32,以实际项目为导向)】 【精准空降到 00:39】 https://www.bilibili.com/video/BV1Jw411i7Fz/?p=17&share_source=copy_web&vd_source=8af85e60c2df9af1f0fd23935753a933&t=39


参考文章:http://t.csdnimg.cn/MAJe7
参考文章:http://t.csdnimg.cn/YEwmm

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1839653.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

图像处理之几何变换

一、柱形畸变 import cv2 import numpy as npdef cylindrical_projection(image, f):h, w = image.shape[:2]map_x, map_y = np.meshgrid(np.arange(w), np.arange(h))x_c = w / 2y_c = h / 2theta = (map_x - x_c) / fh_c = (map_y - y_c) / np.sqrt((map_x - x_c)**2 + f**2…

音视频入门基础:H.264专题(3)——EBSP, RBSP和SODB

音视频入门基础&#xff1a;H.264专题系列文章&#xff1a; 音视频入门基础&#xff1a;H.264专题&#xff08;1&#xff09;——H.264官方文档下载 音视频入门基础&#xff1a;H.264专题&#xff08;2&#xff09;——使用FFmpeg命令生成H.264裸流文件 音视频入门基础&…

亚特全球链锯文化推广大使活动盛大启航

&#xff08;本台记者报&#xff09;链锯&#xff0c;这一象征着力量与技艺的工具&#xff0c;自诞生以来便见证了人类工业文明的进步。从最初的简易链锯到如今的多功能锂电链锯&#xff0c;彰显了人类对于技艺与科技的追求&#xff0c;其演变历程不仅映射出人类科技的巨大飞跃…

CSS3基本语法

文章目录 一、CSS引入方式二、选择器1、标签选择器2、类选择器3、id选择器4、通配符选择器 三、字体操作1、字体大小2、字体粗细3、字体样式&#xff08;是否倾斜&#xff09;4、字体修改常见字体系列 修改字体系列语法 四、文本操作1、文本缩进2、文本水平对齐方式3、文本修饰…

HarmonyOS Next 系列之从手机选择图片或拍照上传功能实现(五)

系列文章目录 HarmonyOS Next 系列之省市区弹窗选择器实现&#xff08;一&#xff09; HarmonyOS Next 系列之验证码输入组件实现&#xff08;二&#xff09; HarmonyOS Next 系列之底部标签栏TabBar实现&#xff08;三&#xff09; HarmonyOS Next 系列之HTTP请求封装和Token…

CobaltStrike后渗透进阶篇

0x01 网络钓鱼攻击 钓鱼攻击简介 钓鱼攻击主要通过生成的木马诱使受害者运行后上线&#xff0c;其中木马一般都伪装成正常的程序。与此同时配合钓鱼网站可帮助攻击者模拟真实网站诱骗受害者访问&#xff0c;达到获取账号密码、上线木马等目的。接下来主要介绍后门程序的生成及…

vue-json-viewer组件 copyable失效,页面并不现实copy按钮

<json-viewer :value"props.row.param_detail.query" :expand-depth"10" copyable> </json-viewer> 官方文档中&#xff0c;说明&#xff0c;只要在json-viewer中加入 copyable属性&#xff0c;即可实现copy功能&#xff0c;如下图&#xff1…

基于IDEA的Maven(properties属性配置)

&#xff08;property &#xff1a;财产&#xff09;properties&#xff1a;它的复数。 同样也是基于上篇博客进行学习。&#xff08;具体的全部项目代码和结构可以去查看上篇...&#xff09; <properties><!--当前jdk版本 , 这一步可以完全省略--><maven.com…

Swift开发——简单函数实例

函数是模块化编程的基本单位,将一组完成特定功能的代码“独立”地组成一个执行单位,称为函数。函数的基本结构如下所示: 其中,func为定义函数的关键字;“函数名”是调用函数的入口;每个函数可以有多个参数,即可以有多个“参数标签 参数名称:参数类型”,一般地,各个参…

CSS【详解】样式选择器的优先级(含提升优先级的方法)

数值越大&#xff0c;优先级越高&#xff0c;尽量保持较低的优先级&#xff0c;以便使用更高优先级的选择器重置样式 0级——通配选择器、选择符和逻辑组合伪类。逻辑组合伪类有:not()、:is()和:where等&#xff0c;这些伪类本身并不影响CSS优先级&#xff0c;影响优先级的是括…

【qt5生成软件-can卡-上位机-无法加载ControlCAN.dll错误代码(0xc0150002)等相关问题-WIN11系统-尝试解决】

【qt5生成软件-无法加载ControlCAN.dll&错误代码0xc0150002&#xff1a;-等相关问题-WIN11系统-尝试解决-总结整理】 1.前言2.环境说明3.问题说明4.尝试方法总结&#xff08;1&#xff09;更新支持包c库&#xff08;2&#xff09;更新USB相关驱动&#xff08;3&#xff09;…

valgrind工具的交叉编译及使用

一 概述 valgrind是一款非常好用的工具&#xff0c;用于检测内存泄漏等&#xff0c;这里讲述如何将其交叉编译到arm开发板及如何使用 【C/C 集成内存调试、内存泄漏检测和性能分析的工具 Valgrind 】Linux 下 Valgrind 工具的全面使用指南 - 知乎 (zhihu.com) valgrind: fai…

Word2Vec基本实践

系列文章目录 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 例如&#xff1a;第一章 Python 机器学习入门之pandas的使用 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目…

WPF三方UI库全局应用MessageBox样式(.NET6版本)

一、问题场景 使用HandyControl简写HC 作为基础UI组件库时&#xff0c;希望系统中所有的MessageBox 样式都使用HC的MessageBox&#xff0c;常规操作如下&#xff1a; 在对应的xxxx.cs 顶部使用using 指定特定类的命名空间。 using MessageBox HandyControl.Controls.Message…

Elasticseach RestClient Api

Elasticsearch RestclientApi基础用法 查询 索引库 初始化 添加依赖 <dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId> </dependency>创建链接 package com…

今日分享丨点亮这四个技能,你也可以成为可视化专家

引言 以大数据、人工智能等为代表的新质生产力时代已悄然而至&#xff0c;央企、国企逐步意识到数据资源展示对于经营管理的重要性和紧迫性。数据可视化成为连接用户与数据的桥梁&#xff0c;藉由设计师的巧手&#xff0c;把复杂抽象的数据以基于管理需求&#xff0c;转化为直…

PyTorch -- RNN 快速实践

RNN Layer torch.nn.RNN(input_size,hidden_size,num_layers,batch_first) input_size: 输入的编码维度hidden_size: 隐含层的维数num_layers: 隐含层的层数batch_first: True 指定输入的参数顺序为&#xff1a; x&#xff1a;[batch, seq_len, input_size]h0&#xff1a;[batc…

探究C语言函数栈帧的创建和销毁

引言 在C语言程序中&#xff0c;每当一个函数被调用时&#xff0c;系统都会在栈上为该函数分配一块内存空间&#xff0c;这块内存空间就被称为栈帧。 栈帧中包含了函数执行所需的所有信息&#xff0c;如局部变量、参数、返回地址等。栈帧的创建和销毁是函数调用的核心部分&am…

【华为HCIA数通网络工程师真题-数据通信与网络基础】

文章目录 选择题判断题 选择题 1、在 VRP 平台上&#xff0c;可以通过下面哪种方式访向上条历史命令&#xff1f; 上光标 &#xff08;ctrlU 为自定义快捷键&#xff0c;ctrlP 为显示历史缓存区的前一条命令&#xff0c;左光标为移动光标&#xff09; 2、主机 A &#xff08;1…