现在的位置: 首页 > 综合 > 正文

Am335x 下GPIO控制实例

2014年03月11日 ⁄ 综合 ⁄ 共 3963字 ⁄ 字号 评论关闭


看了这么多的资料,现在决定上手了,下面将用两种方式来实现对GPIO 117的控制
1,用直接添加到内核的方式,实现MISC的驱动(misc_register)
2,用手工安装的方式,实现简单字符设备驱动(register_chrdev)

实现前提:当前所用的GPIO没有被其它设备所使用,大家可以用我前面BLOG说的方式查看GPIO的使用情况,当前我所用的GPIO本来是bluetooth的开关,需要屏蔽一个函数。不然后面的驱动申请IO都会失败。
函数为Board-am335xevm.c 中的wl12xx_bluetooth_enable();

一,MISC驱动的实现
1,参考linux SDK for AM335x Ver 1.1.pdf P28,添加kernel 配置选项
  打开/driver/input/misc/Kconfig并添加:

  config INPUT_GPIOTEST
  bool "Gpio 117 test"
  help
  Just test the Gpio 117 status

  打开/driver/input/misc/Makefile并添加:
  

 obj-$(CONFIG_INPUT_GPIOTEST)+=GpioTestDriver.o

2,实现GpioTestDriver.c

#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/moduleparam.h>
#include <linux/delay.h>
#include <linux/types.h>
#include <linux/miscdevice.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/init.h>

#define TEST_IO_NUM(117)
#define NAME_MISC"GpioTest"
#define NAME_MOUDULE"GpioTest1"
#define USE_MISC_MODE1
static int major = 251;

void GpioTest(void);

static long GpioIOctl(struct file *filp, unsigned cmd, unsigned long arg)
{
GpioTest();
return 1;
}

void GpioTest(void)
{
int iCount = 0;

for(iCount = 0; iCount <=20; iCount++ )
{
if(iCount%2 == 0)
{
gpio_direction_output(TEST_IO_NUM, 1);
printk(KERN_INFO"#######IO117 statu is high.\r\n");
}
else
{
gpio_direction_output(TEST_IO_NUM, 0);
printk(KERN_INFO"#######IO117 statu is low.\r\n");
}
mdelay(3000);
}
printk(KERN_INFO"#######App run over!");
}



static int GpioOpen(struct inode *inode, struct file *file)
{
int iRen = -1;
iRen = gpio_request(TEST_IO_NUM, "IO117");
if(iRen < 0)
{ 
printk(KERN_INFO"#######Failed to request the IO117!");
}else
{
printk(KERN_INFO"#######Success to request the IO117");
}
return iRen;
}

static int GpioClose(struct inode *inode, struct file *file)
{
printk(KERN_INFO"#######Free the IO117");
gpio_free(TEST_IO_NUM);
return 1;
}

//****entry point for TEST GPIO module
static const struct file_operations gpio_test_driver = {
.owner = THIS_MODULE,
.unlocked_ioctl= GpioIOctl,
.llseek = no_llseek,
.open = GpioOpen,
.release = GpioClose, 
};

#if USE_MISC_MODE
static struct miscdevice gpiotest_misc_device = {
.minor    = MISC_DYNAMIC_MINOR,
.name     = NAME_MISC,
.fops     = &gpio_test_driver,
};
#endif

static int __init GpioTestInit(void)
{
int iRet;
printk(KERN_INFO"#######GpioTest modules is install!\r\n");
#if USE_MISC_MODE
iRet = misc_register(&gpiotest_misc_device);
if (iRet) {
printk(KERN_INFO"#######unable to register a misc device\r\n");
return iRet;
}
#else
iRet = register_chrdev(major, NAME_MOUDULE, &gpio_test_driver);
if (iRet < 0) {
printk(KERN_INFO"#######unable to register a chr device\r\n");
return iRet;
}
#endif

return iRet;
}

static void __exit GpioTestExit(void)
{
#if USE_MISC_MODE
misc_deregister(&gpiotest_misc_device);
#else
unregister_chrdev(major, NAME_MOUDULE);
#endif
printk(KERN_INFO"#######GpioTest modules is exit!\r\n");
}

module_init(GpioTestInit);
module_exit(GpioTestExit);
MODULE_AUTHOR("david.hu<343556608@qq.com>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Gpio117 Test driver");

3,直接编译:
make uImage
拷到小板上升级运行
注意启动的过程有打印:
[    3.730712] #######GpioTest modules is install!
这里表示我们的驱动已经合入NK里去了,当然我们也可以命令:ls /dev,可以看到有GpioTest这个存在
4,写测试APP

#include <stdio.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <linux/input.h>
#include <fcntl.h>

int main(int argc, char *argv)
{
int fd;

fd = open("/dev/GpioTest", O_RDWR);
if(fd < 0)
{
printf("***Can't open the gpiotest!\r\n");
return -1;
} 
ioctl(fd, 0, 0);
close(fd);
printf("***App run over!\r\n");

return 1;
}

将编译的.out文件拷到小机上面运行,看是不是会打印正确的结果。

二,字符设备驱动的实现
1,代码的实现,请将上面MISC的代码里#define USE_MISC_MODE1改成0
2,makefile的实现

KERNEL_DIR := /home/ding/workdir/david/EVMBoard/board-support/linux-3.2

PLATFORM := "am335x-evm"
MACHINE_NAME := "am335x"

# If CROSS_COMPILE is not set by Rules.make then set a sane default
CROSS_COMPILE ?= arm-arago-linux-gnueabi-
export CROSS_COMPILE

obj-m := GpioTestDriver.o

MAKE_ENV = ARCH=arm

PWD := $(shell pwd)
all:
$(MAKE) EXTRA_CFLAGS="$(EXTRA_CFLAGS)" -C $(KERNEL_DIR) $(MAKE_ENV) \
   M=$(PWD) modules

clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions *.symvers

3,将编译的ko拷入小机,然后命令:

insmod ./GpioTestDriver.ko
lsmod
mknod /dev/GpioTestDriver c 251 0

4,实现APP的代码
将上面MISC的代码作如下修改:

fd = open("/dev/GpioTestDriver", O_RDWR);

5,运行APP查看结果



总结:两个驱动代码实现差不多,但是步骤不一样,主要体现在模块需要安装。MISC会自动创建设备文件,它的主设备号是10,字符设备需要我们来指定。
可安装的字符设备对驱动的编写测试是非常有帮助的。

抱歉!评论已关闭.