ZYNQ7000基于linux3.0操作系统驱动分析——GPIO驱动第二天

GPIO驱动是通过GPIOLIB通用架构实现。GPIOLIBlinux下统一管理gpio设备的架构接口,在linuxmenuconfig下选择:

          ----GPIO Support

               /SYS/CLASS/GPIO/...(SYSFS INTERFACE)

就可以进行GPIOLIB的统一管理。驱动代码源文件drivers\gpio\xilinx_gpiops.c

gpiops.c首先注册初始化一个设备xgpiops:

static int__init xgpiops_init(void)

{

         returnplatform_driver_register(&xgpiops_driver);

}

subsys_initcall(xgpiops_init);

然后在xgpiops_probe()函数里增加对gpio_chip结构添加,这个结构实际上也是一个抽象的GPIO控制器:

chip =&gpio->chip;

//标签

chip->label= "xgpiops"; 

//模块指针

chip->owner= THIS_MODULE;                

//可选的设备结构

chip->dev= &pdev->dev;

//获取相应偏移脚的值

chip->get= xgpiops_get_value;

//设置相应偏移脚的输出值

chip->set= xgpiops_set_value;

//配置偏移脚为输入引脚

chip->direction_input= xgpiops_dir_in;

//配置偏移脚为输出引脚

chip->direction_output= xgpiops_dir_out;

//未选DEBUGFS,所以不配置

chip->dbg_show= NULL;

//gpio_chip管理的第一个GPIO的编号

chip->base= 0;                  /* default pin base*/

//gpio_chip管理的GPIO数目

chip->ngpio= 246;

//是否有睡眠功能

         chip->can_sleep= 0;

这样配置后,GPIO控制器就根据应用程序的调用语句或者shell的输入命令来对对应的GPIO口进行操作。使用GPIOLIB管理后,多了SYS/CLASS/GPIO文件夹以方便对指定GPIO脚进行操作。参考linux内核文档可知,SYS/CLASS/GPIO有以下三种类型入口:

         --用户空间控制GPIO的接口(第一类)

         --对应具体的GPIO接口(第二类)

         --GPIO控制器(“GPIO_CHIP”实例)(第三类)

默认情况下,SYS/CLASS/GPIO下已经有两类接口:

         --exportunexport(第一类):

                   --export:用户空间通过写入GPIO编号来向内核申请指定GPIO控制权导出到用户空间。

                   --unexport:和导出效果相反。

         --gpiochip0(第三类):申请的gpio控制器信息,“0”指管理的第一个gpio编号,与chip->base值一致。

我们在ZYNQ QEMUZYNQ QEMU为了调试方便,把GPIO0~7脚和GPIO54~61依次连接起来,以下实例是用GPIO0GPIO54作例子)下进行测试,输入命令:

echo 0 > export

echo 54 > export

分别为0号和54GPIO创建节点。我们会发现在SYS/CLASS/GPIO下会多了两个GPIO接口,这些就是刚才提到的第二类接口:

进入gpio0可以看到:

其中主要的属性是:

                   --direction:写入“OUT”,设置成输出接口;写入“IN”,设置成输入接口。

                   --value:读取结果是01。如果端口配置成输出,此值可写入,任何非零值都将输出高电平。

                   --active_low:读取结果01。写入任何非零值将反转“value”中读取和写入的值。

继续在ZYNQ QEMU下测试,输入命令:

echo out > gpio0/direction

echo in > gpio54/direction

分别设置gpio0为输出和设置gpio54为输入。

cat gpio54/value

cat gpio0/value

echo 1 > gpio0/value

cat gpio54/velue

输出结果是:

可以看出从GPIO54输出了设定值。如果能直接接硬件通过NFS等手段控制,测试效果更好。

以上可看出,用GPIOLIB统一管理,能在命令行中方便使用指令控制指定的GPIO信号。如果在应用程序中配置操作GPIO,系统也提供了方便的调用手段。查看XILINX提供的测试工程sobel_qt中,查看hwi.c

voidgpio_reset(int level)

{

         // reset TPG

         gpio_export(TPG_RST_PIN);

         gpio_dir_out(TPG_RST_PIN);

         gpio_value(TPG_RST_PIN, level);

         gpio_unexport(TPG_RST_PIN);

         // reset SOBEL

         gpio_export(SOBEL_RST_PIN);

         gpio_dir_out(SOBEL_RST_PIN);

         gpio_value(SOBEL_RST_PIN, level);

         gpio_unexport(SOBEL_RST_PIN);

         // set the external clock for the

         gpio_export(EXT_SYNC_PIN);

         gpio_dir_out(EXT_SYNC_PIN);

         gpio_value(EXT_SYNC_PIN, gLiveVideoOn);

         gpio_unexport(EXT_SYNC_PIN);

}

以上代码片段实际上是进行一些GPIO脚复位操作。主要函数是:

--gpio_export(unsigned gpio):导出控制权,效果与export命令一样。

--gpio_dir_out(unsigned gpio):指定端口为输出,效果与out命令一样。

--gpio_dir_in(unsigned gpio):指定端口为输入,效果与in命令一样。

--gpio_value(unsigned gpio,unsigned value):指定输出值。

--gpio_unexport(unsignedgpio):解除导出控制权,效果与unexport命令一样。

你可能感兴趣的:(ZYNQ)