Chinaunix首页 | 论坛 | 博客
  • 博客访问: 401865
  • 博文数量: 27
  • 博客积分: 470
  • 博客等级: 一等列兵
  • 技术积分: 546
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-24 11:51
文章存档

2016年(12)

2012年(15)

分类: LINUX

2012-05-01 17:32:22

一,硬件抽象层的理解

硬件抽象层(Hardware Abstraction Layer),简称为HAL,是在具体的硬件平台上抽象出来的一个硬件接口层,这个接口层负责实现具体硬件平台的功能和控制,同时又为其它软件模块提供统一的API接口。HAL其产生就是为了将硬件操作和控制的共性抽象出来,向上层软件提供统一操控接口,以实现其它软件模块与底层硬件隔离。有了HAL后,系统在新硬件平台上的移植就变得异常简单,只需提供新硬件的抽象层,就可以将整个eCos系统包括基于eCos的应用移植到新的硬件平台上。

下面我们举个简单的例子来说明一些硬件抽象层(HAL)给嵌入式软件设计带来的好处,下面是arm体系结构里实现的HAL_ENABLE_INTERRUPTS()宏定义的代码:

#define HAL_ENABLE_INTERRUPTS() \

asm volatile ( \

"mrs r3,cpsr;" \

"bic r3,r3,#0xC0;" \

"msr cpsr,r3" \

: \

: \

: "r3" \

);

而如下是Powerpc体系结构下实现的HAL_ENABLE_INTERRUPTS()宏定义的代码:

#define HAL_ENABLE_INTERRUPTS() \

CYG_MACRO_START \

cyg_uint32 tmp1, tmp2; \

asm volatile ( \

"mfmsr %0;" \

"ori %1,%1,0x8000;" \

"rlwimi %0,%1,0,16,16;" \

"mtmsr %0;" \

: "=r" (tmp1), "=r" (tmp2)); \

CYG_MACRO_END

显然,以上宏的调用接口是统一的,但实际的实现方法却因两个体系结构的不同而差别很大,这就是为什么我们要提出硬件抽象层(HAL)的原因.因为它隔离了硬件相关的特性,给其它模块提供硬件无关的统一的结构。

二、硬件抽象层的层次结构

HAL层可细分为:common HAL(通用抽象层)、architecture HAL(体系结构抽象层)、variant HAL(变体抽象层)和platform HAL(平台抽象层)。

体系结构抽象层:eCos所支持的不同处理器系列具有不同的体系结构,如ARM系列、PowerPC系列、MIPS系列等,体系结构抽象层对CPU的基本结构进行抽象和定义,此外它还包括中断的交付处理、上下文切换、CPU启动以及该类处理器结构的指令系统等。

变体抽象层指的是处理器在该处理器系列中所具有的特殊性,这些特殊性包括Cache、MMU、FPU等,eCos的变体抽象层就是对这些特殊性进行抽象和封装。

平台抽象层是对当前系统的硬件平台进行抽象,包括平台的启动、芯片选择和配置、定时设备、I/O寄存器访问以及中断寄存器等。

硬件抽象层的这三个子模块之间没有明显的界线。对于不同的目标平台,这种区分具有一定的模糊性。例如,MMU和Cache可能在某个平台上属于体系结构抽象层,而在另一个平台上则可能属于变体抽象层的范围;再比如,内存和中断控制器可能是一种片内设备而属于变体抽象层,也可能是片外设备而属于平台抽象层。

eCos的移植通过这三个子模块来完成,即平台抽象层的移植、变体抽象层的移植和体系结构抽象层的移植。对一个新的体系结构来说,其体系统结构抽象层的建立相对来说比较困难,需要编写新的体系结构抽象层。eCos支持大部分当前广泛使用的嵌入式CPU,已具有了支持各种体系结构的硬件抽象层。因此,eCos的移植很少需要进行体系结构抽象层的编写。

一般来说,进行eCos开发时,移植的主要工作在于变种抽象层和平台抽象层,这是由于eCos已实现了绝大多数流行嵌入式CPU的体系结构抽象层。其中,平台抽象层主要完成的工作包括:内存的布局、平台早期初始化、中断控制器以及简单串口驱动程序等。

下图是ecos HAL层的架构图:

image

最上层除了common文件夹是所有体系结构公用的外,其它每一个文件夹对于ecos所支持的体系结构中的一种。Common文件夹里包含的内容就是我们所说的通用抽象层的实现。而各个体系结构文件夹下的arch文件夹中的内容就是我们所说的体系结构抽象层的实现。至于变种抽象层一般在命名为/var的文件夹中。而平台抽象层就位于具体开发板命令的文件夹下。

下面我们用一个实际例子来分析一下一个功能在HAL各子层之间的调用关系以及代码在各层中的分配原则,下面的复位过程调用实例采用MIPS Atlas评估板做为目标平台:

image

1,__reset()过程是为所有体系结构定义的一个通用的reset过程,其定义在/hal/common文件夹下的hal_stub.c文件中,是属于通用抽象层。

2,hal_atlas_reset()过程,其定义在/hal/mips/atlas文件夹下的hal_misc.c文件中,是属于平台抽象层部分。

3,平台复位过程利用/hal/mips/atlas文件夹下的plf_io.h文件中的宏HAL_REG()对复位寄存器进行写操作,这是属于变体抽象层部分。

以上复位调用过程可以看出,整个复位过程的实现是如何被分开在各个子抽象层中实现的。

三、HAL在系统启动过程中的体现

要很好的理解HAL功能,就必须了解HAL在启动过程所起的作用,下图是系统启动流程图:

                                   image

1. 当有开机上电事件发生后,硬件开始复位处理。

2. 硬件复位后,处理器跳转到它的复位向量reset_vector,复位向量被定义在arch文件夹下的vector.S中,这个文件包含了同一体系结构下所有HAL包的程序入口点。复位向量完成最少的处理器寄存器的初始化。

3. 复位向量跳转到_start,它在vector.S中实现,是HAL初始化过程的开始点。

4. 过程hal_cpu_init被调用,这个过程的定义根据不同的体系结构在不同的文件中实现,有的在variant.inc文件中,有的在arch.inc中。这个过程对处理器的某些寄存器做初始化,比如关指令和数据缓存。

5. 过程hal_hardware_init被调用,因为这个过程实现的功能与具体平台相关,所以在平台相关的汇编程序文件中实现,通常是platform name.S文件。这个过程实现的功能包含缓存设置,关看门狗,适时时钟和片选设置等。

6. 接下来设置中断的栈空间,为保存中断时处理器的运行现场预留存储空间,至于要为栈预留多大的空间,放在通用初始化部分实现。启动过程临时利用中断栈空间来完成它的初始化。因为这个时候中断使能未开,所以不会出现栈空间的冲突。

7. 过程hal_mon_init被调用,它的实现放在variant.inc或者platform.inc中。当作为ROM monitor或者ROM应用时,主要是保证对处理器支持的各种异常条件安装默认处理。

8. 接下来是清楚BSS段为0,这个段包含了所有未初始化的静态存储变量,包括局部变量和全局变量。

9. 堆栈被设置,以便vectors.S中的汇编代码能调用C语音代码。

10. 过程hal_platform_init被调用,过程在hal_aux.c文件中实现。这个过程又相继调用了hal_if_init,这个函数在hal_if.c文件中实现,这个过程初始化虚拟向量表。

11. 过程hal_MMU_init被调用来初始化MMU,实现逻辑地址向物理地址的转换,同时实现保护和缓存机制。这个过程在hal_misc.c文件中实现,而hal_misc.c文件位于arch文件夹下。

12. 通过调用hal_enable_caches来使能指令和数据cache,这个过程在hal_misc.c文件中实现,而hal_misc.c文件位于arch文件夹下。

13. 调用hal_IRQ_init来设置CPM,这个过程在arch文件夹下的hal_intr.c文件中实现。

14. 全局的c++构造函数被cyg_hal_invoke_constructors调用,这个过程在hal_misc.c文件中实现,而hal_misc.c文件位于arch文件夹下。Linker处理全局构造函数列表的生成。Infra文件夹下的cyg_type.h中定义了相关的宏。

15. 如果这是为了搭建一个调试环境,而ROM monitor又没有提供调试支持,则initialize_stub过程将被调用。这个过程在HAL common文件夹下的generic_stub.c文件里实现。这个过程安装标准的trap处理过程,同时将硬件初始化到调试状态。

16.调用cyg_start,将控制交给kernet。

四、硬件抽象层(HAL)的可配置组件

1.HAL中通用的可配置组件

CYGPKG_HAL_COMMON:组件包含异常处理、MMU表的安装和诊断信息重定向等功能;

CYGPKG_HAL_COMMON_INTERRUPTS:组件包含中断相关的所有配置功能,包括用HAL维护的栈空间、中断嵌套是否使能和中断栈的大小设置。

CYGPKG_HAL_COMMON_CONTEXT:此组件使能特定体系结构相关的上下文切换方式以节省上下文切换的开销。

CYGPKG_HAL_CACHE_CONTROL:此组件运行在系统启动过程中使能指令和数据缓存,如果有其它的平台相关的缓存配置要求,则此选项必须disable.

CYGPKG_HAL_DEBUG:可以选择是否在HAL中包含GDB调试功能。

CYGPKG_HAL_ROM_MONITOR:组件定义了应用和ROM monitor直接的交互接口。

2.HAL中体系结构相关的可配置组件,比如

PowerPC Architecture (CYGPKG_HAL_POWERPC)

PowerPC MPC8xx Variant HAL (CYGPKG_HAL_POWERPC_MPC8xx)

Motorola MBX PowerPC Evaluation Board (CYGPKG_HAL_POWERPC_MBX)

Motorola MBX PowerQUICC Support (CYGPKG_HAL_QUICC)

ARM Architecture (CYGPKG_HAL_ARM)

ARM PID Evaluation Board (CYGPKG_HAL_ARM_PID)

出处注明:本博文的部分内容来源于西安电子科技大学柳林写的一篇论文,名称叫:基于EP9315ARM9开发平台下的redboot移植及串口通信,另外也参考了《embedded software development with ecos》这边英文书。

由于本人也是接触ECOS的新手,可能博文中有表述不准的地方,请大家批评指正,只求达到相互学习共同进步的目的。

阅读(4847) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~