AliOS Things 硬件抽象层(HAL)对接系列1 — GPIO driver porting

简介: HAL层(Hardware abstraction layer 硬件抽象层) 的目的是为了屏蔽底层不同芯片平台的差异,从而使驱动层上面的软件不会随芯片平台而改变。AliOS Things定义了全面的HAL抽象层,这个系列主要介绍AliOS ThingsHAL层与不同芯片平台对接的poring要点,并举例说明。

HAL层(Hardware abstraction layer 硬件抽象层) 的目的是为了屏蔽底层不同芯片平台的差异,从而使驱动层上面的软件不会随芯片平台而改变。AliOS Things定义了全面的HAL抽象层,这个系列主要介绍AliOS ThingsHAL层与不同芯片平台对接的poring要点,并举例说明。

Hal 对接系列1 —— Gpio driver porting

一. 接口定义说明

gpio 对外接口定义在 include/hal/soc下面,接口函数主要有以下几个:

int32_t hal_gpio_init(gpio_dev_t *gpio)
int32_t hal_gpio_output_high(gpio_dev_t *gpio);
int32_t hal_gpio_output_low(gpio_dev_t *gpio);
int32_t hal_gpio_output_toggle(gpio_dev_t *gpio);
int32_t hal_gpio_input_get(gpio_dev_t *gpio, uint32_t *value);
int32_t hal_gpio_enable_irq(gpio_dev_t *gpio, gpio_irq_trigger_t trigger, gpio_irq_handler_t handler, void *arg);
int32_t hal_gpio_disable_irq(gpio_dev_t *gpio);
int32_t hal_gpio_clear_irq(gpio_dev_t *gpio);
int32_t hal_gpio_finalize(gpio_dev_t *gpio)

其中,结构体gpio_dev_t 定义为:

typedef struct {
    uint8_t       port;           /* gpio port */
    gpio_config_t config;  /* gpio config */
    void         *priv;           /* priv data */
} gpio_dev_t;

接口函数的含义清晰明了,这里用户有两种方式可以调用驱动:

  1. 直接调用接口函数,常用于对gpio驱动的二次封装,如在lcd驱动中调用gpio进行相关操作;
  2. 通过vfs虚拟文件系统进行操作,即使用open, read, write, ioctl等标准接口进行。

二. 接口使用说明

二者调用方式在hal层没有显著区别。以第一种为例:
调用gpio驱动时,首先定义
gpio_dev_t gpio_1 = {KEY_1, OUTPUT, &value}
即使用gpio 的输出功能,可以使用

hal_gpio_output_high(&gpio_1);
hal_gpio_output_low(& gpio_1);
hal_gpio_output_toggle(& gpio_1);

等接口函数操作gpio输出高、低电平或者反转电平。

gpio_dev_t gpio_2 = {KEY_2, INPUT, NULL}
即使用gpio的输入功能,可以使用
hal_gpio_input_get(&gpio_2 , uint32_t *value)
等接口函数操作读取gpio电平值;

gpio_dev_t gpio_3 = {KEY_3, IRQ_MODE, &value}
即使用gpio的输入中断功能,value值为上升沿、下降沿和边沿触发三种模式,
可以使用

hal_gpio_enable_irq(&gpio_3, gpio_irq_trigger_t trigger,                                 
                    gpio_irq_handler_t handler, void *arg);

进行中断初始化,用户还需要自行提供中断处理函数handler,定义如下:
typedef void (gpio_irq_handler_t)(void arg);

具体的操作示例,可以参考aos/example/peri_deiver_test_developerkit/peri_test.c

三. HAL层对接要点

HAL层需要严格按照位于include/hal/soc/gpio.h的实现进行对接, 新建两个文件hal_gpio_xxx.c和hal_gpio_xxx.h,将封装层代码放到这两个文件中,实现上面列出的接口函数。

hal_gpio_init是gpio初始化,不同系列芯片的初始化方式差异较大,我们往往无法直接调用芯片厂商的初始化函数,此时需要对接口进行一些转换以对接芯片厂商的驱动。举例说明。

ST系列:
我们最终需要的gpio初始化接口即:int32_t hal_gpio_init(gpio_dev_t *gpio)
ST系列芯片驱动的gpio初始化接口为:void HAL_GPIO_Init(GPIO_TypeDef GPIOx, GPIO_InitTypeDef GPIO_Init)
其中的结构体GPIO_TypeDef 、GPIO_InitTypeDef 为ST芯片专用的驱动结构体定义,
对接ST系列的gpio驱动时,需要手动对上述结构体进行定义,以满足继续调用ST的驱动的要求:
定义
GPIO_TypeDef *GPIOx;
GPIO_InitTypeDef GPIO_InitStruct;

/伪代码举例/
get_gpio_group(gpio, &GPIOx) 来获取GPIOx
gpio_para_transform(gpio, &GPIO_InitStruct); 来获取 GPIO_InitStruct
(get_gpio_group 和 gpio_para_transform 等函数的实现要点:根据GPIO_TypeDef 和GPIO_InitTypeDef 结构体的定义将 gpio_dev_t 实现转换 ,具体可参考ST驱动源码)
有了GPIOx 和 GPIO_InitStruct,进一步调用ST提供gpio初始化函数 HAL_GPIO_Init

再以NRF系列芯片为例:
NRF系列芯片驱动的gpio初始化接口为:ret_code_t renrf_drv_gpiote_init(void)
对接该系列hal层时,可以直接调用底层驱动,需要注意的是,NRF的gpio初始化分
输入gpio的初始化和输出gpio的初始化,即:

ret_code_t  nrf_drv_gpiote_out_init(nrf_drv_gpiote_pin_t pin,
                nrf_drv_gpiote_out_config_t const * p_config);

ret_code_t  nrf_drv_gpiote_in_init(nrf_drv_gpiote_pin_t  pin,
                 nrf_drv_gpiote_in_config_t const * p_config,
                 nrf_drv_gpiote_evt_handler_t  evt_handler);

这里的 nrf_drv_gpiote_pin_t 、nrf_drv_gpiote_out_config_t 、nrf_drv_gpiote_in_config_t 等结构体定义也是NRF系列专用,对接该系列的gpio驱动时,需要手动对上述结构体进行定义,如:

static nrf_drv_gpiote_out_config_t out_config = GPIOTE_CONFIG_OUT_SIMPLE(false);
static nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(true);

int32_t hal_gpio_init(gpio_dev_t *gpio)
{
    int32_t ret = -1;

    if (!nrf_drv_gpiote_is_init()) {
        ret = nrf_drv_gpiote_init();
         if (ret != NRF_SUCCESS)
            return NRF_ERROR_INTERNAL;
    }

    switch (gpio->config) {
    case OUTPUT_PUSH_PULL:
    case OUTPUT_OPEN_DRAIN_NO_PULL:
    case OUTPUT_OPEN_DRAIN_PULL_UP:
        ret = nrf_drv_gpiote_out_init(gpio->port, &out_config);
        break;
    case IRQ_MODE:
         in_config.pull = NRF_GPIO_PIN_PULLUP;
         ret = nrf_drv_gpiote_in_init(gpio->port, &in_config, gpio->priv);
    default:
        ret = -1;
     break;
   }
    return ret;
}

hal_gpio_output_high、
​hal_gpio_output_low、
​hal_gpio_output_toggle 、
​hal_gpio_input_get
等函数的HAL层对接比较简单,一般在gpio初始化后直接调用相应芯片的驱动即可,
如ST系列: HAL_GPIO_WritePin、HAL_GPIO_ReadPin 进行gpio输入输出操作;
NRF系列:nrf_drv_gpiote_out_set、nrf_drv_gpiote_out_clear、nrf_drv_gpiote_in_is_set进行gpio输入输出操作。

对于gpio的输入中断的对接,ST系列使用了
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)进行gpio输入中断的响应,并在

int32_t hal_gpio_enable_irq(gpio_dev_t *gpio, gpio_irq_trigger_t trigger, gpio_irq_handler_t handler, void *arg)

中定义中断响应的handler 和传入的参数arg,如:

    ret = hal_gpio_enable_irq(&gpio1, IRQ_TRIGGER_RISING_EDGE,  key_handle,  NULL);
    if (ret != 0) {
        printf("hal_gpio_enable_irq key return failed.\n");
    }​

    void key_handle(void *arg) 
    {
          /*key interupt相关操作*/
    }​  ​

与ST不同,NRF系列在使用

ret_code_t nrf_drv_gpiote_in_init(nrf_drv_gpiote_pin_t pin,
                        nrf_drv_gpiote_in_config_t const * p_config,
                          nrf_drv_gpiote_evt_handler_t  evt_handler);

最后一个参数evt_handler来表示中断响应函数,nrf 底层驱动会对这个参数进行判断,如果传入NULL,则表示不使用gpio输入中断功能。

综上所述, hal层porting需要根据不同芯片厂商的驱动的接口来进行。

相关文章
|
消息中间件 移动开发 物联网
3_4_AliOS Things 基础 AOS API 及 HAL API 介绍|学习笔记
快速学习3_4_AliOS Things 基础 AOS API 及 HAL API 介绍。
330 0
3_4_AliOS Things 基础 AOS API 及 HAL API 介绍|学习笔记
|
物联网 中间件
AliOS Things 使用HAL库的USB_DEVICE MSC调用SPI W25Q128
AliOS Things的USB_DEVICE MSC的SPI W25Q128实现
1078 0
|
JavaScript 物联网 芯片
AliOS Things 硬件抽象层(HAL)对接系列3 — I2C driver porting
HAL层(Hardware abstraction layer) 的目的是为了屏蔽底层不同芯片平台的差异,从而使驱动层上面的软件不会随芯片平台而改变。AliOS Things定义了全面的HAL抽象层,这个系列主要介绍AliOS ThingsHAL层与不同芯片平台对接的poring要点,并举例说明。
3253 0
|
JavaScript 物联网 芯片
AliOS Things 硬件抽象层(HAL)对接系列2 — SPI driver porting
HAL层(Hardware abstraction layer) 的目的是为了屏蔽底层不同芯片平台的差异,从而使驱动层上面的软件不会随芯片平台而改变。AliOS Things定义了全面的HAL抽象层,这个系列主要介绍AliOS ThingsHAL层与不同芯片平台对接的poring要点,并举例说明。
2867 0
|
物联网 Linux
【AliOS Things学习笔记】为你的AliOS Things应用增加自定义cli命令
怎么才能在RTOS系统中,通过 串口shell控制LED的开关。
3583 0
|
AliOS-Things 物联网 编译器
使用HaaS Studio开发AliOS Things C/C++应用
本文章将介绍使用HaaS Studio 进行AliOS-Things C/C++应用开发。
使用HaaS Studio开发AliOS Things C/C++应用
|
传感器 存储 移动开发
使用AliOS Things快速构建温度计应用 |《AliOS Things快速开发指南》
本文是基于AliOS Things 3.1快速构建温度计的应用场景。涉及AliOS Things组件开发,构建AliOS Things用户项目,AliOS Things HAL API使用,向AliOS Things中添加并使用组件。用到的硬件设备有半导体开发板、温度传感器、数码管显示器。
使用AliOS Things快速构建温度计应用 |《AliOS Things快速开发指南》
|
域名解析 移动开发 数据可视化
使用 AliOS Things 3.0 快速构建用户应用 BlinkAPP
AliOS Things 3.0版本于去年9月份在云栖大会正式发布,在新版本中带来了全新的应用开发框架,帮助用户快速构建自己的应用。使用户可以更专注于自身应用的开发。本文将已BlinkAPP为例,为大家演示如何快速使用应用开发框创建项目并完成应用代码编写。
910 0
使用 AliOS Things 3.0 快速构建用户应用 BlinkAPP
|
物联网 AliOS-Things 机器人
AliOS Things 3.0 应用笔记:摄像头配网 + 钉钉群通知 + 天气显示
距离 AliOS Things 3.0 上线已经有一段时间了,新版的 AliOS Things 3.0 体验感到底如何呢?本文将为大家详细讲解其应用实例,我们分别从运行流程、效果展示、操作流程以及源码讲解四个方面进行了阐述。
1700 0