嵌入式

大家是不是经常听到这几个词:嵌入式、单片机、STM32。你知道他们之间的关系吗?今天就来科普一下他们的基础概念和关系~

嵌入式

“嵌入式”的官方定义是用于控制、监视或者辅助操作机器和设备的装置。
专业的名词或许有点晦涩难懂,我们举个例子:

  • 个人通信和娱乐系统:手机、数码相机、音乐播放器、可穿戴电子设备、PSP 游戏机

  • 家电:数字电视、扫地机、智能家电

  • 办公自动化:打印机、复印机、传真机

  • 医疗电子产品:生化分析仪、血液分析仪、CT

  • 网络通讯产品:通讯类交换设备、网络设备(交换机、路由器、网络安全)

  • 汽车电子产品:发动机控制、安全系统、汽车导航和娱乐系统

  • 工控产品:工控机、交互终端(POS、ATM)、安防监控、数据采集传输、仪器仪表

  • 军用和航空产品:无人机、雷达、作战机器人上述所有领域都使用嵌入式系统。这只是冰山一角。

所以,通俗点来说,就是在其它电子产品设备中,加入(嵌入)一个小小的"计算机"。这个小小的"计算机",就是嵌入式系统。

通常我们会要求这个小小"计算机",体积小、功耗低、成本低、实时性强、可靠性高。这是个小小的"专用"的"计算机",不追求最高性能,适用就行。

麻雀虽小,五脏俱全,要求还很高!会飞!

所以,搞嵌入式系统,即要懂硬件,也要懂软件,还要懂通信。是电子、通信、计算机的融合。

以后要求更多,主要是人工智能方面的,叫边缘计算。

单片机

上面我们说到嵌入式是一个专用计算机系统,那么系统就应该有硬件和软件,单片机就是硬件部分。在很久以前的技术不发达,没有办法把所有功能做到一个芯片里,只能把功能放到一个个片机里面,这就是单片机。

1.jpg

省流版:单片机就是一个微型电脑,它是靠程序工作的,并且可以修改。通过不同的程序实现不同的功能。

我们常说的51单片机其实是一个系列,51单片机,兼容Intel 8031指令系统。他们的来源就是英特尔(Intel) 8004单片机,51单片机靠着库存基础和大众基础,一直占领着主流市场,但是毕竟这是比较老的技术,现在使用的人已经大幅度减少了,不过因为他的价格便宜,所以在一些低端产品上还在使用。

STM32

最后就是STM32,其实STM32也是单片机的一种,只不过属于进阶版,51单片机是8位的,STM32单片机是基于ARM Cortex M 处理器内核的 32位闪存微控制器,ST厂商提供了非常丰富的函数库,所以工程师在编写程序的时候可以直接调取对应功能的函数,特别方便。51单片机的运行速度慢,显然已经跟不上现在的产品的要求,所以现在比较智能的电子产品都选用运行速度更快的STM32,并且STM32的内部资源更多,接近于计算机的CPU,所以在程序编写上有更多的选择。

2.jpg

经过讲解,你明白嵌入式,单片机和STM32的关系了吗?至于在就业层面需要如何选择,还是要看各位小伙伴自己的个人偏好啦!

本文来源:网络转载、华清远见,

转载此文目的在于传递更多信息,版权归原作者所有。

免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 94

嵌入式设备在运行中需要设置参数,这个工作经常由PC机来实现,需要为双方通信设计协议,有代表性协议是如下三种:

“几种常见嵌入式设备通信协议"

从上表可以看到,一般嵌入式设备内存和运算性能都有限,因此,固定二进制是首选通信协议。

一. 简单性

保证协议是一个简单的方案,晦涩难懂往往意味着实现困难和容易出错。协议的结构宜采用平面方式,每个域作用明确,数据域尽可能设计得长度和位置固定,注释详尽,文档清晰,实例丰富,让人尽快上手和理解。

协议一般都需要以下域:帧头,长度,帧类型,目标地址,源地址,数据,校验,帧尾。

二. 可扩展

必须保证将来增加功能和更改硬件后协议仍能胜任工作,这往往是通过预留空间来实现,协议的变更应该只是量的增加,不至于引起协议结构的变化。

三. 低耦合

理想情况下每个协议包是原子信息,即本协议包不与其他协议包牵连,以防止通讯丢帧和设置牵连带来的错误。

四. 稳定性

协议包长度适宜:太小包含的信息过少,协议包的种类繁多,容易引起通讯混乱和牵连错误;太大包含的信息过多,可读性较差,组帧和解帧的工作困难,还会带来通讯易受干扰的缺陷,一般协议长度以最小原子性信息为标尺。

协议必须包括校验机制,以便于接收方判别协议包正确完整接收,如果出错需要较好的机制来确保通讯成功(如重传)。

五. 高效率

按信息类型区分协议包类别,如:设置网络信息参数,设置当前运行参数,可以区分开来,方便程序处理。

将同种操作编码为一个子集是一种高效手段,如Read操作,编码为0x0010,Write操作,编码为0x0020。

数据尽可能设计成同构模式,如果实在有差异,至少将同类型数据放置在一起,这样程序可以充分利用指针和线性寻址加速处理。

六. 易实现

尽量减少复杂算法的使用,如,通讯链路稳定,数据帧的校验码可以由CheckSum代替CRC。除非资源非常紧张,否则不要将过多的信息挤压在一个数据里,因为它会带来可读性差和实现困难。

七、软件开发

尽可能地让硬件ISR完成驱动工作,不要让“进程”参与复杂的时序逻辑,否则处理器将步履蹒跚且逻辑复杂!如:

接收固定长度的数据帧,可以使用DMA,每接收完一帧DMA_ISR向进程发消息。小心处理DMA断层异常(接收的数据帧长度正常但数据错误,数据为上帧的后半部分+本帧的前半部分)。

接收不定长的数据帧,可以使用状态机,当接收到“帧尾数据”时向进程发消息。小心数据紊乱和超时异常(数据紊乱时需要将状态机及时复位,超时一般使用定时器监控)。

八、考虑硬件

如果通信链路是高速总线(如SPORT可达100Mbps),一般设计成一帧产生一次中断,它通过长度触发的DMA来实现,需要将协议设计成固定长度,如附录A。它具备高效率,但灵活性较差。

如果通信链路是低速总线(如UART一般100kbps),一般接收一字节产生一次中断,可以将协议设计成变长帧,如附录B。它具备高灵活性,但效率较低。

“几种常见嵌入式设备通信协议"

上图显示了PC发送数据帧的格式,总长为64字节,是4字节的整倍数,符合绝大部分32位处理器结构体对齐的特性。

  • 0x3C:INT8U,帧头,可见字符’<’

  • Len:INT8U,本帧的总数据长度,在图4即为64

  • Dst:INT8U,标识目标设备的ID号

  • Src:INT8U,标识源设备的ID号

  • Data:56字节的存储区,内容依赖于具体的通信帧(实例见表2)

  • Cmd:INT16U,数据帧的类别

  • CS:INT8U, 对它前面所有数据(62字节)进行8位累加和校验

  • 0x7D:INT8U, 帧尾,可见字符’}’

Data域数据结构实例:

“几种常见嵌入式设备通信协议"

一个基于变长格式的UART通信协议实例:

“几种常见嵌入式设备通信协议"

PC与iWL880A(一种无线通信产品,详见www.rimelink.com)通信帧采用变长格式,如下图所示。大部分设备(常见为PC机)对于接收以“回车符”的机制很好处理,协议中的Tail就等于0x0D(换行符)。

来源:Microchip
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 108

参考地址:
https://www.designnews.com/design-software/5-best-practices-utilizing-open-source-software

嵌入式软件开发,现在相比以前方便多了,当你要实现一个项目需求,勤快一点基本上在网络上都能找到对应的资料,自己拿来修修改改也基本上能够实现大体的功能。

这或许就是开源的力量能够帮助很多开发者快速的进行现有软件资源的整合而为之所用,但这些软件和资源也存在优劣,一方面就是有开发者足够的能力把握这些软件,另一方面就是选择更加靠谱的开源组件来使用。

英文文章中描述了5点关于嵌入式开源软件的使用建议,这几点我相信是大部分嵌入式开发者都要考虑的,这里分享给大家:

正文(译文):

开源软件无处不在,有潜力帮助企业加快开发和提高软件质量。但如果不谨慎行事,它们可能是一个挑战。

下面是五个成功利用开源软件的最佳实践。

1、使用抽象层解决依赖关系

笔者审阅代码库时发现的一个常见问题是,开发人员将应用程序代码与使用的软件库紧耦合。

例如,如果一个开发人员正在使用FreeRTOS,那么应用程序代码调用特定于FreeRTOS API的方法是,如果开发人员决定更改RTOS,则必须重写大量代码来替换所有这些RTOS调用。

你可能会认为更改库是很少见的,但你会惊讶,经常是团队开始使用某个操作系统、库或组件后,而当他们决定需要进行更改时,却不得不返回并重写代码。

当团队选择一个开源组件,甚至是商业组件时,他们应该做的第一件事就是创建一个与该组件交互的抽象层。以RTOS为例,一个团队应该使用OS抽象层OSAL(它允许他们使用独立于OS的API编写应用程序代码)。

如果操作系统发生变化,应用程序不会在意,因为它正在访问一个抽象层,软件更改可能只需要几分钟而不是几天。

2、尽可能利用集成软件

大多数开源软件都是在自己的沙盒中编写的,而没有考虑到它可能需要与之交互的其他组件。组件通常使用不同的编码标准、样式、测试程度等编写。

当你开始将多个设计为不能相互协作的开源组件组合在一起时,可能会导致长时间的调试、头疼和错过最后期限。所以,尽可能选择已经集成并测试在一起的组件。

一个很好的例子是使用Amazon FreeRTOS连接AWS。FreeRTOS已经与连接到云所需的附加连接库进行了集成和测试,因此不要选择其他库,除非它也经过测试和集成。另一个例子是许多微控制器制造商生产的代码生成器工具。

这些工具通常已经集成了驱动程序软件组件、RTOS、文件系统、USB和其他一些组件。它们已经被证明可以协同工作,可以节省时间和金钱。

3、软件审核与质量分析

有很多优秀的开源软件,也有很多不太好的软件。在开发人员决定在项目中使用开源组件之前,他们需要确保他对软件进行尽职调查,或者雇佣别人做这件事。这包括花时间审核组件并执行质量分析。

在开始使用开源组件时,至少应检查源代码的以下方面:使用圈复杂度度量的复杂性、从功能上确保其满足业务需求和目标、遵守最佳实践和编码标准(根据需要)、处理错误的能力、可测试性。

这至少可以帮助开发人员了解他们正在使用什么,以及潜在的问题和陷阱。

4、从活跃设计中选择软件

通过快速的网络搜索或浏览github来找到解决问题的软件组件总是很诱人的。在选择一个开源组件时,确保其有一个活跃的社区是非常重要的。

这包括,在论坛上提问会得到快速的响应,新版本会定期发布,软件也会随着新功能的增加而不断改进。

选择一个不活跃的社区的组件会导致开发人员被迫自己解决问题,或者更糟的是,不得不维护组件。

5、由律师审查许可证

开源软件许可可能很复杂。有十几种不同的许可方案,对用户提出了不同的要求。

在某些情况下,开发人员可以使用他们认为合适的开源软件。在其他一些情况下,可以使用该软件,但任何其他软件也必须是开源的。

虽然这些许可证在最近几年变得更加容易理解,但是产品开发人员正在经营一项业务,因此有必要聘请一名律师来审查软件许可。

这是一项额外的开支,但这是成本的一部分,从长远来看可以节省开支。

6、最后

适当地利用开源软件可以使开发团队受益匪浅。然而,为了成功,开发人员需要确保明智地选择开源组件。这包括抽象出组件,以确保其应用程序保持灵活性和可维护性。

还需要仔细检查开源软件,以确保满足质量和一般要求。

遵循这些最佳实践可以帮助团队避免陷入导致产品延迟、解决方案架构不良的解决方案、质量问题以及产品开发过程中经常出现的许多其他问题的泥潭。

直接来源:最后一个bug
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 34

本文将介绍如何拆焊Flash芯片,设计及制作相应的分线板。了解对嵌入式设备的非易失性存储的简单有效攻击手段。这些攻击包括:

  • 读取存储芯片内容

  • 修改芯片内容

  • 监视对存储芯片的读取操作并远程修改(中间人攻击)

想想,当你拆开一个嵌入式产品,却被挡在Flash之外,好奇的你一定想对它一探究竟。

那么,下面我们就开始。

拆焊Flash芯片

为了读取Flash芯片的内容,有以下两个基本途径:

  • 直接将导线连接到 芯片的引脚

  • 把芯片拆下来,插到另一块板子上

下面介绍的Flash为BGA(球形栅格阵列)封装——无外露引脚。因此,只能选择拆焊的方法。

“图:目标芯片"
图:目标芯片

拆焊法的优点:

  • 可避免对电路板上其他器件造成影响;

  • 可以很容易看到芯片底部的布线;

  • 可用其他芯片或微控制器代替原芯片。

一些不便之处:

  • 电路在缺少完整器件的情况下无法运行;

  • 在拆卸过程中,一些邻近器件可能被损坏;

  • 如果操作不恰当,Flash本身可能毁坏。

OK,拆焊是吧?你看,下图所示的热风枪简直就是神器。只要将芯片周围加热,便可以很容易地拿下芯片:

“图:热风枪拆焊"
图:热风枪拆焊

这种办法简单、快速只是可能伤及无辜——焊掉邻近的元件,所以,务必小心翼翼。

下图显示芯片拆下后PCB的布线。观察图片,猜想底部的两列引脚为空引脚,因为他们压根就没接入电路。

“图:拆焊下来后"
图:拆焊下来后

用KiCAD定制分线板

现在该做什么?BGA封装简直就是一团糟,依然无法外接导线。

一种可行的方法是制作分线板。通常,分线板是将芯片的所有针脚的位置“镜像”下来,这样就能将芯片的引脚引接出来。

为此,我们首先要搜集芯片的相关信息。大多数情况下,芯片的型号都印制在芯片上,这样我们就很容易识别。如上图,芯片上第一行为MXIC代表Macronix International公司,第二行为芯片的具体型号MX25L3255EXCI datasheet 。以下为datasheet资料:

“图:针脚排布"
图:针脚排布

 PCB的设计可由KiCAD ,常用的EDA软件实现。

    分线板的设计过程与其他PCB板一样:

  • 新建电路板,画出电路简图,标明元器件的具体型号

  • 确定芯片的具体尺寸

根据之前datasheet的资料。我们添加1个4×6的网格作为整个芯片的BGA封装,2个1×4的网格作为连接芯片8个有效引脚的接线柱。最后一步是,用线路将这些器件连接起来:

“图:step2"
图:step2

转接板的设计到此为止,接下来是如何把设计转化成的PCB。

PCB制作

PCB就像是由两层铜和一层基板压制成的三明治,导线分布在铜上面。

根据制作流程,分为:

  • 蚀刻法

  • 数控铣法

以下为两种方法的具体步骤。

蚀刻法

蚀刻,即是用化学药品逐步除去铜的过程。我们先用油墨保护覆铜板上的线路及要保留下来的铜。

1、首先,用热转印法制作PCB。PCB电路图用激光打印机打印在亮光纸上。然后,把亮光纸紧贴在覆铜板上,加热和施以压力,使亮光纸上的电路图转印到覆铜板上。通常,这个过程用熨衣服的熨斗即可完成,但是专用的压制器会使加热及受力更加均匀,更容易成功。

2、接下来是蚀刻,将整块PCB板浸没在腐蚀液,以此来去除多余的铜。

蚀刻后的分线板,转印的墨粉还附着在上面:

“图:step3"
图:step3

除去墨粉后:

“图:step4"
图:step4

现在可以准备手工焊接了。微型焊接与正常焊接一样,只是器件的尺寸极小,因此需要借助显微镜。

此外,传统的焊接用的是线状的焊锡丝,而BGA微型焊接用的是锡球。

“图:step5"
图:step5

接下来,开始重整锡球:

  • 将一个新的锡球放置在凹槽上,加热,熔化锡球;

  • 校准芯片和板子;

  • 回流。

“图:step6"
图:step6

锡球重整完成:

“图:step7"
图:step7

芯片焊接完成后的最终结果:

“图:step8"
图:step8

数控铣

作为替代方法,数控铣仅是将需要的线路和剩余的铜隔离开来而已。

(1)5X5的BGA通常用于制作 PCB,而4X6的常用于分线板。我们设计5X5的是为了该分线板可以直接插接在通用EEPROM 编程器的ZIF插槽里,电路简图如下:

“图:step9"
图:step9

(2)芯片的尺寸与前面设计的4X6的一样,只是网格变成5X5,板上的布线也稍显复杂:

“图:step10"
图:step10

(3)由于KiCAD无法直接生成与数控铣兼容的目标文件,因此,我们用Flatcam接收Gerber文件并确定数控铣隔离的导线的路径:

“图:step11"
图:step11

“图:step12"
图:step12

(4)接下来将生成的STL文件导入bCNC——数控铣的终端控制程序,如下图所示:

“图:step13"
图:step13

雕刻过程中:

“图:step14"
图:step14

(5)板子雕刻完成:

“图:step15"
图:step15

最终结果:

“图:step16"
图:step16

(6)下一步,涂覆阻焊层,保护铜不被氧化,并用紫外灯固化:

“图:step17"
图:step17

“图:step18"
图:step18

(7)阻焊层覆盖了BGA的铜片及1X4的接线柱,我们得刮掉这个薄层,使铜片露出来:

“图:step19"
图:step19

(8)给各个节点焊锡:

“图:step20"
图:step20

“图:step21"
图:step21

(9)回到数控铣,打孔,切削PCB的边缘:

“图:step22"
图:step22

“图:step23"
图:step23

(10)最终成品,BGA焊接在板子上,准备插到EEPROM编程器上:

“图:step24"
图:step24

结论

了解了如何拆焊Flash芯片和如何设计PCB,以及制作PCB的两种不同方法。

来源:STM32嵌入式开发
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 107

前言

随着单片机的发展,单片机在家用电器、工业自动化、生产过程控制、智能仪器仪表等领域的应用越来越广泛。

然而处于同一电力系统中的各种电气设备通过电或磁的联系彼此紧密相连,相互影响,由于运行方式的改变,故障,开关操作等引起的电磁振荡会波及很多电气设备。

这对我们单片机系统的可靠性与安全性构成了极大的威胁。单片机测控系统必须长期稳定、可靠运行,否则将导致控制误差加大,严重时会使系统失灵,甚至造成巨大损失。

因此单片机的抗干扰问题已经成为不容忽视的问题。

1、干扰对单片机应用系统的影响

1.1、测量数据误差加大

干扰侵入单片机系统测量单元模拟信号的输入通道,叠加在测量信号上,会使数据采集误差加大。特别是检测一些微弱信号,干扰信号甚至淹没测量信号。

1.2、控制系统失灵

单片机输出的控制信号通常依赖于某些条件的状态输入信号和对这些信号的逻辑处理结果。若这些输入的状态信号受到干扰,引入虚假状态信息,将导致输出控制误差加大,甚至控制失灵。

1.3、影响单片机RAM存储器和E2PROM等

在单片机系统中,程序及表格、数据存在程序存储器EPROM或FLASH中,避免了这些数据受干扰破坏。但是,对于片内RAM、外扩RAM、E2PROM 中的数据都有可能受到外界干扰而变化。

1.4、程序运行失常

外界的干扰有时导致机器频繁复位而影响程序的正常运行。若外界干扰导致单片机程序计数器PC值的改变,则破坏了程序的正常运行。

由于受干扰后的PC 值是随机的,程序将执行一系列毫无意义的指令,最后进入“死循环”,这将使输出严重混乱或死机。

2、如何提高我们设备的抗干扰能力

2.1、解决来自电源端的干扰

单片机系统中的各个单元都需要使用直流电源,而直流电源一般是市电电网的交流电经过变压、整流、滤波、稳压后产生的,因此电源上的各种干扰便会引入系统。

“提升嵌入式产品设计的10个细节问题"

除此之外,由于交流电源共用,各电子设备之间通过电源也会产生相互干扰,因此抑制电源干扰尤其重要。电源干扰主要有以下几类:

2.1.1、电源线中的高频干扰(传导骚扰)

供电电力线相当于一个接受天线,能把雷电、电弧、广播电台等辐射的高频干扰信号通过电源变压器初级耦合到次级,形成对单片机系统的干扰;

解决这种干扰,一般通过接口防护;在接口增加滤波器、或者使用隔离电源模块解决。

2.1.2、感性负载产生的瞬变噪音(EFT)

切断大容量感性负载时,能产生很大的电流和电压变化率,从而形成瞬变噪音干扰,成为电磁干扰的主要形式;

解决这种干扰,一般通过屏蔽线与双胶线,或在电源接口、信号接口进行滤波处理。

这二种方法都需要在系统接地良好的情况下进行,滤波器、接口滤波电路都必须良好的接地,这样才能有效的将干扰泄放。

2.2、模拟信号采样抗干扰技术

单片机应用系统中通常要对一个或多个模拟信号进行采样,并将其通过A/D转换成数字信号进行处理。

为了提高测量精度和稳定性;

1)要保证传感器本身的转换精度;
2)传感器供电电源的稳定;
3)测量放大器的稳定;
4)A/D转换基准电压的稳定;
5)要防止外部电磁感应噪声的影响;

如果处理不当,微弱的有用信号可能完全被无用的噪音信号淹没。

在实际工作中,可以采用具有差动输入的测量放大器,采用屏蔽双胶线传输测量信号,或将电压信号改变为电流信号,以及采用阻容滤波等技术。

“提升嵌入式产品设计的10个细节问题"

2.3、数字信号传输通道的抗干扰技术

数字输出信号可作为系统被控设备的驱动信号(如继电器等),数字输入信号可作为设备的响应回答和指令信号(如行程开关、启动按钮等)。

数字信号接口部分是外界干扰进入单片机系统的主要通道之一。

在工程设计中,对数字信号的输入/输出过程采取的抗干扰措施有:

1)传输线的屏蔽技术,如采用屏蔽线、双胶线等;
2)采用信号隔离措施;
3)合理接地,由于数字信号在电平转换过程中形成公共阻抗干扰,选择合适的接地点可以有效抑制地线噪声。

2.4、硬件监控电路

在单片机系统中,为了保证系统可靠、稳定地运行,增强抗干扰能力,需要配置硬件监控电路,硬件监控电路从功能上包括以下几个方面:

1)上电复位:保证系统加电时能正确地启动;
2)掉电复位:当电源失效或电压降到某一电压值以下时,产生复位信号对系统进行复位;
3)电源监测:供电电压出现异常时,给出报警指示信号或中断请求信号;

硬件看门狗:当处理器遇到干扰或程序运行混乱产生“死锁”时,对系统进行复位。

2.5、PCB电路合理布线

PCB板设计的好坏对抗干扰能力影响很大。因此,在进行PCB 设计时,必须遵守PCB 设计的一般原则,并应符合抗干扰设计的要求。下面着重说明两点:

2.5.1、关键器件放置

在器件布置方面与其它逻辑电路一样,应把相互有关的器件尽量放得靠近些,这样可以获得较好的抗噪声效果。

1)时钟发生器、晶振和CPU 的时钟输入端都易产生噪声,要相互靠近些;
2)CPU 复位电路、硬件看门狗电路要尽量靠近CPU相应引脚;
3)易产生噪声的器件、大电流电路等应尽量远离逻辑电路。

“提升嵌入式产品设计的10个细节问题"

2.5.2、D/A、A/D 转换电路地线的正确连接

D/A、A/D 芯片及采样芯片均提供了数字地和模拟地,分别有相应的管脚。

在线路设计中,必须将所有器件的数字地和模拟地分别相连,但数字地与模拟地仅在一点上相连。另外,也可以采用屏蔽保护,屏蔽可用来隔离空间辐射。

对噪声特别大的部件(如变频电源、开关电源)可以用金属盒罩起来以减少噪声源对单片机的干扰,对容易受干扰的部分,可以增加屏蔽罩并接地,使干扰信号被短路接地。

“提升嵌入式产品设计的10个细节问题"

12.6、软件抗干扰原理及方法

尽管我们采取了硬件抗干扰措施,但由于干扰信号产生的原因错综复杂,且具有很大的随机性,很难保证系统完全不受干扰。

因此,往往在硬件抗干扰措施的基础上,采取软件抗干扰技术加以补充,作为硬件措施的辅助手段。软件抗干扰方法具有简单、灵活方便、耗费低等特点,在系统中被广泛应用。

2.6.1、数字滤波方法

数字滤波是在对模拟信号多次采样的基础上,通过软件算法提取最逼近真值数据的过程。数字滤波的的算法灵活,可选择权限参数,其效果往往是硬件滤波电路无法达到的。

2.6.2、输入信号重复检测方法

输入信号的干扰是叠加在有效电平信号上的一系列离散尖脉冲,作用时间很短。

当控制系统存在输入干扰,又不能用硬件加以有效抑制时,可用软件重复检测的方法,达到“去伪存真”的目的,直到连续两次或连续两次以上的采集结果完全一致时方为有效。

若信号总是变化不定,在达到最高次数限额时,则可给出报警信号。对于来自各类开关型传感器的信号,如限位开关、行程开关、操作按钮等,都可采用这种输入方式。

如果在连续采集数据之间插入延时,则能够对付较宽的干扰。

2.6.3、输出端口数据刷新方法

开关量输出软件抗干扰设计,主要是采取重复输出的方法,这是一种提高输出接口抗干扰性能的有效措施。对于那些用锁存器输出的控制信号,这些措施很有必要。

在尽可能短的周期内,将数据重复输出,受干扰影响的设备在还没有来得及响应时,正确的信息又到来,这样就可以及时防止误动作的产生。在程序结构的安排上,可为输出数据建立一个数据缓冲区,在程序的周期性循环体内将数据输出。

对于增量控制型设备不能这样重复送数,只有通过检测通道,从设备的反馈信息中判断数据传输的正确与否。在执行重复输出功能时,对于可编程接口芯片,工作方式控制字与输出状态字一并重复设置,使输出模块可靠地工作。

2.6.4、软件拦截技术

当窜入单片机系统的干扰作用在CPU 部位时,后果更加严重,将使系统失灵。

最典型的故障是破坏程序计数器PC 的状态,导致程序从一个区域跳转到另一个区域,或者程序在地址空间内“乱飞”,或者陷入“死循环”。

使用软件拦截技术可以拦截“乱飞”的程序或者使程序摆脱“死循环”,并将运行程序纳入正轨,转到指定的程序入口。

2.6.5、“软件看门狗”技术

PC 受到干扰而失控,引起程序“乱飞”,也可能使程序陷入“死循环”。当软件拦截技术不能使失控的程序摆脱“死循环”的困境时,通常采用程序监视技术WDT TIMER(WDT),又称看门狗技术,使程序脱离“死循环”。

WDT 是一种软、硬件结合的抗程序跑飞措施,其硬件主体是一个用于产生定时T 的计数器或单稳,该计数器或单稳基本独立运行,其定时输出端接至CPU 的复位线,而其定时清零则由CPU 控制。

在正常情况下,程序启动WDT 后,CPU 周期性的将WDT 清零,这样WDT 的定时溢出就不会发生,如同睡眠一般不起任何作用。在受到干扰的异常情况下,CPU 时序逻辑被破坏,程序执行混乱,不可能周期性的将WDT 清零,这样当WDT 的定时溢出时,其输出使系统复位,避免CPU因一时干扰而陷入瘫痪的状态。

3、总结

随着单片机系统的广泛应用和技术的进步,电磁干扰问题越来越突出,推广现有的、成熟的抗干扰技术,研究抗干扰的新技术、新方向是单片机应用技术的当务之急。在单片机应用系统设计及应用中,只要充分考虑设备的电磁兼容性,并通过各种技术措施来消除干扰,就可以大大提高设备的稳定性和可靠性。

转载来源:嵌入式Linux(陈翀 珠海格力电器股份有限公司;张建勇 中智经济技术合作公司)
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 22

瑞萨32位RA、RX产品家族和Synergy平台MCU客户均可获得免费wolfSSL标准商用许可,用于使用wolfCrypt加密库的TLS协议栈

瑞萨电子集团(TSE:6723)和嵌入式安全解决方案供应商wolfSSL今日宣布,推出一项长期许可协议——使用瑞萨32位MCU产品的客户可以获得wolfSSL TLS(传输层安全)协议栈的免费商用许可。瑞萨RA产品家族、RX产品家族和Synergy平台MCU的客户均有资格获得这一商用许可,许可中还包括wolfSSL的技术支持。

“瑞萨电子与wolfSSL联手打造基于嵌入式TLS协议栈的即用型物联网安全解决方案"

TLS是保护互联网通信安全的世界性标准。基于瑞萨TSIP(可信安全IP)和SCE(安全加密引擎)等经过认证的集成硬件安全引擎构建的TLS解决方案,为安全物联网产品提供卓越解决方案。用ANSI C语言编写的wolfSSL嵌入式TLS协议栈是一种轻量级TLS解决方案,具有小代码尺寸、高运行速度和多功能等优势,主要针对嵌入式系统、RTOS和资源受限的环境。wolfSSL支持目前TLS 1.3和DTLS 1.2级别的行业标准,代码量小于OpenSSL的1/20。除了与瑞萨MCU硬件安全引擎完全集成外,wolfSSL还提供已通过FIPS 140-2一级认证的wolfCrypt轻量级密码库。此外,wolfCrypt还支持目前最流行的算法、密码,以及演进中的前沿技术,如通过Open Quantum Safe项目库的抗量子密钥交换。

保密性是MCU客户关注的一个关键因素,特别是在快速增长的物联网市场。瑞萨凭借广泛的解决方案和认证确立了安全加密领域的重要地位。今年早些时候,瑞萨宣布RX65N获得FIPS 140-2三级认证,该产品也成为通过此类认证的首批通用型MCU之一。基于Arm® Cortex®-M核心的RA产品家族MCU已通过PSA二级认证和物联网平台安全评估标准(SESIP)认证,并正在筹备NIST认证。瑞萨MCU产品为加密运算提供保护,具备抵抗计时和SPA/DPA等侧信道攻击的能力;其所有产品家族均支持无限的安全密钥存储功能,其中RA产品家族提供简化的安全密钥安装。

瑞萨电子物联网及基础设施事业本部高级副总裁Roger Wendelken表示:“作为先进的MCU供应商,能够为客户创造附加价值让我们倍感自豪。除了瑞萨产品中内置的诸多安全加密功能外,免费提供高质量wolfSSL TLS和加密软件的商用许可也是贯彻这一理念的例证。”

wolfSSL CEO Larry Stefonic表示:“瑞萨与我们一样对安全加密技术充满热情。我们很高兴看到瑞萨庞大的MCU客户群现在可以轻松且不受限地使用我们先进的加密软件,以实现优化、新型安全功能。瑞萨让客户以更少付出获得更大收益;这无疑是优秀MCU供应商的使命。”

供货信息

瑞萨32位MCU客户可访问:https://github.com/wolfssl/Renesas,下载WolfSSL TLS协议栈,以及wolfCrypt加密库。

关于wolfSSL

wolfSSL专注于打造轻量级和嵌入式安全解决方案,强调速度、尺寸、便携性、功能性和标准合规性;双重授权满足了从爱好者到商用用户的多样性需求。我们很荣幸能够以一切可能的方式帮助我们的客户和社区。我们的开源产品让客户可以自由探索产品内部架构;我们的wolfSSL嵌入式TLS库是世界首个TLS 1.3商用版本。有关wolfSSL产品的更多信息,请访问:www.wolfSSL.com

关于瑞萨电子集团

瑞萨电子集团 (TSE: 6723) ,提供专业可信的创新嵌入式设计和完整的半导体解决方案,旨在通过使用其产品的数十亿联网智能设备改善人们的工作和生活方式。作为全球微控制器、模拟、电源和SoC产品供应商,瑞萨电子为汽车、工业、家居、基础设施及物联网等各种应用提供综合解决方案,期待与您携手共创无限未来。更多信息,敬请访问renesas.com

来源:瑞萨电子
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 28

以前的嵌入式系统对安全问题相对不那么重视,但随着时间的推移,你会发现很多嵌入式设备都在做各种“保护措施”,你平时在产品开发和设计时,有注意安全问题吗?

嵌入式系统12种常见攻击

嵌入式系统的攻击可根据其目标分为三类:

  • 基于软件的攻击

  • 基于网络的攻击

  • 旁道攻击

“嵌入式系统12种常见攻击及防范方法"

让我们找出针对这些类型攻击的关键特征,常见示例以及可能的对策。

第一类:基于软件的攻击

基于软件的攻击针对系统的大脑-管理设备的应用程序。对软件的成功攻击使黑客能够访问数据或获得对嵌入式系统的控制。

搜索软件设计和代码中的漏洞是最常见的攻击手段,因为可以远程进行此类攻击。而且,基于软件的攻击不需要黑客的专业知识,因为他们可以使用典型的攻击,例如部署恶意软件和暴力破解。

最普遍的基于软件的攻击包括:

· 恶意软件

· 暴力访问

· 内存缓冲区溢出

· 利用web服务

对嵌入式系统的恶意软件攻击与任何其他系统的工作方式相同:黑客部署了一段恶意代码,这些代码试图拦截存储在系统内部的数据,控制受害系统或对其进行破坏。通常,黑客会伪造固件更新,驱动程序或安全补丁来分发恶意软件。

为了防止此类攻击,可以实施以下保护措施:

  • 应用黑名单方法,即开发人员为系统检测到的任何新恶意软件创建签名,并将这些签名添加到嵌入式系统固件中。当系统检测到具有已知签名的软件时,它将不会运行它。

  • 使用白名单保护,为所有受信任的软件源创建特定的签名。这允许系统只运行具有正确签名的软件。

简单地说,强制访问凭证就是猜测凭证的过程。大多数嵌入式系统提供对图形用户界面(GUI)的远程访问,黑客可以利用该界面进行攻击。你可以通过使用强密码和限制登录尝试次数来防止暴力强制攻击。

内存缓冲区溢出是一种攻击,当黑客手动溢出分配给包含在嵌入式系统中移动的数据的内存缓冲区时。黑客部署的漏洞攻击使内存缓冲区充满了过多的数据。在这种情况下,嵌入式操作系统将把其中的一些数据记录到缓冲区旁边的内存段中。记录的数据可能包含外壳代码或其他漏洞,帮助黑客获取凭据并提升其访问权限。

通过创建一个沙箱将溢出的数据与系统隔离,可以解决此问题。请记住,你的沙箱必须非常复杂,因为许多现代漏洞利用了躲避沙箱的技术。

第2类:基于网络的攻击

这种攻击利用网络基础设施漏洞,也可以远程执行。利用这些漏洞,黑客可以侦听、拦截和修改嵌入式系统传输的流量。

让我们看一下最常见的基于网络的攻击:

· 中间人(MITM)

· 域名系统(DNS)中毒

· 分布式拒绝服务(DDoS)

· 会话劫持

· 信号干扰

MITM攻击用于拦截或更改嵌入式系统传输的数据。为了执行它,黑客改变两个设备的连接参数,以便在它们之间放置第三个设备。如果黑客可以获得或更改这两个设备使用的加密密钥,他们就可以以一种很难检测到的方式进行窃听,因为这不会对网络造成干扰。

通过加密传输的数据并使用Internet协议安全(IPsec)安全地传输密钥和数据,可以防止或阻止MITM攻击。

DNS中毒会迫使本地DNS服务器根据黑客的需求修改其记录。DNS服务器将可记忆的域名和主机名转换为相应的IP地址。通过使用DNS服务器的漏洞并毒害其缓存,黑客可以将流量从目标网站重新路由到任何其他地址。

域名系统安全扩展(DNS-SEC)协议通过对DNS发布或传输的任何数据进行数字签名来防止DNS服务器中毒。

DDoS是一种众所周知的攻击,它通过来自不同来源的请求使系统溢出从而使系统不可用。这种攻击很难阻止,因为请求量巨大。没有针对DDoS攻击的通用保护。但是,在你的嵌入式软件中添加防火墙以及流量分析和过滤算法将大大提高防止DDoS攻击或及时检测它们的机会。

会话劫持类似于MITM攻击,但目标不同:黑客侦听嵌入式系统流量以获取身份验证凭据。执行劫持的方法有多种:固定用户会话标识符,窃取会话缓存,跨站点脚本等等。

防范此类攻击的方法很经典:对凭据和可能包含凭据的任何数据进行加密,定期更改凭据,以及在会话结束时处置与会话相关的任何数据。

信号干扰在无线网络中很常见。借助这种技术,黑客会在网络中造成干扰,从而干扰或扭曲来自设备的通信。根据干扰器的类型,它可能会阻塞信道上的任何通信,在目标设备传输数据时开始工作,或者在检测到特定数据包时被激活。这样的攻击会使嵌入式系统不可用。

要停止信号干扰,请部署适合你软件的抗干扰机制 [PDF]。请记住,此保护措施还将保护你的嵌入式系统免受其他设备造成的意外干扰。

第3类:旁道攻击

旁道攻击是利用嵌入式系统中的硬件安全缺陷来攻击它们。旁道攻击是最困难和最昂贵的攻击类型,因为它需要精确了解目标系统的硬件设计和物理可用性。为了进行侧信道攻击,黑客收集系统功耗、电磁泄漏、操作时间等信息。

因此,他们可以计算出系统和连接设备的内部操作,窃取密码密钥,甚至获得对系统的控制权。

以下是最常见的旁道攻击列表:

· 功率分析

· 定时攻击

· 电磁分析

功耗分析攻击需要对嵌入式系统进行物理访问,以便探测其连接并检测功耗的变化。这些变化取决于系统处理的数据,因此黑客可以检测到系统何时处理特定类型的信息并截获它。要防止此攻击,请使用数据屏蔽技术修改敏感内容,使其看起来像不重要的数据。

定时攻击是基于嵌入式系统操作的时间。它们用于获取信息,如应用的加密算法、指令时间和代码分支中的数据依赖差异、缓存访问时间等等。这种类型的攻击还需要对设备进行物理访问和对嵌入式系统架构的深入了解。

由于定时攻击强烈依赖于线性和可预测的软件操作,你可以通过使用随机数对空闲周期中的活动进行重新安排来防止此类攻击。基于此对嵌入式系统的时序分析将具有极大的挑战性。

电磁分析为黑客提供了另一种无需黑客攻击就能查看嵌入式软件的方法。黑客可以使用电磁分析来记录和分析设备的发射,找出其加密操作,甚至提取秘密

密钥。这是最耗时且成本最高的攻击类型,因为它需要:

· 物理上接近嵌入式系统

· 有关系统嵌入到的设备的布局的信息

· 与其他设备隔离以保护系统免受电磁干扰

硬件设计师可以通过降低信号强度或增加物理保护(例如使用某些类型的胶水或电路和电线屏蔽)来使收集电磁信号变得困难。随机性和加密过程的中断也是对抗电磁分析的有效措施。

我们上面讨论的嵌入式系统的网络安全措施可以帮助你预防或阻止特定类型的攻击。在下一部分中,我们提供了11条建议来有效保护嵌入式硬件和软件。

保护嵌入式系统的11个最佳实践

在开始编码之前,请研究嵌入式软件开发的行业标准,以发现有效的安全措施和开发实践。

例如,注意:
· OWASP嵌入式应用程序安全性
· IEEE标准
· NIST 为物联网设备制造商提供的基础网络安全活动 [PDF]
· IPA的嵌入式系统开发过程参考指南 [PDF]

通过以下实践,你可以在从设计到支持的所有开发阶段使你的保护更加可靠:

“嵌入式系统12种常见攻击及防范方法"

提高嵌入式系统安全性的11个最佳实践。

第一类:设计和软件配置

1.使用安全的语言。在编写第一行代码之前,请针对你选择的语言研究嵌入式软件开发标准。例如,如果你要使用C或C ++,请首先学习MISRA-C / C ++。

2.启用安全启动。此功能允许微处理器在执行固件之前验证加密密钥和固件的位置。为了增强这种保护,您还可以启用处理器的受信任执行环境功能,该功能在微处理器中创建一个安全区域来存储固件。

3.禁用不安全和不必要的服务。要定义此类服务,你需要分析系统的操作。通常,此类服务的列表包括Telnet和琐碎文件传输协议,调试代理,开放端口等。

第2类:内存和应用程序安全

1.限制内存分配。实现一个内存管理单元,为缓冲区、操作系统和应用程序分配足够的内存。内存管理单元有助于保持嵌入式系统运行的平衡,并防止内存缓冲区溢出。此外,尽可能将内存切换到只读模式。

2.创建分区。将嵌入式系统的重要部分(如操作系统、GUI和安全应用程序)划分为不同的分区,有助于将它们彼此隔离并包含攻击。分区可以是物理分区和虚拟分区。

第3类:通讯安全

1.实施访问控制。不受保护地访问嵌入式系统的任何部分都是对黑客的公开邀请。要保护您的访问点,请使用强凭据并对其进行加密,实现最小权限原则,并尽可能启用身份验证。

2.保护通信通道。实现IPsec、DNS-SEC、SSH或SSL协议,并使用VPN保护与嵌入式系统的任何通信。部署防火墙来过滤流量也是一个很好的做法。

第4类:数据保护

1.加密所有内容。所有固件更新、传输和处理的数据以及存储的凭证都必须加密。使用加密签名来验证从可信来源获得的文件并检测可疑的修改。

2.混淆目标代码。混淆是一个过程,使你的代码纠缠在一起,对黑客来说不清楚,但在嵌入式系统中是可执行的。甚至可以通过混淆来加速代码的执行。这项措施将使黑客更难对你的代码进行反向工程。

第5类:发布和支持

1.进行端到端威胁评估。完整的安全评估包括:

a.从设备制造商,软件开发人员和最终用户的角度执行完整的生命周期分析并识别潜在威胁
b.创建风险矩阵,并通过每个可能的渠道估算攻击的可能性和成功率
c.自己模拟黑客攻击或进行黑盒渗透测试

2.定期更新软件。无论为旧的嵌入式系统开发软件有多么困难,这样做总是有益的。在新的软件版本中,你可以推出其他安全措施,以抵消新型攻击或修补漏洞(如果在产品发布后发现一个漏洞)。别忘了添加如上所述的黑名单和白名单保护。这些方法将阻止从不受信任的来源安装软件。

有了这些实践,你就可以使网络犯罪分子更难为嵌入式系统盗用你的软件。

最后

为嵌入式系统开发软件是一个很大的挑战。开发人员必须实现所有必需的功能,同时要考虑多个设备的限制并保护软件免受攻击。

当然,威胁可能来自不同的来源和渠道,因此在微处理器和少量内存中安装针对所有这些威胁的保护似乎是不可能的。

参考来源:

https://www.apriorit.com/dev-blog/690-embedded-systems-attacks

转载来源:strongerHuang
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 110

在嵌入式裸机编程中,作为一名初级的CODER。经常要与CPU、内存等打交道。CPU作为系统的动力源,其重要程度不言而喻。

但是,在裸机编程中,对内存的管理也不容忽视。如果稍微不注意,轻则,可能造成内存泄漏,重则造成内存访问异常。导致系统死机。

嵌入式产品,对稳定性要求及其严格。动不动就死机,那可就麻烦大了。以下,是我本人对嵌入式系统裸机编程的内存管理的一些简介。

1、尽量不使用库自带的malloc和free

malloc和free在PC编程中是很好用的一种内存分配手段。但是,其在嵌入式中,就未必好用了。由于嵌入式裸机编程中,无MMU,即内存管理单元。无法实现对内存进行动态映射(不明白什么叫动态映射的同学,可以参考网上的资料)。

也就是说,实际上,malloc和free并不能实现动态的内存的管理。这需要在启动阶段专门给其分配一段空闲的内存区域作为malloc的内存区。如STM32中的启动文件startup_stm32f10x_md.s中可见以下信息:

Heap_Size       EQU     0x00000800

                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem        SPACE   Heap_Size
__heap_limit

其中,Heap_Size即定义一个宏定义。数值为 0x00000800。Heap_Mem则为申请一块连续的内存,大小为 Heap_Size。简化为C语言版本如下:

#define Heap_Size 0x00000800
unsigned char Heap_Mem[Heap_Size] = {0};

在这里申请的这块内存,在接下来的代码中,被注册进系统中给malloc和free函数所使用:

__user_initial_stackheap
LDR     R0, =  Heap_Mem  ;  返回系统中堆内存起始地址
LDR     R1, =(Stack_Mem + Stack_Size)
LDR     R2, = (Heap_Mem +  Heap_Size); 返回系统中堆内存的结束地址
LDR     R3, = Stack_Mem
BX      LR

就如上面分析的那样,其实,在裸机编程的时候,对堆内存的管理。并非是智能化的,并非你想申请多少就多少。而是使用一块固定的内存用作堆内存的分配。这在设计的时候,往往不是最佳的方案。这块内存,如果被多次按照不同的大小进行申请,就会造成内存碎片。最终导致无法申请到足够的内存。导致系统运行出错。这在原本内存就已经很少的嵌入式系统中,更是不能接受的。所以,建议是把那个Heap_Size设置成 0 吧。放弃其使用吧。

而更为致命的是,有些malloc,free函数,由于工程人员的偷懒。实现甚至可能如下:

unsigned char mem_buffer[512];
unsigned char *mem_offset = & mem_buffer;
void *malloc(int size)
{
    unsigned char *tmp = mem_offset;
    mem_offset += size;
    return (void *)tmp;
}

void free(void *mem)
{
 mem_offset = mem;
}

2、不用malloc、free的原因

一般单片机的内存都比较小,而且没有MMU,malloc 与free的使用容易造成内存碎片。而且可能因为空间不足而分配失败,从而导致系统崩溃,因此应该慎用,或者自己实现内存管理。

在函数中使用malloc,如果是大的内存分配,而且malloc与free的次数也不是特别频繁,使用malloc与free是比较合适的,但是如果内存分配比较小,而且次数特别频繁,那么使用malloc与free就有些不太合适了。

因为过多的malloc与free容易造成内存碎片,致使可使用的堆内存变小。尤其是在对单片机等没有MMU的芯片编程时,慎用malloc与free。如果需要对内存的频繁操作,可以自己实现一个内存管理。

使用动态内存分配,应分不同的应用场合。

对于在操作系统上运行的程序,实际的物理内存分配与释放使用操作系统来实现的,即使程序调用了 malloc和free物理内存并不会马上变化。物理内存的变化,直到系统的内存管理操作时才发生。

对于裸机跑在MCU上的程序,分配与释放内存都会造成实际物理内存的变化。因为此时物理内存的分配是由自己实现的,而内存管理我们自己并没有去做。这样,盲目的使用malloc与free恰恰并不好,反而会造成内存的不恰当使用。甚至于内存溢出。

所以,动态内存的使用前提是有一套好的内存管理方法,这样动态内存的使用才会合理使用内存。如果没有合适的内存管理代码,还是用静态内存好一些。

3、 更好的替代方案:内存池

可能有些同学,觉得:内存池,这是什么东西?

内存池,简洁地来说,就是预先分配一块固定大小的内存。以后,要申请固定大小的内存的时候,即可从该内存池中申请。用完了,自然要放回去。注意,内存池,每次申请都只能申请固定大小的内存。这样子做,有很多好处:

(1)每次动态内存申请的大小都是固定的,可以有效防止内存碎片化。(至于为什么,可以想想,每次申请的都是固定的大小,回收也是固定的大小)

(2)效率高,不需要复杂的内存分配算法来实现。申请,释放的时间复杂度,可以做到O(1)。

(3)实现简单,易用。

(4)内存的申请,释放都在可控的范围之内。不会出现以后运行着,运行着,就再也申请不到内存的情况。

内存池,并非什么很厉害的技术。实现起来,其实可以做到很简单。只需要一个链表即可。在初始化的时候,把全局变量申请来的内存,一个个放入该链表中。在申请的时候,只需要取出头部并返回即可。在释放的时候,只需要把该内存插入链表。以下是一种简单的例子(使用移植来的linux内核链表,对该链表的移植,以后有时间再去分析):

#define MEM_BUFFER_LEN  5    //内存块的数量
#define MEM_BUFFER_SIZE 256 //每块内存的大小

//内存池的描述,使用联合体,体现穷人的智慧。就如,我一同学说的:一个字节,恨不得掰成8个字节来用。
typedef union mem {
struct list_head list;
unsigned char buffer[MEM_BUFFER_SIZE];
}mem_t;

static union mem gmem[MEM_BUFFER_LEN];

LIST_HEAD(mem_pool);

//分配内存
void *mem_pop()
{
    union mem *ret = NULL;
    psr_t psr;

    psr = ENTER_CRITICAL();
    if(!list_empty(&mem_pool)) { //有可用的内存池 
        ret = list_first_entry(&mem_pool, union mem, list);
        //printf("mem_pool = 0x%p  ret = 0x%p\n", &mem_pool, &ret->list);
        list_del(&ret->list);
 }
 EXIT_CRITICAL(psr);
 return ret;//->buffer;
}


//回收内存
void mem_push(void *mem)
{
    union mem *tmp = NULL; 
    psr_t psr;

    tmp = (void *)mem;//container_of(mem, struct mem, buffer);
    psr = ENTER_CRITICAL();
    list_add(&tmp->list, &mem_pool);
    //printf("free = 0x%p\n", &tmp->list);

    EXIT_CRITICAL(psr);
}

//初始化内存池
void mem_pool_init()
{
    int i;
    psr_t psr;
    psr = ENTER_CRITICAL();
    for(i=0; i<MEM_BUFFER_LEN; i++) {
        list_add(&(gmem[i].list), &mem_pool);
        //printf("add mem 0x%p\n", &(gmem[i].list));
 }
 EXIT_CRITICAL(psr);
}

整理来自:

1、https://blog.csdn.net/chenyuwen789/category_5823163.html

2、https://blog.csdn.net/c12345423/article/details/53004465

来源:嵌入式大杂烩
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 497

找工作也是一门技能,有的人很快就找到自己喜欢的工作,有的人找了很久也没找到合适的工作。

下面给大家分享几点找工作过程中存在的“潜规则”内容。

1、面试的本质不是考试,而是告诉面试官你会做什么

经验不够的小伙伴特别容易犯的一个错误,不清楚面试官到底想问什么,其实整个面试中面试官并没有想难倒你的意思,只是想通过提问的方式来知道你会什么。

比如STM32单片机的代码从哪里开始执行?
没入门的说从main函数开始,大佬会从上电启动开始。

围绕着一个话题只要你能在某一方面回答得很深入很透彻,基本上面上的可能性会大大提高;

如果当你听到这个话题时,感觉不知道如何回答,或者说感觉很简单,几句话就说完了,那么基本上你很难面上,因为你的知识储备不够,说不出来关于技术相关的内容。

2、薪水要求高一点录取概率就大一点

我曾经面试一个嵌入式工程师,各种精通C语言,精通stm32等等等,然后我就问他你期望的薪水是多少呢?

他的回答是4K,先不说他简历上写的是真是假,但是有一点很明确,如果你在市场上去肉,别人都是卖30元一斤,而路边有个摆摊的只买10元一斤,那么你们会去买么?

另外,我想告诉大家的是,一般来说对于一家正规的技术型公司,真的不在乎多给工资,最重要的是人才;

或者我们换位思考一下,假设你是项目经理,你来招人帮你干事情,你会节约一点工资,去招技术差的,帮老板节约成本,自己慢慢来带人么,给自己找一大堆事情么?

而且,从心里角度来说,人们一般只会集中精力关注一个点,如果你的期望薪水高一点,那么他在考虑是否录取你时考虑的就是薪水问题,或者就是考虑你的技术问题,但是工资是老板发,技术是自己使用,所以从某方面来说如果有几个人与你技术差不多,但是从潜意识里,就会因为你的期望工资高而觉得你的技术好一点,最后录取你,这就像假设我们要求买一件羽绒衣服,同时看上了两件,一件800元,另一件1000元,我相信大多数人都会认为1000元这件质量好点,如果再加上买这件衣服的钱不是你出,那么你会选择那件呢?

最后提醒大家,期望薪水高一点并不是说无边界,那么到底多少合适呢?

可以从两个方面考虑一是工作年限,一般来说

初入行:8K到12K
1年到2年:10K到15K
3年到5年:13K到22K
5年以上:18K以上

当然,不同的地区有点差别,但差别应该不大

另一个方面是参考大公司的工资标准,打开招聘信息,查看大公司的招聘信息,一般来说都是给的一个区间值,你可以把区间值最大的那个值乘80%作为你的期望薪资的参考值。

3、简历上罗列了很多技能的很难面上

这里我就简单说一下为什么,简历上罗列很多技能可以反映如下几个问题:

1.不清楚对应岗位工程师的核心技术是什么,给面试官的第一感觉就是:外行;

2.罗列的技能越多面试官问的方向就越多,你很难每一样都精通,最后会成为问的每一个技能你都只会点皮毛;

3.完全暴露出你没有任何工作经验,我见过有的把熟练使用办公软件、外语等级、计算机二级什么的都写在上面;

那面试技能这里到底应该怎样写呢?从个人经验和及面试反馈来看,个人建议如下:

1.写两个精通或者深入研究的技术点,如:熟练某款MCU,有多个某平台项目实战等;

2.写三个熟练应用,这个最好写常用的框架;

3.写三个了解并能简单使用的技能;

总之技能这一栏要在潜意识里引导面试官去问你你已经准备好的话题;

4、笔试题做不来影响并不大,关键是要体现出你在认真对待

首先大家要明白一点的就是,在你认真对待笔试题的情况下,笔试题做得好与不好、正确与错误其实影响并不大,注意我这里说的是认真对待的情况下。

这一点估计没有多年工作经验或没有带过团队开发的人很难理解,其实大部分面试官招人重点看如下3点:

1.是否聊得来
2.主观能动性
3.逻辑思维注意:

我这里并不是没有任何基础的人具备上述三点就能面试,而是指已经基本会编程的情况下满足上述三点就很容易面试上;

5、对自己要自信,面试官只是比你早到公司几个月而已

首先强调一点,对自己自信,并不是不尊重面试官;

这里主要表达的核心思想是,在整个面试中你要让人感到你和面试官是平等的,面试官在挑选你,你也在挑选公司;

6、不写假简历,但必须扬长避短

其实这就是里我们常常说的如何包装简历,老老实实总是会吃亏的;诚实守信、不写假简历这是最基本的职业道德;

但是,扬长避短,适当的夸张一下自己的能力是很有必要的,这就如同一家公司在对外宣传自己的产品是一个道理;

好了,这一点我也不好在公开场合长篇大论,先具体、实际的了解情况,然后在根据实际情况包装简历;

7、老板是人精,谈理想时,别虚伪,要坦诚

这里一般是面试的最后一个环节,你一定要让人感觉你是一个真诚、实干的技术员,千万不能让人感觉你是一个浮躁、眼高手低的人;

8、不打没有把握的仗,必须充分准备

这是面试是否顺利非常非常重要的一个环节,也是很多浮躁的最容易犯的错误。

它的核心思想其实就是:面试必须系统化的认真的准备!

怎样系统化的认真的准备呢?

以下7个步骤是在我实际经验中总结出来的,提供给大家参考

1.最基本条件,概念上一定要懂的一些知识和技能。

2.系统化的知识点,对知识点系统化的梳理和系统化的看面试题,并且强行将知识点划分为3类,精通、熟练、了解,千万别东看一下西弄一下,最后会让你浮躁的心直接在面试中崩溃掉。

3.写简历,简历中必须在醒目的位置体现出技术点(hr就认几个关键词,决定是否通知你面试),如果投递出去的简历面试邀请率低于60%,肯定是简历写得有问题,最好找专业人士帮你看看简历。

4.模拟面试(三次),提高面试通过率。面试的成本其实挺高的,好不容易收到面试通知,千辛万苦赶车找路来。

到面试的地方,如果犯了常规的低级错误,其实很不划算,早一天找到工作就早一天赚到钱(程序员的工资平均在500左右一天)

5.实战学习面试(5次实战面试),出去面试,但目的不是为了面上,而是为了让你放松心情,不紧张,习惯与面试官进行技术沟通(其实很多人在这个阶段就会拿到offer)

面试完后马上回忆并记录面试中问了那些问题,自己大体是怎么回答的,然后与专业人士讨论这样回答是否恰当,必须保证下次遇到类似问题会回答得更好,否则面试很多次也不会有提高,因为在你回答得不好或者明显错误的地方面试官并不会给你指出来,这就是为什么,很多人出去面试说自己回答得很好,然后就让他等通知,然后。。。就没有然后了

6.正式面试,同样,每面试一次后马上与专业人沟通,最后你会发现每个面试官问的问题都大同小异,你会觉得面试so easy!当你拿到多个offer后,然后从中选一个,那感觉简直就像走上了人生巅峰!

7.通过试用期,虽然都说面试造飞机、工作拧螺丝,但是估计对于刚入行的人来说,还是有很多的技术没有接触或者不懂,这时不懂的一定要多问,业务上的多问同事,技术上的要先自己研究一下,如果还是不懂就要多请教专业的人,实在不懂再问同事,总而言之言而总之一定要积极主动!

9、选择大于努力的前提是先足够的努力才会有选择

很多人都在倡导选择大于努力,可更重要的往往更容易被忽略,那就是:只有足够的努力才会有选择。

这就形成了一个死循环,或者用我们程序员术语叫做:死锁,选择一家好的公司上班,对自己的发展前景很重要,但前提是你能拿到好公司的offer!

10、人生苦短,绝不将就,必须去自己真心想去的公司

我遇到过很多人,在跟他们聊天时,他们都有类似的心理:一点都不想在这里上班,但是工作又不好找,只好暂时做着,这一做就是好几年;每天带着一种不愿意的心情上班,是何种的煎熬,而且我相信也很难作出卓越的成绩,最多勉强把工作完成,这样做下去意义又何在!

参考来源:
https://www.cnblogs.com/newAndHui/p/12451882.html

本文转载自:网络
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 29

页面

订阅 RSS - 嵌入式