Chinaunix首页 | 论坛 | 博客
  • 博客访问: 554692
  • 博文数量: 99
  • 博客积分: 4010
  • 博客等级: 上校
  • 技术积分: 1117
  • 用 户 组: 普通用户
  • 注册时间: 2009-06-23 15:17
文章分类

全部博文(99)

文章存档

2011年(4)

2010年(13)

2009年(82)

我的朋友

分类: LINUX

2009-11-12 11:12:29

HAL层的含义是硬件抽象层,它是位于Linux操作系统内核(包含驱动)与硬件电路之间的接口层,其目的在于将硬件抽象化。它隐藏了特定平台的硬件接口细节,为操作系统提供虚拟硬件平台,使其具有硬件无关性,可在多种平台上进行移植。 从软硬件测试的角度来看,软硬件的测试工作都可分别基于硬件抽象层来完成,使得软硬件测试工作的并行进行成为可能。

1.1 硬件抽象层的介绍

我们之所以要提出这个HAL层是由于现在SEP4020的硬件平台类型很多像EVB系列,MBT系列,MINI4020系列,EPOS系列,这些不同类型的硬件如果想应用我们的SEP4020SDK,那么我们就要为每套平台移植驱动,因为它们的I/O硬件口线都不一样的,所以我们经过讨论认为HAL层可能是解决这个问题的一个比较好的方法。

1.1.1 HAL层的框架

我们的HAL层是位于驱动层和硬件层的中间,它本身是把SEP4020的硬件资源,主要是GPIO口和中断抽象出来了,驱动想用硬件资源就只能到HAL层去申请了,所以在HAL层我们能够看到所有的硬件资源的使用情况,下面我们看下HAL在整个linux中的位置:

 

1.1.2 HAL层的内容介绍

       我们的HAL层由于主要包含两种资源(中断和GPIO),所以我们必须在这里对这两种资源的使用作一个详细说明。

1GPIO口使用

在这里我们将GPIO的使用分成两种类型:第一种是GPIO口单根线的使用,也即bit的操作;第二种是多个bits或整个port的使用,这里我们提供了两组宏来操作两种不同类型,驱动中间是不能直接使用单个和整个port的,只能通过这些宏来操作GPIO的,这样就将他们与具体的硬件分开了。

#define REG32(addr)  (*(volatile unsigned int *)(addr))

/*-------------------------- bit operation------------------------*/

#define SET_BIT(port,bit) REG32(port) |= (1 << bit)       //对单个bit置位

#define CLR_BIT(port,bit) REG32(port) &= (~(1 << bit))   //对单个bit清零

#define GET_BIT(port,bit) (REG32(port) & (1 << bit))     //获取单个bit的值

 

/*-----------port or many bit operation------------------------*/

#define SET_PORT_VALUE(port,value,mask) ({unsigned long res_port = REG32(port); REG32(port) = (res_port & (~mask)) | (value & mask); })     //对没有maskport位赋值value

#define SET_PORT_MASK(port,mask) REG32(port) |= mask   //对没有maskport位置位

#define CLR_PORT_MASK(port,mask) REG32(port) &= (~mask)  //对没有maskport位清零

#define GET_PORT_MASK(port,mask) (REG32(port) & mask)   //获取没有maskport位的值

2)外部中断的使用

       对于外部中断我们也是统一接管的,驱动想使用也是需要在HAL层申请的,这里涉及到两种操作:第一种:中断的申请和配置;第二种:中断的清除

/*--------------------------EXTERN INTERRUPT----------------------------------------*/

/*---------中断类型定义------------------------------------------------------*/

#define RISING_EDGE_TRIG      0x0

#define FALLING_EDGE_TRIG     0x1

#define HIGHT_LEVEL_TRIG      0x2

#define LOW_LEVEL_TRIG        0x3

 

/*----------------------------------中断的申请和配置-------------------------------------------------------*/

#define CONFIG_INT(int_num,int_type)   \

do{    \

       if(int_num == 11){  \

              (*(volatile unsigned long*)GPIO_PORTF_SEL_V) |= 0x0001 ;(*(volatile unsigned long*)GPIO_PORTF_DIR_V) |= 0x0001 ; (*(volatile unsigned long*)GPIO_PORTF_INTRCTL_V) |= int_type;(*(volatile unsigned long*)GPIO_PORTF_INCTL_V) |= 0x0001;(*(volatile unsigned long*)GPIO_PORTF_INTRCLR_V) |= 0x0001;(*(volatile unsigned long*)GPIO_PORTF_INTRCLR_V) = 0x0000;}\

       else if(int_num < 11){      \

              *(volatile unsigned long*)GPIO_PORTA_SEL_V |= 0x1 << (int_num - 1);*(volatile unsigned long*)GPIO_PORTA_DIR_V |= 0x1 << (int_num - 1);*(volatile unsigned long*)GPIO_PORTA_INTRCTL_V |= int_type << ((int_num - 1)*2);*(volatile unsigned long*)GPIO_PORTA_INCTL_V |= 0x1 << (int_num - 1);*(volatile unsigned long*)GPIO_PORTA_INTRCLR_V |= 0x1 << (int_num - 1);*(volatile unsigned long*)GPIO_PORTA_INTRCLR_V = 0x0000;}\

}while(0)

 

/*--------------------------------------外部中断的清除------------------------------------------*/

#define CLR_INT(int_num)  \

do{   \

       if(int_num == 11){  \

              *(volatile unsigned long*)GPIO_PORTF_INTRCLR_V |= 0x0001;*(volatile unsigned long*)GPIO_PORTF_INTRCLR_V = 0x0000;}  \

       else if(int_num < 11){   \

              *(volatile unsigned long*)GPIO_PORTA_INTRCLR_V |= 0x1 << (int_num - 1);*(volatile unsigned long*)GPIO_PORTA_INTRCLR_V = 0x0000;}  \

}while(0)

 

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