资源描述
,*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,硬件抽象层,BSP,的概念,BSP,全称“板级支持包”(,Board Support Packages,),说的简单一点,就是一段启动代码,和计算机主板的,BIOS,差不多,但提供的功能区别就相差很大,在,Windows CE,中,,BSP,是驱动程序、,OEM,适应层(,OEM Adaptation Layers,,,OAL,)、硬件抽象层(,HAL,)以及启动设备和使外设正常工作所需,BIOS,文件的集合。,BSP,和,BIOS,区别,BIOS,主要是负责在电脑开启时检测、初始化系统设备(设置栈指针,中断分配,内存初始化,.,)、装入操作系统并调度操作系统向硬件发出的指令。,BSP,是和操作系统绑在一起运行,尽管,BSP,的开始部分和,BIOS,所做的工作类似,但是,BSP,还包含和系统有关的基本驱动,BIOS,程序是用户不能更改,编译编程的,只能对参数进行修改设置,但是程序员还可以编程修改,BSP,,在,BSP,中任意添加一些和系统无关的驱动或程序,甚至可以把上层开发的统统放到,BSP,中,不同系统中的,BSP,一个嵌入式操作系统针对不同的,CPU,,会有不同的,BSP,即使同一种,CPU,,由于外设的一点差别,BSP,相应的部分也不一样,BSP,的特点与功能,硬件相关性,因为嵌入式实时系统的硬件环境具有应用相关性,所以,作为高层软件与硬件之间的接口,,BSP,必须为操作系统提供操作和控制具体硬件的方法。,操作系统相关性,不同的操作系统具有各自的软件层次结构,因此,不同的操作系统具有特定的硬件接口形式。,BSP,的设计与实现,为实现上述两部分功能,设计一个完整的,BSP,需要完成两部分工作:,(,1,)设计初始化过程,完成嵌入式系统的初始化;,(,2,)设计硬件相关的设备驱动,完成操作系统及应用程序对具体硬件的操作。,嵌入式系统初始化以及,BSP,的功能,嵌入式系统的初始化过程是一个同时包括硬件初始化和软件初始化的过程;而操作系统启动以前的初始化操作是,BSP,的主要功能之一,初始化过程总可以抽象为三个主要环境,按照自底向上、从硬件到软件的次序依次为:片级初始化、板级初始化和系统级初始化。,初始化过程,片级初始化:,主要完成,CPU,的初始化,包括设置,CPU,的核心寄存器和控制寄存器,,CPU,核心工作模式以及,CPU,的局部总线模式等。片级初始化把,CPU,从上电时的缺省状态逐步设置成为系统所要求的工作状态。这是一个纯硬件的初始化过程。,板级初始化:,完成,CPU,以外的其他硬件设备的初始化。除此之外,还要设置某些软件的数据结构和参数,为随后的系统级初始化和应用程序的运行建立硬件和软件环境。这是一个同时饮食软硬件两部分在内的初始化过程。,系统级初始化:,这是一个以软件初始化为主的过程,主要进行操作系统初始化。,BSP,将控制转交给操作系统,由操作系统进行余下的初始化操作。包括加载和初始化与硬件无关的设备驱动程序,建立系统内存区,加载并初始化其他系统软件模块,比如网络系统、文件系统等;最后,操作系统创建应用程序环境并将控制转交给应用程序的入口。,硬件相关的设备驱动程序,BSP,另一个主要功能是硬件相关的设备驱动。,与初始化过程相反,硬件相关的设备驱动程序的初始化和使用通常是一个从高层到底层的过程。,尽管,BSP,中包含硬件相关的设备驱动程序,但是这些设备驱动程序通常不直接由,BSP,使用,而是在系统初始化过程中由,BSP,把它们与操作系统中通用的设备驱动程序关联起来,并在随后的应用中由通用的设备驱动程序调用,实现对硬件设备的操作。,BSP,开发的前提和步骤,开发的前提 :,熟悉硬件方面:使用,CPU,等,熟悉工具方面:电表,示波器,逻辑分析仪,硬件仿真器,仿真调试环境。,语言方面:汇编语言,,C,语言。,BSP,开发的一般步骤如下:,硬件主板研制,测试。,操作系统的选定,,BSP,编程。,上层应用程序的开发。,编写函数,对板卡中每个芯片的操作都通过多个函数来完成,如果应用程序对板卡的操作都直接通过调用中的函数来完成,那将很不利于源程序的调试 ,并降低了程序的可移植性,把能完成某个特定功能的函数封装在一个库文件中,并放在应用程序与之间,对每个芯片来说,都应当有初始化函数和状态读取函数,设计实现,BSP,的一般方法,BSP,的开发需要具备一定的硬件知识,要求掌握操作系统所定义的,BSP,接口,两种快捷方法,以经典,BSP,为参考,使用操作系统提供的,BSP,模板,设计实现,BSP,两部分功能时应采用以下两种不同方法,“自底向上”地实现,BSP,中的初始化操作,“自顶向下”地设计硬件相关的驱动程序,BSP,设计方法的不足与改进,目前,BSP,的设计与实现主要是针对某些特定的文件进行修改,直接修改相关文件容易造成代码的不一致性,增加软件设计上的隐形错误,从而增加系统调试和代码维护的难度,解决这个问题的一个可行办法是:设计实现一种具有图形界面的,BSP,开发设计向导,由该向导指导设计者逐步完成,BSP,的设计和开发,并最终由向导生成相应的,BSP,文件,而不再由设计人员直接对源文件进行修改。,驱动程序,嵌入式,Linux,驱动程序开发,常用的系统支持,Linux,系统网络设备驱动程序,编写,Linux,网络驱动程序中需要注意的问题,LINUX,驱动开发,Agenda,基本原理,内核模块,设备驱动的结构,Linux 2.6,内核设备模型,中断处理,各种接口设计与驱动开发实例,Linux,系统驱动,Linux,中设备被抽象出来,所有设备都看成文件,设备的读写和普通文件一样,设备驱动程序主要完成这些功能:,探测设备和初始化设备,从设备接收数据并提交给内核,从内核接收数据送到设备,检测和处理设备错误,Linux,设备驱动程序分类,Linux,系统的设备分为字符设备,(char device),,块设备,(block device),和网络设备,(network device),三种,字符设备是指存取时没有缓存的设备。,块设备的读写都有缓存来支持,并且块设备必须能够随机存取,(random access),网络设备在,Linux,里做专门的处理,编写驱动程序的一些基本概念,读写,几乎所有设备都有输入和输出。每个驱动程序要负责本设备的读写操作。操作系统的其他不需要知道对设备的具体读写操作怎样进行,这些都由驱动程序屏蔽掉了。操作系统定义好一些读写接口,由驱动程序完成具体的功能。在驱动程序初始化时,需要把具有这种接口的读写函数注册进操作系统。,中断,中断在现代计算机结构中有重要的地位。操作系统必须提供驱动程序响应中断的能力。一般是把一个中断处理程序注册到系统中去。操作系统在硬件中断发生后调用驱动程序的处理程序。,Linux,支持中断的共享,即多个设备共享一个中断。,时钟,在实现驱动程序时,很多地方会用到时钟。如某些协议里的超时处理,没有中断机制的硬件的轮询等。操作系统应为驱动程序提供定时机制。一般是在预定的时间过了以后回调注册的时钟函数。,LINUX,设备的分类,字符设备,串口,终端,触摸屏,ls,-l /dev/ttyS0,crw-rw-rw,- 1 root,uucp,4, 64 4,月,1 19:56 /dev/ttyS0,块设备,FLASH,,,RAMDISK,,硬盘,ls,-l /dev/mtdblock3,brw-r-r,- 1 505,505,31, 3 Feb 19 2005 /dev/mtdblock3,网络设备,ifconfig,-a,设备文件与设备号,用户通过设备文件访问设备,每个设备用一个主设备号和次设备号标识,设备驱动的功能,管理,I/O,设备,上层软件的抽象操作与设备操作的转换,内核模块,Linux,内核运行时动态扩展的一种技术,一组可以动态加载,/,卸载的代码,Linux,驱动以内核模块的方式实现,LINUX,内核模块的框架,static,int,init_routine,(void),void,cleanup_routine(void,),module_init(init_routine,);,module_exit(cleanup_routine,);,MODULE_LICENSE(GPL);,内核模块的编译和加载,Kconfig,Makefile,Kconfig,与,Makefile,的关系,Kconfig,语法,config ,config options,类型定义,依赖性定义,帮助定义,Kconfig,示例,Makefile,示例,定义示例,obj-y,+=,hello.o,obj-m,+=,hello.o,obj,-$(CONFIG_HELLO_MODULE) +=,hello.o,编译,make -C M = $PWD modules,设备驱动的结构,驱动与内核的接口,注册,/,卸载,VFS,接口,数据交互,中断注册,硬件设备接口,硬件探测,初始化,读写访问,设备控制,设备驱动与,VFS,的接口,简单字符设备驱程的框架,static,struct,file_operations,driver_fops,= ,;,int,_init,init_routine,(void),cdev_add,();,return 0;,void,cleanup_routine(void,),cdev_del,();,内核与用户空间数据交换方法,copy_to_user(void,_user *to, const void *from, unsigned long n);,copy_from_user(void,*to, const void _user *from, unsigned long n);,Linux 2.6,内核设备模型,Linux 2.6,内核在整个系统范围内对硬件设备进行抽象,建立了一个统一的设备模型,四个重要的数据结构,struct,kobject,struct,kset,struct,kobj_type,struct,subsystem,什么是中断,Linux,中的中断处理,中断处理程序的编写,中断处理程序的注册与释放,中断处理,工作推后执行的机制,中断处理程序要求短小,处理快。,为了尽快处理中断,以免发生中断丢失,实时性要求不高的工作推后执行。,给,LINUX,带来实时性不好恶名的,bottom half,机制在,2.6,内核中已不再使用。,工作推后执行的机制,软中断,Tasklet,工作队列,(work queue),软中断,执行频率或连续性要求很高的强实时性系统工作,一般不用。,HI_SOFTIRQ,优先级高的,tasklets,TIMER_SOFTIRQ,定时器软中断,NET_TX_SOFTIRQ,网络数据包,TX,NET_RX_SOFTIRQ,网络数据包,RX,SCSI_SOFTIRQSCSI,软中断,TASKLET_SOFTIRQ,tasklets,软中断,tasklets,最常用的延迟执行机制,与软中断类似,通过软中断实现,接口更简单,工作队列,(work queue),将工作交给内核线程执行,允许重新调度或睡眠,通常可以用内核线程代替,与,tasklet,使用的区别,若推后执行的任务不需要休眠,taklet/softirq,内核模块,模块是内核的一部分,但是并没有被编译到内核里去。它们被分别编译和连接成目标文件。,用命令,insmod,插入一个模块到内核中,用命令,rmmod,卸载一个模块,在,Linux,内核中,以下内容一般编译成模块:,大多数的驱动程序。包括,SCSI,设备,,CD-ROM,,网络设备,不常用的字符设备,如打印机,,watchdog,等。,大多数文件系统,理论上除了根文件系统不能是模块,其他文件系统都可以是模块。,一些内核支持的不常用的可执行文件格式,如,binfmt_misc,。,kmod,和高级模块化,Linux,提供了对模块自动加载和卸载的支持,要利用这一特性,在编译内核前进行的配置中,必须打开对,kmod,的支持选项。,一旦内核试图访问某种资源并发现该资源不可用时,它会对,kmod,子系统进行一次特殊的调用而不仅仅是返回一个错误,按需加载的例子 :,ALSA,(,Advanced Linux Sound Architecture,)声卡驱动程序组的实现,常用的系统支持,内存申请和释放,中断,时钟,I/O,中断打开关闭,打印信息,注册驱动程序,内存申请和释放,include/,linux/kernel.h,里声明了,kmalloc,(),和,kfree,(),。用于在内核模式下申请和释放内存。,与用户模式下的,malloc,(),不同,,kmalloc,(),申请空间有大小限制。长度是,2,的整次方。可以申请的最大长度也有限制。另外,kmalloc,(),有,priority,参数,Kfree,(),释放的内存必须是,kmalloc,(),申请的,申请中断和释放中断,request_irq,(),、,free_irq,(),是驱动程序申请中断和释放中断的调用。,在,include/,linux/sched.h,里声明,时钟,时钟的处理类似中断,也是登记一个时间处理函数,在预定的时间过后,系统会调用这个函数。,在,include/,linux/timer.h,里声明,使用时钟,先声明一个,timer_list,结构,调用,init_timer,对它进行初始化。,Time_list,结构里,expires,是标明这个时钟的周期,单位采用,jiffies,的单位。,I/O,I/O,端口的存取使用:,inline unsigned,int,inb(unsigned,short port);,inline unsigned,int,inb_p(unsigned,short port);,inline void,outb(char,value, unsigned short port);,inline void,outb_p(char,value, unsigned short port);,在,include/,adm/io.h,里定义,中断打开关闭,系统提供给驱动程序开放和关闭响应中断的能力,是在,include/,asm/system.h,#define,cli,() _,asm,_ _volatile_ (,cli,:),#define,sti,() _,asm,_ _volatile_ (,sti,:),打印信息,驱动程序要输出信息使用,printk,(),include/,linux/kernel.h,里声明,注册驱动程序,如果使用模块,(module),方式加载驱动程序,需要在模块初始化时把设备注册到系统设备表里去,不再使用时,把设备从系统中卸除,定义在,drivers/net/,net_init.h,里的两个函数完成这个工作,Int,register_netdev(struct,device *dev);,void,unregister_netdev(struct,device *dev);,网络驱动程序的结构,所有的,Linux,网络驱动程序遵循通用的接口,设计时采用的是面向对象的方法,一个设备就是一个对象,(device,结构,),,它内部有自己的数据和方法,一个网络设备最基本的方法有初始化、发送和接收,网络驱动程序的基本方法,初始化,(initialize),打开,(open),关闭,(stop,),发送,(,hard_start_xmit,),接收,(reception),硬件帧头,(,hard_header,),地址解析,(,xarp,),参数设置和统计数据,网络驱动程序中用到的数据结构,最重要的是网络设备的数据结构。定义在,include/,linux/netdevice.h,sk_buff,Linux,网络各层之间的数据传送都是通过,sk_buff,编写,Linux,网络驱动程序中需要注意的问题,中断共享,硬件发送忙时的处理,流量控制,(flow control),调试,硬件抽象层的引入,嵌入式实时系统自底向上包含三个部分,硬件环境,嵌入式实时操作系统,RTOS,嵌入式实时应用程序,由于嵌入式系统应用的硬件环境差异较大,新增加的中间层次位于操作系统和硬件之间,包含了系统中与硬件相关的大部分功能 ,隐蔽了底层硬件的多样性,HAL,简介,硬件抽象层(,HAL,)是体系结构相关的底层程序,处理系统启动、硬件初始化以及中断与异常,硬件抽象层对内核其它部分提供统一的调用接口,HAL,可以提供,BSP,规范,提供跨平台可移植性,硬件抽象层接口定义和代码设计特点,硬件抽象层具有与硬件密切相关性,硬件抽象层具有与操作系统无关性,接口定义的功能应包含硬件或系统所需硬件支持的所有功能,接口定义简单明了,太多接口函数会增加软件模拟的复杂性,具有可测性的接口设计有利于系统的软硬件测试和集成,HAL,设计目标,支持多种的国际主流嵌入式芯片,支持数字电视机顶盒、智能手机、数字化音视频、数字仪表等数字化产品中常见外设的驱动,基于甚高端通讯设备的硬件抽象层,能够支持多,CPU,体系结构(,SMP,),以及基于网络元素,NE,的甚高端通讯设备,基于智能手机的硬件抽象层,能够支持以,Intel PCA,体系结构为内核的智能手机、以,Intel EIA,体系结构为内核的智能手机,以及以,Motorola,的,88000,系列为内核的,PDA,基于,IC,卡的汇编级硬件抽象层,能够支持数字电视条件接收,CA,的,8/16/32,位,CPU IC,设计和机器码级汇编抽象层,
展开阅读全文