跳至主要内容

【转】嵌入式内功.葵花宝典

在我们这个时代,有太多的人想走捷径,想练"葵花宝典",结果却落得一场空。盖世神功我们要练,不过要踏踏实实地练,不能走自宫化为"人妖"的道路。嵌入式内功我们必须练,而且要踏踏实实一招一势地练。好,今天就翻开《嵌入式内功》准备练第一页:

       《嵌入式内功》准备练第一页

  话说...,现在大部分处理器生产商在销售处理器的同时,还会提供开发环境IDE比如TI的CCS和AD的Visual Dsp++。另外你还可以从这些公司或其它专门开发DEMO板的公司购买开发板。这些DEMO一般会提供比较丰富的Demo程序,比如音视频捕捉及显示、I2C实例、DMA实例、CACHE实例等。这些DEMO程序基本上由应用处理器生产商提供的底层驱动程序库(driver lib)经二次开发出来的。可见,对于一般的嵌入式底层软件开发人员来说,基本就不用写什么真正意义上的驱动程序,(除非你是为处理器生产商写底层驱动的,毕竟这种大牛不多,也不屑于我的文章),只要参照DEMO程序或使用驱动程序接口开发适合自己项目的FIRMWARE就可以了。这种开发已经演变成驱动应用而不是驱动开发,其难度相比从零开始的驱动开发已经大大降低。我们国内很大部分"驱动开发者"都在从事这样的工作!不过也确实没办法,如果处理器生产商不提供已经屏蔽硬件特性并降低底层软件开发难度的驱动程序库,估计许多的"驱动开发者"即使磕破头皮绞尽脑汁也未必能搞定那些底层驱动。可见,要搞真正的驱动开发,还是要到大公司去混!

  一般来说,从事消费类或通信类产品研发的底层软件开发的人员,如果不熟练掌握DMA、cache、PCI、代码优化(包括编译器优化)等技术,那么他充其量还只是停留在应用软件或简单系统开发的层面,就好比搞VC编程的还没很好掌握MFC一样,虽然进入了应用软件开发的殿坛,但还没有把握这个领域的关键技术。这几个东西在对嵌入式底层软件软件开发的人来说至关重要,可以说是高手和普通者的分水岭。现在,一些高端的流媒体产品如手机研发、游戏设备开发、IPTV、数字视频录像机(DVR)、数字视频广播(DVB)、机顶盒、视频会议系统、网络监控摄像头以及可视电话,为了能够处理大量的音视频输入输出数据流,往往采用单一MPU(比如ARM和Motorola的PPC/Coldfire/68K)、单一DSP(专用媒体处理器TI C64x/DM642、AD Blackfin 5xx、Equator的BSP15以及Philips TriMedia)或MPU+DSP组合的单核多芯或单芯多核的处理结构(TI OMAP/DaVinci和AD BF561)作为核心处理模块(一般的MCU主要应用于控制目的,不具备大批量数据处理的能力,所以比较少被应用于这些产品)。另外,这些处理器为了能进一步提升数据处理能力往往都会配备DMA、CACHE、PCI等外设或接口(见下图,DMA+CACHE+PCI的协作极大地提高了处理器与处理器之间以及处理器与外设的交互能力)。由此可见DMA、CACHE、PCI对于从事消费类或通信类研发的底层软件开发的重要性可想而知(搞定了这些复杂有难度的外设,其它的也不在话下了:))。

DMA+CACHE+PCI的协作极大地提高了处理器与处理器之间以及处理器与外设的交互能力

*DMA:它是个很好"奴才"。"主子"CPU让它干什么它就干什么,任劳任怨。那些搬移大量外围设备数据的"体力活"它统统包下,干完之后马上中断告诉"主子",而且两者在同时使用数据总线时,卑微的"奴才"会让着"主子"。这样的好"奴才"谁会不要,谁会不喜欢呢?(DMA是很基本的东西,后面介绍的cache和PCI控制器也都会用到)。

*Cache:它是"加速器"。在目前的IT行业,外围内存在访问速率上与处理器严重脱节一直是不可回避的"瓶颈"问题。cache的引入无疑极大地缓解了这个问题。它使得处理器访问cache就如同访问外部内存一样快速,极大地提高了CPU处理数据的效率,所以被广泛地应用于流媒体设备中。

*PCI:当在一块板子上有多块处理器时,它们之间大量的数据交互就是可能存在问题,比如MPU从网络接收的大块连续数据发送给DSP处理时,就需要有足够承载能力及带宽的总线。PCI总线一般33M最大66M带宽能力足以应付决大部分的应用。PCI给处理器之间架上了桥梁,使得MPU+DSP的应用设计成为现实。

*Optimization:选择合适的处理器并设计能够充分发挥外设性能的板子是项目负责人和硬件人员干的事情,而软件开发人员要干的就是编写能够充分发挥硬件功能的高效代码。代码优化方法就是其中用于提高系统性能和代码效率的有效技术,是任何嵌入式开发人员都要努力掌握的技能。

在之后的文章中陆续会对上述4个方面进行全面深入的分析。更多精彩值得期待。

评论

此博客中的热门博文

【转】AMBA、AHB、APB总线简介

AMBA 简介 随着深亚微米工艺技术日益成熟,集成电路芯片的规模越来越大。数字IC从基于时序驱动的设计方法,发展到基于IP复用的设计方法,并在SOC设计中得到了广泛应用。在基于IP复用的SoC设计中,片上总线设计是最关键的问题。为此,业界出现了很多片上总线标准。其中,由ARM公司推出的AMBA片上总线受到了广大IP开发商和SoC系统集成者的青睐,已成为一种流行的工业标准片上结构。AMBA规范主要包括了AHB(Advanced High performance Bus)系统总线和APB(Advanced Peripheral Bus)外围总线。   AMBA 片上总线        AMBA 2.0 规范包括四个部分:AHB、ASB、APB和Test Methodology。AHB的相互连接采用了传统的带有主模块和从模块的共享总线,接口与互连功能分离,这对芯片上模块之间的互连具有重要意义。AMBA已不仅是一种总线,更是一种带有接口模块的互连体系。下面将简要介绍比较重要的AHB和APB总线。 基于 AMBA 的片上系统        一个典型的基于AMBA总线的系统框图如图3所示。        大多数挂在总线上的模块(包括处理器)只是单一属性的功能模块:主模块或者从模块。主模块是向从模块发出读写操作的模块,如CPU,DSP等;从模块是接受命令并做出反应的模块,如片上的RAM,AHB/APB 桥等。另外,还有一些模块同时具有两种属性,例如直接存储器存取(DMA)在被编程时是从模块,但在系统读传输数据时必须是主模块。如果总线上存在多个主模块,就需要仲裁器来决定如何控制各种主模块对总线的访问。虽然仲裁规范是AMBA总线规范中的一部分,但具体使用的算法由RTL设计工程师决定,其中两个最常用的算法是固定优先级算法和循环制算法。AHB总线上最多可以有16个主模块和任意多个从模块,如果主模块数目大于16,则需再加一层结构(具体参阅ARM公司推出的Multi-layer AHB规范)。APB 桥既是APB总线上唯一的主模块,也是AHB系统总线上的从模块。其主要功能是锁存来自AHB系统总...

【转】select问题

问: 该串口初始化如下 ioctl(comm2Fd,FIOBAUDRATE,9600) ioctl(comm2Fd,FIOSETOPTIONS,OPT_RAW) 使用如下 FD_ZERO   (&readFds); FD_SET   (comm2Fd,   &readFds);   width   =   comm2Fd   +   1; FD_ISSET   (comm2Fd,   &readFds); FOREVER { if(timeoutvalue==0) { printf("\nselect   start!\n"); selectnum   =   select   (width,   &readFds,   NULL,   NULL,   NULL); printf("\nselect   over!\n"); }                                 ........... } 现在的状况是程序跑一段时间后会死机或这个串口通讯任务死掉,每次死机都是"select   start!"打印出来,而"select   over!"打印不出来,在仅这个串口通讯任务死掉的情况下,用comm1Fd超级终端登陆,查询任务状态,会发现tExcTask任务居然处于挂起状态??? 哪位大哥帮忙分析一下或给予一点提示,小弟不胜感激!! 答: sele...

【转】C++/CLI程序进程之间的通讯

 现在,把大型软件项目分解为一些相交互的小程序似乎变得越来越普遍,程序各部分之间的通讯可使用某种类型的通讯协议,这些程序可能运行在不同的机器上、不同的操作系统中、以不同的语言编写,但也有可能只在同一台机器上,实际上,这些程序可看成是同一程序中的不同线程。而本文主要讨论C++/CLI程序间的通讯,当然,在此是讨论进程间通讯,而不是网络通讯。    简介   试想一个包含数据库查询功能的应用,通常有一个被称为服务端的程序,等待另一个被称为客户端程序发送请求,当接收到请求时,服务端执行相应功能,并把结果(或者错误信息)返回给客户端。在许多情况中,有着多个客户端,所有的请求都会在同一时间发送到同一服务端,这就要求服务端程序要更加高级、完善。   在某些针对此任务的环境中,服务端程序可能只是众多程序中的一个程序,其他可能也是服务端或者客户端程序,实际上,如果我们的数据库服务端需要访问不存在于本机的文件,那么它就可能成为其他某个文件服务器的一个客户端。一个程序中可能会有一个服务线程及一个或多个客户线程,因此,我们需小心使用客户端及服务端这个术语,虽然它们表达了近似的抽象含义,但在具体实现上却大不相同。从一般的观点来看,客户端即为服务端所提供服务的"消费者",而服务端也能成为其他某些服务的客户端。    服务端套接字   让我们从一个具体有代表性的服务端程序开始(请看例1),此程序等待客户端发送一对整数,把它们相加之后返回结果给客户端。   例1: using namespace System; using namespace System::IO; using namespace System::Net; using namespace System::Net::Sockets; int main(array<String^>^ argv) { if (argv->Length != 1) { Console::WriteLine("Usage: Server port"); Environment::Exit(1); } int port = 0; try { port = Int32::Parse(argv[0]); } catch (FormatException^ e) { Console::Wri...