2022-01-29

GPIO设备驱动测试使用说明-liteos

[TOC]

一、概述

HI3559A芯片的CPU子系统分为两部分,一个是以为A73+A53为主的SOC部分,另一个是为M7为主的Sensor Hub部分,其中SOC子系统与Sensor Hub子系统的外设均采用统一的外设接口,即寄存器组完全一样,并且可以通过地址转换实现跨子系统访问,但是SOC子系统与Sensor Hub子系统的中断系统完全肚子,并不能完全共享中断向量。

主 SOC 子系统支持 19 组 GPIO(General Purpose Input/Output),即 GPIO0~GPIO18。每组 GPIO 提供 8 个可编程的输入输出管脚(GPIO18 只有 4 个)。

Sensor Hub 子系统支持 5 组 GPIO,即 GPIO0~GPIO4。每组 GPIO 提供 8 个可编程的输入输出管脚(GPIO4 只有 2 个)。 每个管脚可以配置为输入或者输出。这些管脚用于生成特定应用的输出信号或采集特定应用的输入信号。作为输入管脚时,GPIO 可作为中断源;作为输出管脚时,每个GPIO 都可以独立地清 0 或置 1。

该文档就GPIO的操作使用以及GPIO的复用功能做详细讲解。

二、 参考文件

GPIO复用功能描述文件《Hi3559A V100_PINOUT_EN.xlsx》

驱动操作使用指南《外围设备驱动 操作指南.pdf》

寄存器相关操作《Hi3559A╱C V100 ultra-HD Mobile Camera SoC 用户指南.pdf》

三、驱动编译

1. 官方GPIO驱动编译

海思官方提供的程序兼容posix接口,实现了部分函数功能,gpio相关的驱动程序源码路径为 drivers/gpio,在编译脚本里指定源码路径与头文件路径,编译成功后,out目录下会生成名为 libgpio.a 的库文件,链接时通过-lgpio 指定对应库文件。

海思官方提供的API函数如下:

gpio_chip_init:GPIO 初始化接口。

gpio_chip_deinit:GPIO 去初始化接口。

gpio_get_direction:获取 GPIO 方向。

gpio_direction_input:设置 GPIO 方向为输入。

gpio_direction_output:设置 GPIO 方向为输出。

gpio_get_value:获取 GPIO 值。

gpio_set_value:设置 GPIO 值。

gpio_irq_register:注册 GPIO 中断。

gpio_set_irq_type:设置 GPIO 中断类型。

gpio_irq_enable:使能 GPIO 中断。

gpio_get_irq_status:获取中断状态。

gpio_clear_irq:清除 GPIO 寄存器中断状态。

但是在posix接口部分只提供了open(),close(),ioctl()函数,因此下面就该部分代码做一定的解读。

#include"fcntl.h"#include"linux/kernel.h"#include"fs/fs.h"#include"sys/ioctl.h"#include"gpio.h"#include"gpio_dev.h"structgpio_descriptor*gpio=NULL;staticintgpio_open(structfile*filep){return0;}staticintgpio_close(structfile*filep){return0;}staticintgpio_ioctl(structfile*filep,intcmd,unsignedlongarg){intret=0;structinode*inode=filep->f_inode;structgpio_descriptor*gd=(structgpio_descriptor*)(inode->i_private);if(!gd)    {        gpio_err("gpio_descriptor is null!\n");return-1;    }switch(cmd)    {caseGPIO_SET_DIR:if(gd->ops->setdir)                ret=gd->ops->setdir(gd,(gpio_groupbit_info*)arg);elseret=-1;break;caseGPIO_GET_DIR:if(gd->ops->getdir)                ret=gd->ops->getdir(gd,(gpio_groupbit_info*)arg);elseret=-1;break;caseGPIO_READ_BIT:if(gd->ops->readbit)                ret=gd->ops->readbit(gd,(gpio_groupbit_info*)arg);elseret=-1;break;caseGPIO_WRITE_BIT:if(gd->ops->writebit)                ret=gd->ops->writebit(gd,(gpio_groupbit_info*)arg);elseret=-1;break;default:ret=-1;    }returnret;}conststructfile_operations_vfs gpio_dev_ops={    gpio_open,/* open */gpio_close,/* close */0,/* read */0,/* write */0,/* seek */gpio_ioctl/* ioctl */#ifndef CONFIG_DISABLE_POLL,0/* poll */#endif};

如上述代码所示:posix驱动部分只实现了open(),close(),ioctl()函数,其中open(),close()函数未做任何操作,ioctl()支持GPIO_SET_DIR,GPIO_GET_DIR,GPIO_READ_BIT,GPIO_WRITE_BIT等操作。

在liteos代码目录下直接执行make便可以实现该部分代码的编译。

2.GPIO复用功能拓展

GPIO除了设计为GPIO功能之外,有时候还会设计为其他功能,例如uart,spi,PWM等,因此根据实际情况,可以选择使用作为第二功能。该部分寄存器位于《Hi3559A V100_PINOUT_EN.xlsx》中。

新建hal_gpioaf.c,hal_gpioaf.h。

hal_gpioaf.h

#ifndef __HAL_GPIOAF_H__#define __HAL_GPIOAF_H__#include"hal.h"#define IOREGL(N)              (0x1F000000 + N * 4)#define IOREGM(N)              (0x1F001000 + (N - 76) * 4)#define IOREGH(N)              (0x1F002000 + (N - 138) * 4)#define IOREG(N)                (N <= 75 ?  IOREGL(N): IOREGM(N))#define AF_UART0_VAL            0x01#define AF_UART0_TX            IOREG(53)#define AF_UART0_RX            IOREG(54)#define AF_UART1_VAL            0x01#define AF_UART1_TX            IOREG(55)#define AF_UART1_RX            IOREG(56)#define AF_UART2_VAL            0x01#define AF_UART2_TX            IOREG(57)#define AF_UART2_RX            IOREG(58)#define AF_UART3_VAL            0x01#define AF_UART3_TX            IOREG(59)#define AF_UART3_RX            IOREG(60)#define AF_UART4_VAL            0x01#define AF_UART4_TX            IOREG(61)#define AF_UART4_RX            IOREG(62)#define AF_UARTO_Config()      {          \    writeor(AF_UART0_TX, AF_UART0_VAL);    \    writeor(AF_UART0_RX, AF_UART0_VAL);    \}#define AF_UART1_Config()      {          \    writeor(AF_UART1_TX, AF_UART1_VAL);    \    writeor(AF_UART1_RX, AF_UART1_VAL);    \}#define AF_UART2_Config()      {          \    writeor(AF_UART2_TX, AF_UART2_VAL);    \    writeor(AF_UART2_RX, AF_UART2_VAL);    \}#define AF_UART3_Config()      {          \    writeor(AF_UART3_TX, AF_UART3_VAL);    \    writeor(AF_UART3_RX, AF_UART3_VAL);    \}#define AF_UART4_Config()      {          \    writeor(AF_UART4_TX, AF_UART4_VAL);    \    writeor(AF_UART4_RX, AF_UART4_VAL);    \}#endif

上述代码中实现了UART部分的gpio复用功能,如需要实现其他功能的IO复用,可以类似于上述代码编写IO复用函数。

四、 API描述

1. 官方GPIO驱动API

官方提供的posix接口只提供了ioctl函数,其中open,close函数的函数内容均为空,因此仅需要分析ioctl函数即可,ioctl()支持GPIO_SET_DIR,GPIO_GET_DIR,GPIO_READ_BIT,GPIO_WRITE_BIT等操作。

ioctl可配置参数如下:

命令号命令码参数说明

GPIO_SET_DIR4GPIO结构体设置一个GPIO的方向

GPIO_GET_DIR5GPIO结构体获取一个GPIO的设置方向

GPIO_READ_BIT6GPIO结构体读取一个GPIO的电平值

GPIO_WRITE_BIT7GPIO结构体设置一个GPIO的电平值

2.GPIO复用功能拓展

上述的GPIO复用功能拓展提供了五个GPIO函数,如果使用有需要,可以进一步编写相关的代码以实现更多设备的GPIO复用功能支持,上述代码支持的函数如下:

AF_UARTO_Config()//设置相应的GPIO复用功能为UART0

AF_UART1_Config()//设置相应的GPIO复用功能为UART1

AF_UART2_Config()//设置相应的GPIO复用功能为UART2

AF_UART3_Config()//设置相应的GPIO复用功能为UART3

AF_UART4_Config()//设置相应的GPIO复用功能为UART4

五、 应用实例

1.官方GPIO驱动实例

如上图所示:电脑通过网线连接HI3559A板卡,实现程序的烧写与调试,示波器通过探头连接到HI3559A的GPIO上,通过程序设置GPIO的输出电平,在示波器上观察IO点评的变化。

gpio_dev_initopenGPIO_SET_DIRGPIO_WRITE_BITclose

其中gpio_dev_init在liteos初始化时候便已经被调用了,因此使用上述代码只需要执行oepn,ioctl,close等函数,如上分析,新建user_gpio.c、user_gpio.h。

user_gpio.h

#ifndef __USER_GPIO_H__#define __USER_GPIO_H__#include"user.h"#include"gpio.h"voiduser_gpio_initial(void);#endif

user_gpio.c

#include"user_gpio.h"#include"gpio.h"intfd;voiduser_gpio_initial(void){    fd=open("/dev/gpio", O_RDWR);    gpio_groupbit_info group_bit_info;    group_bit_info.groupnumber=3;    group_bit_info.bitnumber=6;    group_bit_info.direction=GPIO_DIR_OUT;    ioctl(fd, GPIO_SET_DIR,&group_bit_info);while(1){        LOS_Msleep(10);        group_bit_info.value=GPIO_VALUE_HIGH;        ioctl(fd, GPIO_WRITE_BIT,&group_bit_info);        LOS_Msleep(10);        group_bit_info.value=GPIO_VALUE_LOW;        ioctl(fd, GPIO_WRITE_BIT,&group_bit_info);    }    close(fd);}

2.GPIO复用驱动实例

在使用串口功能时候直接调用API函数即可。

voiduartxxx_initial(){    ...    AF_UARTxxx_Config()    ...    ...}

六、注意事项

官方提供的API不能跨子系统调用,如有必要,需要自行操作寄存器。

注意项目的路径依赖问题。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,254评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,875评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,682评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,896评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,015评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,152评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,208评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,962评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,388评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,700评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,867评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,551评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,186评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,901评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,142评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,689评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,757评论 2 351

推荐阅读更多精彩内容