UCOS-II 任务栈空间合理分配
最近利用空闲时间跑了一下正点原子的stm32f4开发板的实时操作系统demo,发现了一个比较有意思的东西,分享如下:
硬件平台:正点原子stm32f4开发板
软件开发平台:MDK uVision v5.14.0.0
代码:正点原子官方例程 实验56 UCOSII实验1-2-任务创建删除挂起恢复
需要了解的基础知识:
1、会点亮LED灯
2、会读取按键输入
3、会操作串口
4、会RTOS基本知识
官方文档描述实验现象:首先下载代码之后可以看到 LED0 和 LED1 不断闪烁,同时蜂鸣器不
断鸣叫。这个时候我们按下 KEY0 之后 led_task 任务被挂起,我们可以看到 LED 不再闪烁。接
着我们按下 KEY2, led_task 任务重新恢复,可以看到 LED 恢复闪烁。然后我们按下 KEY_UP,
任务 beep_task 被删除,所以蜂鸣器不再鸣叫。这个时候我们再按下按键 KEY_DOWN,任务
beep_task 被重新创建,所以蜂鸣器恢复鸣叫。
一切工具准备就绪,烧录代码观察现象,神奇的bug出现了
首先,确实LED0 和 LED1 不断闪烁,但是一旦按下任意一个按键直接死机。
第一想法,分析代码,打印调试信息
测试现象:果然,按下按键后,所有用户任务停止运行了,可以初步得出结论:程序跑飞了(由于本例程未初始化看门狗,所以程序跑飞,就飞不回来了)
第二想法:调试
测试方法:进入调试模式后,run代码,点击stop,程序会停在正常的代码行,如停在用户代码区、内核代码区的正常逻辑区
进入调试模式后,run代码,按下按键,点击stop,会发现程序停在stm32f4xx_it.c这个文件的HardFault_Handler函数里,这是个死循环,就是这里导致程序跑飞了
cpu进入中断后一直执行死循环,回不来了,无法再进行任务切换了!可
以在这个中断函数里追加printf("HardFault_Handler\r\n");以观察现象如下:
串口助手打印的信息刚好验证了上述结论
整理思路如下:运行ucos ii 应用程序,按下按键后程序发生硬件错误,一般发生硬件错误,很可能就是跟内存有关,最典型的就是栈溢出了,
分析到这里,基本上排查bug就很easy了,检查代码各个任务栈大小发现:三个任务都是设置64字节,经过多次实验,发现只需把KEY_STK_SIZE设置
为大于64时,实验现象就正常了,说明再执行按键任务时,此任务堆栈大小超过64字节了。
#define KEY_TASK_PRIO 3
#define KEY_STK_SIZE 64
OS_STK KEY_TASK_STK[KEY_STK_SIZE];
void key_task(void *pdata);
那么当我们在编写任务函数时,到底栈大小设置多少合适呢?我怎么知道新建的任务运行起来用了多少栈空间呢?
若栈空间设置过大,无疑会导致空间的浪费,这在嵌入式产品中简直就是极其浪费
若栈空间过小,那真运行起来,搞不好某个时间点,栈空间就溢出了,这个时间点可能是一触即发,可能会一年后,甚至10年后
经过一顿百度操作,发现ucosii 系统早都给你设计好了,通过下面的函数即可统计指定任务运行时用了多少栈空间,还剩多少栈空间
OSTaskCreateExt(key_task,(void *)0,(OS_STK *)&KEY_TASK_STK[KEY_STK_SIZE-1],KEY_TASK_PRIO, KEY_TASK_PRIO, KEY_TASK_STK, KEY_STK_SIZE, (void*)0,OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
OSTaskStkChk(KEY_TASK_PRIO, &StackBytes);
printf("%d\r\n", StackBytes.OSUsed);
这也只是一种估测栈空间使用量,测试时,得模拟各种极端条件,尽量让最大使用量测出来
最后,一般堆栈大小设置为任务实际使用量的1.5-2倍即可
具体原理,大家可自行百度理解,也可以自己尝试手撕一波栈空间检测算法(栈基地址----栈顶地址)
UCOS-II 任务栈空间合理分配的更多相关文章
- Linux学习笔记4——函数调用栈空间的分配与释放
一.函数执行时使用栈空间作为自己的临时栈,3种方式决定编译器清空栈的方式:__stdcall. __fastcall.__cdecl 1.__stdcall表示每个调用者负责清空自己调用的函数的临时栈 ...
- java虚拟机 jvm 出入java栈 栈空间内存分配
java栈空间是一块线程私有的内存空间,java堆和程序数据密切相关,那么java栈就是和线程执行密切相关.线程最基本的执行行为就是函数的调用.每次函数调用其实是通过java栈传递数据的. 数据结构中 ...
- 更改Linux默认栈空间的大小
有时候在Linux写C++程序处理大量的数据,程序内部需要分配很大的数组来存放一些数据,但有时候分配的数组太大的话运行时会出现段错误.这种情况可能是分配的数组大小超过了Linux系统的默认栈空间的大小 ...
- DE1-SOC开发板上搭建NIOS II处理器运行UCOS II
DE1-SOC开发板上搭建NIOS II处理器运行UCOS II 今天在DE1-SOC的开发板上搭建NIOS II软核运行了UCOS II,整个开发过程比较繁琐,稍微有一步做的不对,就会导致整个过 ...
- (转)在.NET程序运行过程中,什么是堆,什么是栈?什么情况下会在堆(栈)上分配数据?它们有性能上的区别吗?“结构”对象可能分配在堆上吗?什么情况下会发生,有什么需要注意的吗?
转自:http://www.cnblogs.com/xiaoyao2011/archive/2011/09/09/2172427.html 在.NET程序运行过程中,什么是堆,什么是栈? 堆也就是托管 ...
- [转帖] Linux 下面栈空间大小的实验
比如局部变量是保存在栈空间中的,今天突然在想栈的上限是多大呢,什么时候才会栈溢出? ulimit 命令 linux下使用ulimit 命令可以查看系统的很多上限值. ulimit -a 查看所有 ul ...
- C语言中函数调用过程(如何管理栈空间)
ps:先做草稿,以后有时间再整理并贴图,:) 主要是利用栈底寄存器(ebp).栈顶寄存器(esp)跟eax寄存器(存储返回值)来实现. 假设P调用Q: P() { Q(1,2); } (跟实际情况可能 ...
- 0xC0000005;Access Violation(栈区空间很宝贵, linux上栈区空间默认为8M,vc6下默认栈空间大小为1M)
写C/C++程序最怕出现这样的提示了,还好是在调试环境下显示出来的,在非调试状态就直接崩溃退出. 从上述汇编代码发现在取内存地址 eax+38h 的值时出错, 那说明这个地址非法呗, 不能访问, 一般 ...
- 堆、栈、内存分配、==、equals、hashcode详解(转载)
问题的引入: 问题一:String str1 = "abc";String str2 = "abc";System.out.println(str1==str2 ...
- 《浏览器工作原理与实践》 <12>栈空间和堆空间:数据是如何存储的?
对于前端开发者来说,JavaScript 的内存机制是一个不被经常提及的概念 ,因此很容易被忽视.特别是一些非计算机专业的同学,对内存机制可能没有非常清晰的认识,甚至有些同学根本就不知道 JavaSc ...
随机推荐
- 认识流媒体协议,从 RTSP 协议解析开始!
RTSP 是 Internet 协议规范,是 TCP/IP 协议体系中的一个应用层协议级网络通信系统.专为娱乐(如音频和视频)和通信系统的使用,以控制流媒体服务器.该协议用于在端点之间建立和控制媒体会 ...
- 前端性能精进之浏览器(五)——JavaScript
JavaScript 是一种通过解释执行的高级编程语言,同时也是一门动态.弱类型的直译脚本语言,适合面向对象(基于原型)和函数式的编程风格. 直译语言可以直接在解释器中运行,而与直译语言相对应的编译语 ...
- Collection单列集合总结
这篇文章记录了Collection集合,List集合,Set集合 在文章第七点总结了两大系列集合的五种实现类的区别,有需要的小伙伴可以直接去查看 一.什么是集合 集合是Java中存储对象数据的一种容器 ...
- GIT 操作大全 基于廖雪峰
命令显示从最近到最远的提交日志 git log / git log --pretty=oneline 回退到上一个版本:$ git reset --hard HEAD^ (用HEAD表示当前版 ...
- python入门教程之五数据结构
变量 Python 变量类型 变量存储在内存中的值,这就意味着在创建变量时会在内存中开辟一个空间. 基于变量的数据类型,解释器会分配指定内存,并决定什么数据可以被存储在内存中. 因此,变量可以指定不同 ...
- [云计算]概念辨析:云计算 [IaaS/PaaS/SaaS & 公有云/私有云/混合云]
1 云计算(Cloud Computing) 1.0 云计算的发展 1.1 概念 "云"实质上就是一个[网络], 狭义上讲,云计算就是一种提供资源的网络,使用者可以随时获取&quo ...
- C# 通过一个控制台打开另一个控制台
现有个需求是通过一个主程序获取配置的线程数和进程数打开连一个控制台程序,将线程数和系统编码作为参数传给控制台程序. 下面附上Demo. 1 private static void Main(strin ...
- SpringBoot 整合 JDBC 实例
0.数据库表 CREATE DATABASE springboot; USE springboot; CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_ ...
- CSS笔记(待完善)
CSS笔记 css权重 ID(100)> class(10)> element(1) css最高权重 !important 块元素(block) 可以设置宽度和高度,独立成行. h1~h6 ...
- antv x6 神奇的图片边框
昨天才把html节点中的图片转成base格式的,今天就发现一个用户体验的问题:那么是啥呢?就是我从左侧的树形菜单中拖拽节点的时候(鼠标按下也是同样问题),发现节点的图片区域那里会出现一个边框,持续时间 ...