闲谈嵌入式的复杂性2
上次聊了一下嵌入式编程的复杂性,很多朋友们在我QQ上留言。很感谢大家,关于嵌入式编程的复杂性话题,还有很多内容,这里再和大家继续上次的话题随便说说。
嵌入式往往没有操作系统支撑,或者因为有操作系统支撑,但因为种种的限制,操作系统提供的功能少得可怜。所以,很多代码不能像PC编程那样天马行空,任意驰骋。今天就聊聊内存分配的问题,内存碎片,可能大家都不陌生。然而在嵌入式系统里,最怕的就是内存碎片,也是系统稳定的头号杀手。我曾经做了一个项目,系统中有很多的malloc和free,尺寸不一,从60多个字节到64KB的不等。使用一款RTOS作为支撑。当时我有两个选择,一个是使用C系统库的malloc和free,另外一个是使用操作系统提供的固定内存分配。我们系统的设计要求要能稳定运行3个月以上。实际上连续运行6天左右就宕机了。各种问题都怀疑过,最后定为在内存分配上,其实就是长时间,大量的内存分配后,系统的内存变得零散而无法连续。虽有大空间,但却无法分配连续的空间。当有大空间申请时,只能是宕机完蛋。为了使系统达到原先的设计需求,我们在PC机上模拟了整个硬件,将嵌入式代码在 PC机上跑起来,并重载了malloc和free,做了个复杂的统计程序。统计系统的内存行为。运行了若干天以后,将数据提取出来分析,虽然申请的内存5花八门,还是有些规律,我们把100个字节以下的归为一类,512B的归为一类,1KB的归为一类,2KB归为一类,64KB一下归为一类。统计出每类的数量,在原先的基础上加上30%的余量。做成固定内存申请,使得系统稳定连续运行的时间大大加长。嵌入式就这样,不怕方法原始,就怕性能不达要求。
内存溢出问题,内存溢出问题嵌入式系统比PC系统更可怕! 往往是没有察觉的就溢出了。都很难想到,尤其是C/C++的初学者,对指针不熟悉,查都没法查。由于PC系统有MMU,内存发生严重的越界时,有MMU的保护,不会产生严重的灾难后果。而嵌入式往往没有MMU,差别很大,系统代码都被破坏了还能跑。只是只有上帝和那个CPU才知道跑得是什么。我们来看看这段代码:
char *strcpy(char *dest, const char * src)
{
assert(dest != NULL && src != NULL);
while (*src != '\0')
{
*dest++ = *src++;
}
*dest = '\0';
return (dest);
}
这个代码是一个字符串拷贝的代码,PC机这样写,基本上就可以了。但嵌入式要提防一件事情,那就是 src真的以'\0'结束的。要不是得话,那就悲剧了。到什么时候能结束,呵呵,只有上帝老人家才知道。这段代码侥幸能跑完成的话,估计也别想程序能正常的跑了。因为dest指向的内存区域都被破坏的差不多了。为了和标准C/C++的库兼容,还真的没什么好办法,所以这个问题只能留给程序员自己检查。
相同的,
memcpy( dest, src, n);
内存拷贝同样的问题,要提防n传递个负值进去。这个是拷贝多少个字节,负值被强制类型转换成正的。变成一个很大的正数,造成dest之后的内存全部被破坏……
嵌入式里的内存指针必须做严格的检查才能使用,内存的尺寸也必须进行严格的调试。不然的话,悲剧是很难避免的。如一个函数指针,虽然在嵌入式里赋了个NULL,0。若是ARM的话,连个异常错误都没有,直接复位了,因为调用这个函数指针即便是让代码从0开始运行。而0是ARM上电后运行的第一条代码的位置。在ARM7上尤其如此。这种悲剧比PC上悲情多了,MMU 定然给一个无定义指令的错误。引起程序员的重视。在嵌入式里,全部都留给了程序员去寻找了。
内存溢出发生在任何一个不经意的时刻,你给整个前后台的系统(或操作系统)分配了多大的堆?多大的栈?在通常情况下系统的调用深度是多少(最大是多少),占用多少栈?光看程序的功能正确还不够,还需要统计这些参数。不然,只要有一个地方有溢出。对系统都是致命的。嵌入式系统要求系统连续工作时间长,稳定性可靠性要求苛刻。是需要一些时间仔细的磨这些系统的。
欢迎将您身边发生的嵌入式编程的复杂的例子给我。和我一起探讨嵌入式的复杂性。谢谢。
转载于:https://blog.51cto.com/coolbacon/1279951
闲谈嵌入式的复杂性2相关推荐
- 专访许雪松:深入理解嵌入式开发
许雪松,毕业于西北工业大学生物医学工程专业,现任必达测控技术总经理.15岁开始接触计算机编程,18岁学习C/C++编程,迄今已十多年有余,领导并参与大大小小几十个项目的开发及维护.涉及工业自动化.嵌入 ...
- 嵌入式开发:当用微控制器构建嵌入式GUI时,有哪些注意事项
在嵌入式开发中,借助基于MCU的设计,你可以消除额外的RAM和闪存芯片,并使用板载外设而不是板外逻辑,所有这些都将随着当今功能强大的芯片而变得更加简单.当然,与成熟的微处理器相比,MCU本身也提供了额 ...
- 电子工程师必备硬件知识
硬件知识 1.电源类 1.1 电源基础 各种"地"-- 各种"GND" 板载电源设计规范 电源环路稳定性评价方法 深入芯片内部,理解去耦电容的作用 减小DC ...
- 微控制器8位到32位变迁
1.1 概述 嵌入式领域的发展日新月异.你也许还没有注意到,但是如果你停下来想一想微控制器系统十年前的样子并与当今的微控制器系统比较一下,你会发现PCB设计.元件封装.集成度.时钟速度和内存大小已经经 ...
- 高薪都被谁拿走了?中国电子工程师薪酬调查大揭秘
一谈到高薪,任职于深圳一家著名手机设计公司的小Z就跳了起来,"现在房子.车子.女朋友--哪一个不得花钱?薪水绝对是我找工作的第一因素."或许是由于中国各大城市的生活成本不断上涨,我 ...
- 嵌入式Linux的OTA更新,基础知识和实现
嵌入式Linux的OTA更新,基础知识和实现 OTA updates for Embedded Linux, Fundamentals and implementation 更新的需要 一旦嵌入式Li ...
- 嵌入式开发在过去20年中是如何演变的
嵌入式开发在过去20年中是如何演变的 How embedded development has evolved over the past two decades 与任何开发领域一样,嵌入式系统开发就 ...
- 嵌入式C程序基础与编程结构
嵌入式C程序基础与编程结构 Basics of Embedded C Program and Programming Structure 嵌入式C编程是处理器在我们日常生活中遇到的每一个嵌入式系统(如 ...
- 嵌入式linux 升级,嵌入式Linux的OTA更新,基本原理和实现
需要更新 一旦嵌入式Linux产品离开实验室并进入现实世界,如何更新设备的问题就变得至关重要. 更新并非总是必要的,但是很难想到没有某个漏洞的软件.即使您的软件是完美的,但是如果设备通过任何开放源代码 ...
最新文章
- CSS3——对齐 组合选择符 伪类 伪元素 导航栏 下拉菜单
- Spring Aop的应用
- Canvas绘制星球轨迹移动
- 前端开发者如何利用 CSS 实现酷炫的变色方案?
- 按编译原理的思路设计的一个计算器
- 数据库水平切分的实现原理解析---分库,分表,主从,集群,负载均衡器(转)...
- 关于DIV+CSS和XHTML+CSS的理解
- 登录phpmyadmin提示: #1045 无法登录 MySQL 服务器
- 爬取糗事百科1到5页的图片并下载到本地
- 利用权限设置来阻止程序运行
- 计算机考研2017真题408,2017计算机408考研真题.pdf
- MATLABR2018自学一本通笔记
- HTML怎么使表格居中显示
- springcloud配置nacos,实现不同的环境使用不同的配置文件,不同的开发人员使用不同的配置文件
- matlab实现adf检验,ADF检验MATLAB程序资料
- 问题解决模型ORID
- 题解-[Usaco2005 Mar]Out of Hay 干草危机
- Mac 上简体中文输入方式的键盘快捷键
- Pycharm的安装并且连接已有的Python环境实现自由编译(附中文配置)|并通过Pycharm实现增加网站访问
- Kernel panic - not syncing: IO-APIC + timer doesn‘t work解决办法
热门文章
- python中x y表示_Python中表达式x += y和x = x+y 的区别详解
- 劳力士格林尼治价格_劳力士行情暴跌后回涨,什么时候才是入手的最佳时机?...
- 2021年春季学期-信号与系统-第八次作业参考答案-第五小题
- 第十六届智能车竞赛 | 单车拉力组浅析
- AD5272数字变阻器
- 白名单模板_亚马逊品牌备案常见问题—— 白名单、IP加速器及品牌备案后无法使用A+...
- css实现提示信息,单纯使用CSS实现动态提示信息
- gatdata获取曲线_GetData软件使用--获取曲线图中的数据
- html随机数游戏,js实现随机数小游戏
- python中的 2%s何意_python中的%s%是什么意思