使用情景
GPIO 除了在应用层中使用外,其实更多的是在其他复杂驱动中调用。比如SD卡驱动中要使用一个GPIO来监测卡的插入与拔出,网卡驱动中需要使用一个GPIO来控制phy芯片硬复位,某些情况需要用GPIO来模拟I2C总线等等。驱动中使用GPIO时,为了提高效率并不是调用GPIO设备文件,而是使用SylixOS提供的GPIO调用接口。
GPIO API
/*********************************************************************************************************
GPIO API (以下 API 仅供驱动程序内部使用, 应用程序不可使用)
*********************************************************************************************************/
LW_API VOID API_GpioInit(VOID);
LW_API INT API_GpioChipAdd(PLW_GPIO_CHIP pgchip);
LW_API INT API_GpioChipDelete(PLW_GPIO_CHIP pgchip);
LW_API PLW_GPIO_CHIP API_GpioChipFind(PVOID pvData, BOOL (*pfuncMatch)(PLW_GPIO_CHIP pgchip, PVOID pvData));
LW_API INT API_GpioIsValid(UINT uiGpio);
LW_API INT API_GpioHasDrv(UINT uiGpio);
LW_API INT API_GpioRequest(UINT uiGpio, CPCHAR pcLabel);
LW_API INT API_GpioRequestOne(UINT uiGpio, ULONG ulFlags, CPCHAR pcLabel);
LW_API VOID API_GpioFree(UINT uiGpio);
LW_API INT API_GpioRequestArray(PLW_GPIO pgArray, size_t stNum);
LW_API VOID API_GpioFreeArray(PLW_GPIO pgArray, size_t stNum);
LW_API INT API_GpioGetFlags(UINT uiGpio, ULONG *pulFlags);
LW_API VOID API_GpioOpenDrain(UINT uiGpio, BOOL bOpenDrain);
LW_API VOID API_GpioOpenSource(UINT uiGpio, BOOL bOpenSource);
LW_API INT API_GpioSetDebounce(UINT uiGpio, UINT uiDebounce);
LW_API INT API_GpioSetPull(UINT uiGpio, UINT uiType);
LW_API INT API_GpioDirectionInput(UINT uiGpio);
LW_API INT API_GpioDirectionOutput(UINT uiGpio, INT iValue);
LW_API INT API_GpioGetValue(UINT uiGpio);
LW_API VOID API_GpioSetValue(UINT uiGpio, INT iValue);
LW_API ULONG API_GpioGetIrq(UINT uiGpio, BOOL bIsLevel, UINT uiType);
LW_API ULONG API_GpioSetupIrq(UINT uiGpio, BOOL bIsLevel, UINT uiType);
LW_API VOID API_GpioClearIrq(UINT uiGpio);
LW_API irqreturn_t API_GpioSvrIrq(UINT uiGpio);
同时系统还对这些API函数进行了宏定义
#define gpioInit API_GpioInit
#define gpioChipAdd API_GpioChipAdd
#define gpioChipDelete API_GpioChipDelete
#define gpioChipFind API_GpioChipFind
#define gpioIsValid API_GpioIsValid
#define gpioHasDrv API_GpioHasDrv
#define gpioRequest API_GpioRequest
#define gpioRequestOne API_GpioRequestOne
#define gpioFree API_GpioFree
#define gpioRequestArray API_GpioRequestArray
#define gpioFreeArray API_GpioFreeArray
#define gpioGetFlags API_GpioGetFlags
#define gpioOpenDrain API_GpioOpenDrain
#define gpioOpenSource API_GpioOpenSource
#define gpioSetDebounce API_GpioSetDebounce
#define gpioSetPull API_GpioSetPull
#define gpioDirectionInput API_GpioDirectionInput
#define gpioDirectionOutput API_GpioDirectionOutput
#define gpioGetValue API_GpioGetValue
#define gpioSetValue API_GpioSetValue
#define gpioGetIrq API_GpioGetIrq
#define gpioSetupIrq API_GpioSetupIrq
#define gpioClearIrq API_GpioClearIrq
#define gpioSvrIrq API_GpioSvrIrq
常用接口
一般使用GPIO也就是读取一下输入电平或控制输出电平,不需要太复杂的操作,只需要调用下面4个函数即可。
/*********************************************************************************************************
** 函数名称: API_GpioRequestOne
** 功能描述: 请求使用一个 GPIO
** 输 入 : uiGpio 请求 GPIO 号
** ulFlags 需要设置的属性
** pcLabel 标签
** 输 出 : ERROR_NONE or PX_ERROR
*********************************************************************************************************/
LW_API INT API_GpioRequestOne(UINT uiGpio, ULONG ulFlags, CPCHAR pcLabel);
/*********************************************************************************************************
** 函数名称: API_GpioGetValue
** 功能描述: 获取指定 GPIO 的值
** 输 入 : uiGpio GPIO 号
** 输 出 : GPIO 当前电平状态 1: 高电平 0: 低电平
** 注 意 : 此函数不做任何参数有效性判断, 所以用户必须保证 uiGpio 已经请求成功, 方向与其他参数设置正确.
*********************************************************************************************************/
LW_API INT API_GpioGetValue(UINT uiGpio);
/*********************************************************************************************************
** 函数名称: API_GpioSetValue
** 功能描述: 设置指定 GPIO 的值
** 输 入 : uiGpio GPIO 号
** iValue 1: 高电平 0: 低电平
** 输 出 : NONE
** 注 意 : 此函数不做任何参数有效性判断, 所以用户必须保证 uiGpio 已经请求成功, 方向与其他参数设置正确.
*********************************************************************************************************/
LW_API VOID API_GpioSetValue(UINT uiGpio, INT iValue);
/*********************************************************************************************************
** 函数名称: API_GpioFree
** 功能描述: 释放使用一个 GPIO
** 输 入 : uiGpio GPIO 号
** 输 出 : NONE
*********************************************************************************************************/
LW_API VOID API_GpioFree(UINT uiGpio);
这些 API 都是内核态下接口,仅能在驱动程序内部使用, 用户态下应用程序中不可使用。使用前需要包含 “SylixOS.h” 头文件。
首先调用 API_GpioRequestOne
函数,打开并按照 ulFlags
参数初始化GPIO。只有打开GPIO后才能调用其他接口函数。后面就可以根据GPIO是输入还是输出模式去分别调用 API_GpioGetValue
或 API_GpioSetValue
函数进行操作了。如果该GPIO不再使用,需要调用 API_GpioFree
函数进行释放。
ulFlags
参数与 gpiofd
函数的 flags
参数相似,用于配置GPIO相关的一些属性。具体有如下选项:
#define LW_GPIOF_DIR_OUT (0 << 0)
#define LW_GPIOF_DIR_IN (1 << 0)
#define LW_GPIOF_INIT_LOW (0 << 1)
#define LW_GPIOF_INIT_HIGH (1 << 1)
#define LW_GPIOF_IN (LW_GPIOF_DIR_IN)
#define LW_GPIOF_OUT_INIT_LOW (LW_GPIOF_DIR_OUT | LW_GPIOF_INIT_LOW)
#define LW_GPIOF_OUT_INIT_HIGH (LW_GPIOF_DIR_OUT | LW_GPIOF_INIT_HIGH)
#define LW_GPIOF_OPEN_DRAIN (1 << 2)
#define LW_GPIOF_OPEN_SOURCE (1 << 3)
演示例程
/*********************************************************************************************************
**
** 中国软件开源组织
**
** 嵌入式实时操作系统
**
** SylixOS(TM) LW : long wing
**
** Copyright All Rights Reserved
**
**--------------文件信息--------------------------------------------------------------------------------
**
** 文 件 名: gpioDrvExample1.c
**
** 创 建 人: Hou.JinYu (侯进宇)
**
** 文件创建日期: 2017 年 12 月 13 日
**
** 描 述: gpio 在驱动中的调用例程,针对NXP i.MX-RT1050 EVK开发版。
** 因为连接板载 LED01 的引脚同时也连接了 enet 的复位脚,硬件冲突故不能使用。
** LED02 只是一个空闲的gpio(为J22.7),需要用户连接LED或万用表来检测电平变化。
*********************************************************************************************************/
#define __SYLIXOS_KERNEL
#include "stdio.h"
#include "SylixOS.h"
#include "gpio/gpio.h"
/*********************************************************************************************************
引脚宏定义
********************************************************************************************************/
#define KEY08 GPIO_E_00 /* GPIO5--00 */
#define LED01 GPIO_A_09 /* GPIO1--09 */
#define LED02 GPIO_A_18 /* GPIO1--18 */
/*********************************************************************************************************
** 函数名称: gpioDrvExample1
** 功能描述: gpio 轮询读取例程
** 输 入: NONE
** 输 出: ERROR_CODE
*********************************************************************************************************/
INT gpioDrvExample1 (VOID)
{
UINT8 ucValue;
printf("Gpio poll example. Waiting press the key SW8.\n");
API_GpioRequestOne(KEY08, LW_GPIOF_IN, "KEY08");
API_GpioRequestOne(LED02, LW_GPIOF_OUT_INIT_LOW, "LED02");
while (1) {
ucValue = API_GpioGetValue(KEY08); /* 读取当前按键值 */
printf("The key value = %d\n", ucValue);
API_GpioSetValue(LED02, ucValue); /* 设置LED引脚输出 */
sleep(1);
}
API_GpioFree(KEY08);
API_GpioFree(LED02);
return (ERROR_NONE);
}
/*********************************************************************************************************
END
*********************************************************************************************************/
实现效果和 《在应用层使用GPIO》中的 gpioExample1 例程的一样。