当前位置:首页 > 公众号精选 > 嵌入式微处理器
[导读]01 首先聊一聊 大家都知道进行单片机编程和计算机编程有个最大的差别就是单片机的资源非常的有限,并且对于大部分低端单片机而言都没有操作系统。除了一些嵌入式级的芯片用了Linux系统外,其他大部分操作都是比较简单的RTOS,可能还有一些简单的应用或者芯片

01 首先聊一聊


大家都知道进行单片机编程和计算机编程有个最大的差别就是单片机的资源非常的有限,并且对于大部分低端单片机而言都没有操作系统。除了一些嵌入式级的芯片用了Linux系统外,其他大部分操作都是比较简单的RTOS,可能还有一些简单的应用或者芯片根本不用系统,直接是裸机程序。
不过,大部分单片机编程都与硬件密切的结合,这样工程师能够对当前的项目对象有更多的把控能力和理解能力。但是由于它的简单,我们平时在工作中往往需要控制一个项目的成本,对于单片机的选型和资源的评估都是非常谨慎;同样随着我们项目功能的不断扩展,也会让系统程序逐步变得庞大,这时候资源的使用就更需要节约点用了。
所以当资源受限制(一般的单片机RAM也就Kb级别),比如说单片机RAM不够了,即使你有再牛的算法可能也无法加入到项目中来,那么有些同志们会问,那换芯片不就可以了吗?我只想说这位同志你想多了,对于不怎么热卖产品或者不规范的公司可能还允许你试一试,可是一般的公司项目卡着走的,换了主控芯片,暂且不说软件上的移植工作,换了芯片成本上必定增加,产品的测试都得重新规划,老板领导可不愿意了。
那么主控芯片换不了我们还有什么办法呢?那我们应该从原本的程序中挤出资源来使用了,下面我总结了几种常总方法供大家参考。(具体内容可以网络查找)

02 共联体-union


union-共联体,是C语言常用得关键字。从字面上的意思就是共同联合在一起的意思,union所有的成员共同维护一段能够内存空间,其内存的大小取决于所有成员中占用空间最大的成员。
union结构体由于是共用同一片内存可以大大节省内存空间,那一般什么情况下使用union?又或者union还有什么特点?下面我将用几点为大家解答。
1)所有的union的成员及本身的地址是一样的。
2)union的存储模型受大小端的影响,我们可以通过下面的代码进行测试。(如果输出结果为1,表示小端模式,否则为大端模式)
大端模式(Big_endian):一个数据的高字节存储在低地址,低字节存储在高地址。其指针指向的首地址位于低地址。 小端模式(Little_endian):一个数据的高字节存储在高地址,低字节存储在低地址。其指针指向的首地址位于高地址。
3)union不同于结构体struct,union对成员的改变可能会影响到其他成员变量,所以我们要形成一种互斥使用,比如说我们的顺序执行其实就是每个代码都是互斥的,所以我们可以用union进行函数处理缓存等。(个人觉得也可以认为是分时复用,并且是不会受内存初值影响的处理)
#include typedef union _tag_test{ char a; int b;}uTest; uTest test;unsigned char Checktype(void); int main(void){ printf("%x\n",(unsigned int)&test.a); printf("%x\n",(unsigned int)&test.b); printf("%x\n",(unsigned int)&test); printf("%d\n",Checktype()); } unsigned char Checktype(void){ uTest chk; chk.b = 0x01; if(chk.a == 0x01)return 1; return 0; }

03 位域


位域可能对于初学者用得比较少,不过对于大部分参加工作的工程师应该屡见不鲜了,确实它也是我们省内存的神器。
因为在我们平时编程过程中,我们使用的变量与实际情况是息息相关的,就比如说开关的状态,我们一般就是0或者是1分别表示打开和关闭,那么我们用一个bit就能表示,假如说我们用一个char来存储就几乎浪费了7个bit,如果以后也有类似的的情况,那么大部分内存都得不到有效的应用。所以C语言的位域就是用来解决这个问题。
不过,我们需要注意如下几点:
1)位域是在结构体中实现的,其中位域规定的长度不能超过所定义类型,且一个位域只能定义在同一个存储单元中。
2)无名位域的使用,可以看下面的代码。
3)由于位域与数据类型有关系,那么他的内存占用情况也与平台的位数相关。(相关内容可网络查找)
#include//结果:编译通过//原因:常规形式(结构体占用两个字节)typedef struct _tag_test1{ char a:1; char b:1; char c:1; char d:6;}sTest1;//结果:编译无法通过//原因:d的位域长度10超过了char类型长度/*typedef struct _tag_test2{ char a:1; char b:1; char c:1; char d:10;}sTest2;*///结果:编译可通过//原因:下面使用无名位域,且占8个字节typedef struct _tag_test3{ int a:1; int b:1; int :0;//无名位域 int c:1;}sTest3;int main(void){ printf("%d\n",sizeof(sTest1)); printf("%d\n",sizeof(sTest3)); printf("欢迎关注公众号:最后一个bug\n"); }

		
		

04 结构体对齐


结构体对齐问题可能大部分人关注的不是很多,可能在通讯领域进行内存的copy时候接触得比较多。结构体对齐问题也是与平台相关,CPU为了提高访问内存的效率,一次性可能读取2个字节,4个字节,8个字节等,所以编译器会自动对结构体内存进行对齐。
废话不多说,代码说明一切:
#include#pragma pack(1)//有字节对齐预编译结果为:12,8//无字节对齐预编译结果为:6,6typedef struct _tag_test1{ char a; int b; char c; }STest1; typedef struct _tag_test2{ int b; char a; char c; }STest2; int main(void){ printf("%d\n",sizeof(STest1)); printf("%d\n",sizeof(STest2)); printf("欢迎关注公众号:最后一个bug\n"); }

05 算法优化


算法优化其实主要是我们通过修改一些算法的实现一种效率与内存使用的一个平衡,我们都知道我们的算法都存在着复杂度的问题,我们大部分高效率的算法都是通过使用内存来换效率,也就是一种用空间换时间的概念。那么当我们内存使用有限的时候我们可以适当的用时间来换空间的方法,腾出更多的空间来实现更多的功能。
同样,我们在进行相关设计的时候可以尽量使用局部变量来减少全局变量的使用!

06 利用const

1、const的使用
关于const的用法应该是老生常谈的知识点了,如果还有不是特别清楚的小伙伴可以参考< 一文搞定C语言const关键字 >一文,bug菌就不重复造轮子了,直接以stm32单片机为例看看const变量的的存储方式。
参考demo:
          
		
 #include "led.h" #include "delay.h" #include "usart.h"  #define DEV_NUM_MAX   (3) #define DEV_PARAM_MAX (2)  typedef struct _tag_DevParam{ char* Name; //设备名称 uint32_t Param[DEV_PARAM_MAX]; //设备参数}sDevParam;   const sDevParam stDevParam[DEV_NUM_MAX] = { {"Uart1",57600,0}, {"Uart2",57600,1}, {"CAN",1000000,0}, };/*************************************** * Fuction:const内存分配测试 * Author :bug菌  **************************************/ int main(void) { uint8_t t = 0; uint8_t devCnt = 0;  delay_init(); //延时函数初始化  uart_init(115200); //串口初始化  printf("\n*******************const Test*******************\r\n");  for(devCnt = 0 ;devCnt < DEV_NUM_MAX;devCnt++) { printf("DevName = %s,Param1 = %d,Param2 = %d\r\n",stDevParam[devCnt].Name,\ stDevParam[devCnt].Param[0],\ stDevParam[devCnt].Param[1]); } printf("stDevParam Size : %d \r\n",sizeof(stDevParam)); printf("stDevParam Addr : 0x%X \r\n",stDevParam); printf("\n***********欢迎关注公众号:最后一个bug************\n"); while(1) { delay_ms(10);  if(++t > 150){LED0=0;}else{LED0=1;} }  }

运行结果分析一下:
  • 对于stm32的所有存储映像都在对应工程所编译生成的.map文件中,对.map文件(其文件在工程目录中)的熟悉度就在一定程度上彰显你对stm32单片机的熟练程度。
  • 程序编译成功以后,就可以直接在map文件中查找const修饰的数组名。
  • 从上面我们了解到其stDevParam变量位置0x080016b8数据区且位于(.contdata段--只读数据段)并占用了36个字节,与我们串口输出结果是相符合的。

2、const数据的存储
通过上面的测试程序显示了const数据的存储位置,那么我们看一下该位置位于stm32的哪块存储区域,是RAM还是FLASH?
因为我们节省内存主要就是通过占用更小的RAM来实现相同的项目需求,那么对于MCU而言最好就是的借助Flash,通过时间来置换空间,拿出对应的数据手册看看这些存储范围是如何分配的。
上图来源于ST手册Memory Mapping
很明显前一节测试的const stDevParam变量位置0x080016b8处,正好处于FLASH存储位置,所以其并没有占用RAM资源。
3、const数据使用
很多写单片机程序的小伙伴都喜欢把一些只读的变量用全局变量来保存,然而这些变量基本上只保存一些参数,这对于单片机的RAM资源是非常浪费的。
bug菌曾经接手过一个前同事项目,怎么说呢?可能这个项目他也是接手别人的,该项目MCU还外部扩展了一个16M的SDRAM,大家都觉得反正RAM大,变量随便定,也不去管数据范围,动不动就float,double,真的是牛。
直到bug菌接手内存占用率已高达95%,后面稍微添加一些需求感觉RAM就要爆掉了,没办法这样下去终究会出问题,于是申请了代码重构,通过优化代码结构、设计等RAM占用率直接降到了50%左右,可以想象一下之前的开发人员是多么的任性。
所以,一句话说得好"前人栽树,后人乘凉;前人挖坑,后人入fen"。前面我们分析了stm32的const数据位于Flash上,一般Flash都会比RAM打上好几倍。
这样对于一些预先设置好的参数等等都可以整理以后统一放到类似于前面demo中这样的结构体数组中,从而可以大大减少对RAM的占用。
注意一点的是 : 访问RAM一般来说会比访问Flash要快一些,然而大部分项目对于这样的差异影响非常之小,后面bug菌会为大家再带来一篇文章讲讲这块的知识。

-END-


本文授权转载自最后一个bug,作者:bug菌




推荐阅读



【01】怎么学习单片机外围器件?

【02】漫画版:如何学习单片机?

【03】单片机:3种时钟电路方案对比,你常用哪一种?

【04】单片机编程技术学习攻略

【05】国产超低价单片机五宗罪!“扶不起”的原因就是它们?


免责声明:整理文章为传播相关技术,版权归原作者所有,如有侵权,请联系删除

免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

嵌入式ARM

扫描二维码,关注更多精彩内容

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭