首页 > 游戏测评 >  > 

嵌入式系统设计_嵌入式工程师真实现状

嵌入式系统在硬件设计,作系统的选择,以及软件的设计要遵循哪些原则

要把软件做得非常灵活又要便于维护是一个很困难的事情。灵活的软件他的结构就复杂,维护起来就困难。有得必有失,关键就在于如何处理这两者,使得大于失。软件的设计开发应遵循以下六大原则:1. OCP全称:“Open-Closed Principle” 开放-封闭原则说明:对扩展开放,对修改关闭。优点:按照OCP原则设计出来的系统,降低了程序各部分之间的耦合性,其适应性、灵活性、稳定性都比较好。当已有软件系统需要增加新的功能时,不需要对作为系统基础的抽象层进行修改,只需要在原有基础上附加新的模块就能实现所需要添加的功能。增加的新模块对原有的模块完全没有影响或影响很小,这样就无须为原有模块进行重新测试。如何实现“开-闭”原则在面向对象设计中,不允许更改的是系统的抽象层,而允许扩展的是系统的实现层。换言之,定义一个一劳永逸的抽象设计层,允许尽可能多的行为在实现层被实现。解决问题关键在于抽象化,抽象化是面向对象设计的个核心本质。 对一个事物抽象化,实质上是在概括归纳总结它的本质。抽象让我们抓住最最重要的东西,从更高一层去思考。这降低了思考的复杂度,我们不用同时考虑那么多的东西。换言之,我们封装了事物的本质,看不到任何细节。在面向对象编程中,通过抽象类及接口,规定了具体类的特征作为抽象层,相对稳定,不需更改,从而满足“对修改关闭”;而从抽象类导出的具体类可以改变系统的行为,从而满足“对扩展开放”。对实体进行扩展时,不必改动软件的源代码或者二进制代码。关键在于抽象。2. LSP全称:“Liskov Substitution Principle” 里氏代换原则说明:子类型必须能够替换它们的基类型。一个软件实体如果使用的是一个基类,那么当把这个基类替换成继承该基类的子类,程序的行为不会发生任何变化。软件实体察觉不出基类对象和子类对象的区别。优点:可以很容易的实现同一父类下各个子类的互换,而客户端可以毫不察觉。3. DIP全称:“Dependence Inversion Principle”依赖倒置原则说明:要依赖于抽象,不要依赖于具体。客户端依赖于抽象耦合。抽象不应当依赖于细节;细节应当依赖于抽象;要针对接口编程,不针对实现编程。优点:使用传统过程化程序设计所创建的依赖关系,策略依赖于细节,这是糟糕的,因为策略受到细节改变的影响。依赖倒置原则使细节和策略都依赖于抽象,抽象的稳定性决定了系统的稳定性。怎样做到依赖倒置?以抽象方式耦合是依赖倒转原则的关键。抽象耦合关系总要涉及具体类从抽象类继承,并且需要保证在任何引用到基类的地方都可以改换成其子类,因此,里氏代换原则是依赖倒转原则的基础。在抽象层次上的耦合虽然有灵活性,但也带来了额外的复杂性,如果一个具体类发生变化的可能性非常小,那么抽象耦合能发挥的好处便十分有限,这时可以用具体耦合反而会更好。层次化:所有结构良好的面向对象构架都具有清晰的层次定义,每个层次通过一个定义良好的、受控的接口向外提供一组内聚的服务。依赖于抽象:建议不依赖于具体类,即程序中所有的依赖关系都应该终止于抽象类或者接口。尽量做到:1、任何变量都不应该持有一个指向具体类的指针或者引用。2、任何类都不应该从具体类派生。3、任何方法都不应该覆写它的任何基类中的已经实现的方法。4. ISP全称:“Intece Segregation Principle” 接口隔离原则说明:使用多个专一功能的接口比使用一个的总接口总要好。从一个客户类的角度来讲:一个类对另外一个类的依赖性应当是建立在最小接口上的。过于臃肿的接口是对接口的污染,不应该客户依赖于它们不用的方法。优点:会使一个软件系统功能扩展时,修改的压力不会传到别的对象那里。如何实现接口隔离原则不应该用户依赖于他们不用的方法。1、利用委托分离接口。2、利用多继承分离接口。5. CARP or CRP全称:“Comite/Aggregate Reuse Principle” 合成/聚合复用原则 or “Comite Reuse Principle” 合成复用原则说明:如果新对象的某些功能在别的已经创建好的对象里面已经实现,那么尽量使用别的对象提供的功能,使之成为新对象的一部分,而不要自己再重新创建。新对象通过向这些对象的委派达到复用已有功能的。简而言之,要尽量使用合成/聚合,尽量不要使用继承。优点:1) 新对象存取成分对象的方法是通过成分对象的接口。2) 这种复用是黑箱复用,因为成分对象的内部细节是新对象所看不见的。3) 这种复用支持包装。4) 这种复用所需的依赖较少。5) 每一个新的类可以将焦点集中在一个任务上。6) 这种复用可以在运行时间内动态进行,新对象可以动态的引用与成分对象类型相同的对象。7) 作为复用手段可以应用到几乎任何环境中去。缺点:就是系统中会有较多的对象需要管理。6. LOD or LKP全称:“Law of Demeter” 迪米特原则 or “Least Knowledge Principle” 最少知识原则说明:对象与对象之间应该使用尽可能少的方法来关联,避免千丝万缕的关系。如何实现迪米特法则迪米特法则的主要用意是控制信息的过载,在将其运用到系统设计中应注意以下几点:1) 在类的划分上,应当创建有弱耦合的类。类之间的耦合越弱,就越有利于复用。2) 在类的结构设计上,每一个类都应当尽量降低成员的访问权限。一个类不应当public自己的属性,而应当提供取值和赋值的方法让外界间接访问自己的属性。3) 在类的设计上,只要有可能,一个类应当设计成不变类。4) 在对其它对象的引用上,一个类对其它对象的引用应该降到。

嵌入式系统设计_嵌入式工程师真实现状嵌入式系统设计_嵌入式工程师真实现状


嵌入式系统设计_嵌入式工程师真实现状


还有个单一职责原则:

SRP(SRP--Single-Responsibility Principle): 就一个类而言,应该只专注于做一件事和一个引起它变化的原因。所谓职责,我们可以理解他为功能,就是设计的这个类功能应该只有一个,而不是两个或更多。也可以理解为引用变化的原因,当你发现有两个变化会要求我们修改这个类,那么你就要考虑撤分这个类了。因为职责是变化的一个轴线,当需求变化时,该变化会反映类的职责的变化。 使用SRP注意点: 1、一个合理的类,应该一个引起它变化的原因,即单一职责;

2、在没有变化征兆的情况下应用SRP或其他原则是不明智的;

3、在需求实际发生变化时就应该应用SRP等原则来重构代码;

4、使用测试驱动开发会迫使我们在设计出现臭味之前分离不合理代码;

5、如果测试不能迫使职责分离,僵化性和脆弱性的臭味会变得很强烈,那就应该用Facade或Proxy模式对代码重构; SRP优点: 消除耦合,减小因需求变化引起代码僵化性臭味

什么是嵌入式系统的传统设计方法

嵌入式系统的传统设计方法如下:

1、嵌入式系统一般指非PC系统,有计算机功能但又不称之为计算机的设备或器材。

2、它是以应用为中心,软硬件可裁减的,适应应用系统对功能、可靠性、成本、体积、功耗等综合性严格要求的专用计算机系统。

3、简单地说,嵌入式系统集系统的应用软件与硬件于一体,类似于PC中BIOS的工作方式,具有软件代码小、高度自动化、响应速度快等特点,特别适合于要求实时和多任务的体系。

4、嵌入式系统主要由嵌入式处理器、相关支撑硬件、嵌入式作系统及应用软件系统等组成,它是可工作的“器件”。

5、嵌入式系统几乎包括了生活中的所有电器设备,如掌上PDA、移动计算设备、电视机顶盒、手机上网、数字电视、多媒体、汽车、微波炉、数字相机、家庭自动化系统、电梯、空调、安全系统、自动售货机、蜂窝式电话、消费电子设备、工业自动化仪表与医疗仪器等。

6、嵌入式系统的硬件部分,包括处理器/微处理器、存储器及外设器件和I/O端口、图形等。

7、嵌入式系统有别于一般的计算机处理系统,它不具备像硬盘那样大容量的存储介质,而大多使用EPROM、EEPROM或闪存(FlashMemory)作为存储介质。

8、软件部分包括作系统软件(要求实时和多任务作)和应用程序编程。

9、应用程序控制着系统的运作和行为;而作系统控制着应用程序编程与硬件的交互作用。

嵌入式系统

嵌入式系统由硬件和软件组成.是能够进行运作的器件。其软件内容只包括软件运行环境及其作系统。硬件内容包括信号处理器、存储器、通信模块等在内的多方面的内容。

相比于一般的计算机处理系统而言,嵌入式系统存在较大的异性,它不能实现大容量的存储功能,因为没有与之相匹配的大容量介质,大部分采用的存储介质有E-PROM、EEPROM 等,软件部分以API编程接口作为开发平台的核心。

嵌入式计算机系统的设计过程

1.

需求分析

确定设计任务和目标,并制定说明规格文档,作为下一步设计的指导和验收标准。需求分析往往要与用户反复交流,以明确系统功能需求,性能需求,环境、可靠性、成本、功耗、资源等需求。

2.

体系结构设计

体系结构设计是嵌入式系统的总体设计,它需要确定嵌入式系统的总体构架,从功能上对软硬件进行划分。在此基础上,确定嵌入式系统的硬件选型(主要是处理器选型),作系统的选择和开发环境的选择。

3.

硬件的设计、制作及测试

在这一阶段要确定硬件部分的各功能模块及模块之间的关联,并在此基础上完成元器件的选择、原理图绘制、印刷电路板(PCB)设计、硬件的装配与测试、目标硬件最终的确定和测试。

4.

软件的设计、实现及测试

这部分工作与硬件开发并行、交互进行。软件设计主要完成程序的编制、作系统的移植、驱动程序的开发、应用软件的编写等工作。设计完成后,软件开发进入实现阶段。这一阶段主要是嵌入式软件的生成(编译、链接),调试和固化运行,完成软件的测试。

5.

系统集成

将测试完成的软件系统装入制作好的硬件系统中,进行系统综合测试,验证系统功能是否能够正确无误地实现,将正确的软件固化在目标硬件中。本阶段的工作是整个开发过程中最复杂、最费时的,特别需要相应的辅助工具支持。

6.

系统性能测试及可靠性测试

测试最终完成的系统性能是否满足设计任务书的各项性能指标和要求。若满足,则可将正确无误的软件固化在目标硬件中;若不能满足,在最坏的情况下,则需要回到设计的初始阶段重新进行设计方案的制定。

介绍一下嵌入式系统的设计步骤有哪些?各部分主要工作是什么

步:

硬件设计:主要是设计硬件电路图、绘制硬件原理图、绘制硬件PCB图、制作出PCB板。

第二步:

软件设计:主要是设计系统的底层函数、API函数、植入作系统、设计应用程序。

第三步:

调试:在PCB上运行调试程序

嵌入式系统的设计流程是什么?

嵌入式计算系统将必须紧密工作的硬件和软件相结合。嵌入式系统设计人员已将擅长的设计方法发展到用软件来体现系统的部分功能。早期的硬件/软件协同设计领域的研究人员强调同时进行设计的重要性。系统体系结构一旦确定,硬件和软件可以相对地进行设计。协同设计的目标是做出恰当的体系结构决策,允许在以后的实现阶段中完成。好的体系结构决策需要恰当的分析方法,因为它们必须满足严格的度量标准,例如实时性能和功耗。图1-15显示了一般的协同设计方法。给定可行的规格说明,大部分方法进行初始系统分析来确定并行设计的可能性,并可能将规格说明分解为过程。硬件/软件划分选取体系结构,其中一些作直接由硬件完成,而另一些则由运行在可编程平台上的软件完成。硬件/软件划分生成可以实现的模块设计。那些模块随后结合,进行性能或功耗测试,并调试以创建最终的系统。

(点击查看大图)图1-15硬件/软件协同设计的设计流基于平台的设计是片上系统通常采用的方法。平台允许若干用户将相同的基本平台定制成不同的产品。平台对于基于标准的市场尤其有用,在这种市场中,产品必须支持一些基本功能,而其他功能必须进行定制。如图1-16所示,基于平台的设计是一个两阶段过程。首先,平台的设计必须建立在系统总体需求(例如,某种标准)和平台应如何定制之上。平台一旦设计完,就可用于设计产品。产品利用平台的功能并添加自己的功能。图1-16基于平台的设计平台设计需要几个设计阶段:应用特征分析将系统需求和软件模型变为基于平台硬件体系结构的更明确的需求。设计空间搜索评估硬件选项。体系结构模拟帮助评估和优化体系结构的细节。必须为平台开发基础软件(硬件抽象层、作系统端口、通讯、应用库、调试)。平台的使用比较复杂,因为平台需要用户编程环境。程序员已经习惯了标准平台上丰富的开发环境。那些环境以图形用户界面的方式提供了很多工具—编译器、编辑器、调试器、模拟器。然而丰富的编程环境通常只支持单处理器。多处理器编程更困难,而异构多处理器相比同构多处理器更复杂。平台开发人员必须提供工具使得软件开发人员能够使用平台。有此工具来自CPU组件,其他工具必须从头开发。由于调试访问是依赖于硬件的,因而它尤为重要和困难。进程间通讯也很复杂,但它是应用开发人员的重要工具。

嵌入式系统设计的内容

《嵌入式系统设计》作为嵌入式系统设计的基本教程,全面地阐述了嵌入式系统的软硬件技术及其应用设计的基本方法和过程。《嵌入式系统设计》从嵌入式系统的发展历程开始,以ARM处理器为为蓝本介绍嵌入式系统的硬件原理,然后介绍了作系统原理,并用μClinux、μC/OS-Ⅱ和Windows CE介绍了广泛应用的嵌入式作系统平台,用MIPS的应用系统设计实验介绍了嵌入式系统应用设计的步骤和方法。

如何设计嵌入式系统?带你理解一个小型嵌入式作系统的精髓

1 多任务机制

其实在单一CPU 的情况下,是不存在真正的多任务机制的,存在的只有不同的任务轮流使用CPU,所以本质上还是单任务的。但由于CPU执行速度非常快,加上任务切换十分频繁并且切换的很快,所以我们感觉好像有很多任务同时在运行一样。这就是所谓的多任务机制。

实时系统的特征是延时可预测,能够在一个规定的时间内(通常是 ms 级别的)对某些信号做出反应。

2 任务的状态

任务有下面的特性:任务并不是随时都可以运行的,而一个已经运行的任务并不能保证一直占有 CPU 直到运行完。一般有就绪态,运行态,挂起态等。

运行态:一个运行态的任务是一个正在使用 CPU 的任务。任何时刻有且只有一个运行着的任务。

就绪态:一个就绪态任务是可运行的,等待占有 CPU 的任务释放 CPU。

挂起态:某些条件不满足而挂起不能运行的状态。

3 如何转化为就绪态

INT32U OSRdyTbl; / 就绪任务表 /

上面定义一个 32 位变量,每一位代表一个任务,0 表示挂起状态,1 表示就绪状态。它记录了各任务的就绪与否状态,称它为就绪表。OSRdyTbl 定义为 32 位变量,对应32 个任务。当然,定义为 64 位的话,便最多能支持 64 个任务。这样,可以定义两个宏,实现把任务的状态变为就绪或挂起态。

/ 在就绪表中登记就绪任务 /

#define OSSetPrioRdy(prio) { OSRdyTbl |= 0x01<

/ 从就绪表中删除任务 /

#define OSDelPrioRdy(prio) { OSRdyTbl &= ~(0x01<

任务之间互相,不存在互相调用的关系。所有任务在逻辑上都是平等的。由于任务之间互相看不见,所以他们之间的信息传输就无法当面完成。这就需要各种通信机制如信号量,消息邮箱,队列等来实现。

4 什么是抢占式调度?

调度的概念,通俗的说就是系统在多个任务中选择合适的任务执行。系统如何知道何时该执行哪个任务?可以为每个任务安排一个的优先级别,当同时有多个任务就绪时,优先运行优先级较高的任务。同时,任务的优先级也作为任务的标识号。代码中都是对标识号来完成对任务的作的。

所谓“抢占式调度”是指:一旦就绪状态中出现优先权更高的任务,便立即剥夺当前任务的运行权,把CPU分配给更高优先级的任务。这样CPU 总是执行处于就绪条件下优先级的任务。

5 多任务系统的时间管理

与人一样,多任务系统也需要一个“心跳”来维持其正常运行,这个心跳叫做时钟节拍,通常由定时器产生一个固定周期的中断来充当。

OSTimeDly 函数就是以时钟节拍为基准来延时的(在时钟的中断服务函数中,依次对各个延时任务的延时节拍数减1。若发现某个任务的延时节拍数变为0,则把它从挂起态置为就绪态。)。这个函数完成功能很简单,就是先挂起当起当前任务,设定其延时节拍数,然后进行任务切换,在指定的时钟节拍数到来之后,将当前任务恢复为就绪状态。任务必须通过OSTimeDly或 OSTaskSuspend 让出CPU的使用权(延时或等待),使更低优先级任务有机会运行。

6 如何实现多任务?

只有一个CPU,如何在同一时间实现多个程序的运行?要实现多任务,条件是每个任务互相。人如何才能,有自己的私有财产。任务也一样,如果一个任务有自己的CPU,堆栈,程序代码,数据存储区,那这个任务就是一个的任务。(CPU是通过多任务机制获得的,其他的需要你分配)

TIPS:

如果一个任务正在运行某个公共函数时(如Printf), 被另一个高优先级的任务抢占,那么当这个高优先级的任务也调用同一个公共函数时,极有可能破坏原任务的数据。因为两个任务可能共用一套数据。为了防止这种情况发生,常采用两种措施:可重入设计和互斥调用。

可重入函数中所有的变量均为局部变量,局部变量在调用时临时分配空间,所以不同的任务在不同的时刻调用该函数时,它们的同一个局部变量所分配的存储空间并不相同(任务私有栈中),互不干扰。另外,如果可重入函数调用了其他函数,则这些被调用的函数也必须是可重入函数。

实现互斥(独占)访问的方法有关中断,关调度,互斥信号量,计数信号量等。

6.1 一个任务如何拥有自己的程序代码

对于如何实现多任务,首先是程序代码,每个任务的程序代码与函数一样,与51 的奔程序一样,每个任务都是一个大循环。然后是数据存储区,由于全局变量是系统共用的,各个任务共享,不是任务私有,所以这里的数据存储区是指任务的私有变量,如何变成私有?局部变量也。编译器是把局部变量保存在栈里的,所以好办,只要任务有个私有的栈就行。

TIPS:

临界资源是一次仅允许一个任务使用的共享资源。每个任务中访问临界资源的那段程序称为临界区。

在多任务系统中,为保障数据的可靠性和完整性,共享资源要互斥(独占)访问,所以全局变量(只读的除外)不能同时有多个任务访问,即一个任务访问的时候不能被其他任务打断。共享资源是一种临界资源。

6.2 一个任务如何拥有自己的堆栈、数据存储区

私有栈的作用是存放局部变量,函数的参数,它是一个线性的空间,所以可以申请一个静态数组,把栈顶指针SP指向栈的数组的首元素(递增栈)或一个元素(递减栈)。即可打造一个人工的栈出来。每个任务还要有记录自己栈顶指针的变量,保存在任务控制块(TCB)中。

什么是任务控制块?

系统中的每个任务具有一个任务控制块,任务控制块记录任务执行的环境,这里的任务控制块比较简单,只包含了任务的堆栈指针和任务延时节拍数。任务控制块是任务的。它把任务的程序与数据联系起来,找到它就可以得到任务的所有资源。

6.3 一个任务如何拥有自己的CPU

来看看任务是如何“拥有”自己的CPU 的。只有一个 CPU,各个任务共享,轮流使用。如何才能实现?我们先来看看中断的过程,当中断来临时,CPU 把当前程序的运行地址,寄存器等现场数据保存起来(一般保存在栈里),然后跳到中断服务程序执行。待执行完毕,再把先前保存的数据装回CPU 又回到原来的程序执行。这样就实现了两个不同程序的交叉运行。

借鉴这种思想不就能实现多任务了吗!模仿中断的过程就可以实现任务切换运行。任务切换时,把当前任务的现场数据保存在自己的任务栈里面,再把待运行的任务的数据从自己的任务栈装载到CPU中,改变 CPU 的 PC,SP,寄存器等。可以说,任务的切换是任务运行环境的切换。而任务的运行环境保存在任务栈中,也就是说,任务切换的关键是把任务的私有堆栈指针赋予处理器的堆栈指针SP。

创建一个任务。它接收三个参数,分别是任务的入口地址,任务堆栈的首地址和任务的优先级。调用本函数后,系统会根据用户给出的参数初始化任务栈,并把栈顶指针保存到任务控制块中,在任务就绪表标记该任务为就绪状态。返回,这样一个任务就创建成功了。

当一个任务将要运行时,便通过取得它的堆栈指针(保存在任务控制块中)将这些寄存器出栈装入CPU 相应的位置即可。

6.4 如何实现抢占式调度?

基于任务优先级的抢占式调度,也就是优先级的任务一旦处于就绪状态,则立即抢占正在运行的低优先级任务的处理器资源。为了保证CPU 总是执行处于就绪条件下优先级的任务,每当任务状态改变后,即判断当前运行的任务是否是就绪任务中优先级的,否则进行任务切换。

任务状态会在什么时候发生改变呢?有下面两种情况:

1、高优先级的任务因为需要某种资源或延时,主动请求挂起,让出处理器,此时将调度就绪状态的低优先级任务获得执行,这种调度称为任务级的切换。如任务执行OSTimeDly或OSTaskSuspend把自身挂起就属于这种。

2、高优先级的任务因为时钟节拍到来,或在中断处理结束后,内核发现更高优先级任务获得了执行条件(如延时的时钟到时)则在中断后直接切换到更高优先级任务执行。这种调度也称为中断级的切换。

6.5 挂起/恢复任务

1. 挂起任务

通过 OSTaskSuspend可以主动挂起一个任务。OSTaskSuspend会把任务从任务就绪表中移出,重新启动系统调度。这个函数可以挂起任务本身也可以挂起其他任务。

2 .恢复任务(OSTaskResume())

可以让被 OSTaskSuspend 或 OSTimeDly 挂起的任务恢复就绪态,然后进行任务调度。

版权声明:本文内容由互联网用户自发贡献。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 836084111@qq.com,本站将立刻删除。