全志A20控制GPIO口的一种方法:
1、驱动模块文件:a20_gpio.c
// printk(KERN_ERR "****wyb %s:%d/%s()!\n", __FILE__, __LINE__, __func__);
// http://blog.youkuaiyun.com/mirkerson/article/details/8844997
// android驱动学习---gpio实验
#include <linux/module.h> /* For module specific items */
#include <linux/moduleparam.h> /* For new moduleparam's */
#include <linux/types.h> /* For standard types (like size_t) */
#include <linux/errno.h> /* For the -ENODEV/... values */
#include <linux/kernel.h> /* For printk/panic/... */
#include <linux/fs.h> /* For file operations */
#include <linux/ioport.h> /* For io-port access */
#include <linux/platform_device.h> /* For platform_driver framework */
#include <linux/init.h> /* For __init/__exit/... */
#include <linux/uaccess.h> /* For copy_to_user/put_user/... */
#include <linux/io.h> /* For inb/outb/... */
#include <linux/gpio.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include <linux/slab.h> /*kamlloc */
static int major = 219;
static struct class *gpio_class;
struct cdev_gpio {
struct cdev cdev;
}; //建议用2.6的注册方法,2.4的已经离我们越来越远了。
struct cdev_gpio *gpio_dev;
static long gpio_ioctl(struct file* filp, unsigned int cmd, unsigned long argv)
{
// printk("****wyb %s:%d/%s()! cmd=0x%08x\n", __FILE__, __LINE__, __func__, cmd);
unsigned char ucGPIONumber = (cmd & 0x0000FF00) >> 8;
// printk("****wyb %s:%d/%s()! cmd=0x%08x ucGPIONumber=0x%08x, %d\n", __FILE__, __LINE__, __func__, cmd, ucGPIONumber, ucGPIONumber);
printk(KERN_ERR "****wyb %s:%d/%s()! cmd=0x%08x ucGPIONumber=0x%08x, %d\n", __FILE__, __LINE__, __func__, cmd, ucGPIONumber, ucGPIONumber);
if( cmd > (0x00840000-1) )
{
gpio_direction_output( ucGPIONumber, 1);
}
else
{
gpio_direction_output( ucGPIONumber, 0);
}
printk(KERN_ERR "----wyb %s:%d/%s()! end!!!!\n", __FILE__, __LINE__, __func__);
return 0;
}
//open
static int gpio_open(struct inode* i_node, struct file* filp)
{
printk(KERN_ERR "****wyb %s:%d/%s()! open init....\n", __FILE__, __LINE__, __func__);
return 0;
}
//close
static int gpio_close(struct inode* i_node, struct file* filp)
{
printk(KERN_ERR "****wyb %s:%d/%s()! close init\n", __FILE__, __LINE__, __func__);
return 0;
}
/* file operations */
struct file_operations gpio_fops={
.owner = THIS_MODULE,
.open = gpio_open,
.unlocked_ioctl = gpio_ioctl, // 特别注意从2.6.36以后ioctl已经移除,内核里面用unlocked_ioctl和compat_ioctl. 应用层不变,仍是ioctl调用。
.release= gpio_close,
};
static int __init gpio_init(void)
{
dev_t dev_no;
int result, err;
printk(KERN_ERR "****wyb %s:%d/%s()! init ....\n", __FILE__, __LINE__, __func__);
err = alloc_chrdev_region(&dev_no, 0, 1, "a20_gpio"); //动态申请设备号
if(err<0)
{
printk(KERN_INFO "ERROR\n");
return err;
}
major = MAJOR(dev_no);
gpio_dev = kmalloc(sizeof(struct cdev_gpio), GFP_KERNEL);
if(!gpio_dev)
{
result = -ENOMEM;
goto fail_malloc;
}
memset(gpio_dev, 0, sizeof(gpio_dev));
cdev_init(&gpio_dev->cdev,&gpio_fops); // 初始化cdev
gpio_dev->cdev.owner = THIS_MODULE;
result = cdev_add(&gpio_dev->cdev, dev_no, 1); //加载设备
if(result <0)
{
printk(KERN_INFO "error\n");
goto fail_add;
}
gpio_class = class_create(THIS_MODULE, "a20_gpio"); //在sys/class下创建sysfs文件
device_create(gpio_class, NULL, MKDEV(major, 0), NULL, "a20_gpio"); //动态创建设备文件 /dev/mygpio, 以后不用手动创建了
printk(KERN_ERR "----wyb %s:%d/%s()! err=%d, result=%d\n", __FILE__, __LINE__, __func__, err, result);
return 0;
fail_add:
kfree(gpio_dev);
fail_malloc:
unregister_chrdev_region(dev_no, 1);
return result;
}
static void __exit gpio_exit(void)
{
printk(KERN_ERR "****wyb %s:%d/%s()!\n", __FILE__, __LINE__, __func__);
dev_t dev_no=MKDEV(major, 0);
unregister_chrdev_region(dev_no, 1);
cdev_del(&gpio_dev->cdev);
kfree(gpio_dev);
device_destroy(gpio_class, dev_no);
class_destroy(gpio_class);
printk(KERN_ERR "----wyb %s:%d/%s()!\n", __FILE__, __LINE__, __func__);
}
module_init(gpio_init);
module_exit(gpio_exit);
MODULE_AUTHOR("koliy <xxxx@163.com>");
MODULE_DESCRIPTION("ARM test gpio");
MODULE_LICENSE("GPL");
2、驱动模块文件:Makefile( 请严重注意绝对路径的写法)
#
# gpio drirvers
#
PWD :=$(shell pwd)
KERNELDIR := /home/rootroot/wyb/marsboard_hdmi_video1_csi1_ov7670/marsboard_only_ov7670_720p/lichee/linux-3.3
ANDROIDDIR := /home/rootroot/wyb/marsboard_hdmi_video1_csi1_ov7670/marsboard_only_ov7670_720p/android4.2
ARCH=arm
CROSS_COMPILE = $(ANDROIDDIR)/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi-
CC=$(CROSS_COMPILE)gcc
LD=$(CROSS_COMPILE)ld
obj-m += a20_gpio.o
modules:
$(MAKE) -C $(KERNELDIR) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) M=$(PWD) modules
clean:
make -C $(KERNELDIR) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) M=$(PWD) clean
3、APP程序:setgpio.c
// http://blog.youkuaiyun.com/21cnbao/article/details/7919055
#include <stdio.h>
#include <linux/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <assert.h>
#include <string.h>
#include <linux/i2c.h>
int fd;
int main(int argc, char **argv)
{
unsigned int uiSetGPIO = 0;
// fd = open("/dev/gpioset_imx6q", O_RDWR);
fd = open("/dev/a20_gpio", O_RDWR);
// ioctl(fd, 0x00940000, 0);
if(argc>1)
{
sscanf(argv[1], "%x", &uiSetGPIO);
ioctl(fd, uiSetGPIO, 0);
}
// else
// {
// printf("**** wyb f:%s l:%d f:%s !!!!no Parameters\n", __FILE__, __LINE__, __func__);
//
// ioctl(fd, 0x00940001, 0);
// }
close(fd);
return 0;
}
4、APP程序:Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE = setgpio
# LOCAL_SRC_FILES := $(call all-subdir-c-files)
LOCAL_SRC_FILES := setgpio.c
include $(BUILD_EXECUTABLE)
1、驱动模块文件:a20_gpio.c
// printk(KERN_ERR "****wyb %s:%d/%s()!\n", __FILE__, __LINE__, __func__);
// http://blog.youkuaiyun.com/mirkerson/article/details/8844997
// android驱动学习---gpio实验
#include <linux/module.h> /* For module specific items */
#include <linux/moduleparam.h> /* For new moduleparam's */
#include <linux/types.h> /* For standard types (like size_t) */
#include <linux/errno.h> /* For the -ENODEV/... values */
#include <linux/kernel.h> /* For printk/panic/... */
#include <linux/fs.h> /* For file operations */
#include <linux/ioport.h> /* For io-port access */
#include <linux/platform_device.h> /* For platform_driver framework */
#include <linux/init.h> /* For __init/__exit/... */
#include <linux/uaccess.h> /* For copy_to_user/put_user/... */
#include <linux/io.h> /* For inb/outb/... */
#include <linux/gpio.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include <linux/slab.h> /*kamlloc */
static int major = 219;
static struct class *gpio_class;
struct cdev_gpio {
struct cdev cdev;
}; //建议用2.6的注册方法,2.4的已经离我们越来越远了。
struct cdev_gpio *gpio_dev;
static long gpio_ioctl(struct file* filp, unsigned int cmd, unsigned long argv)
{
// printk("****wyb %s:%d/%s()! cmd=0x%08x\n", __FILE__, __LINE__, __func__, cmd);
unsigned char ucGPIONumber = (cmd & 0x0000FF00) >> 8;
// printk("****wyb %s:%d/%s()! cmd=0x%08x ucGPIONumber=0x%08x, %d\n", __FILE__, __LINE__, __func__, cmd, ucGPIONumber, ucGPIONumber);
printk(KERN_ERR "****wyb %s:%d/%s()! cmd=0x%08x ucGPIONumber=0x%08x, %d\n", __FILE__, __LINE__, __func__, cmd, ucGPIONumber, ucGPIONumber);
if( cmd > (0x00840000-1) )
{
gpio_direction_output( ucGPIONumber, 1);
}
else
{
gpio_direction_output( ucGPIONumber, 0);
}
printk(KERN_ERR "----wyb %s:%d/%s()! end!!!!\n", __FILE__, __LINE__, __func__);
return 0;
}
//open
static int gpio_open(struct inode* i_node, struct file* filp)
{
printk(KERN_ERR "****wyb %s:%d/%s()! open init....\n", __FILE__, __LINE__, __func__);
return 0;
}
//close
static int gpio_close(struct inode* i_node, struct file* filp)
{
printk(KERN_ERR "****wyb %s:%d/%s()! close init\n", __FILE__, __LINE__, __func__);
return 0;
}
/* file operations */
struct file_operations gpio_fops={
.owner = THIS_MODULE,
.open = gpio_open,
.unlocked_ioctl = gpio_ioctl, // 特别注意从2.6.36以后ioctl已经移除,内核里面用unlocked_ioctl和compat_ioctl. 应用层不变,仍是ioctl调用。
.release= gpio_close,
};
static int __init gpio_init(void)
{
dev_t dev_no;
int result, err;
printk(KERN_ERR "****wyb %s:%d/%s()! init ....\n", __FILE__, __LINE__, __func__);
err = alloc_chrdev_region(&dev_no, 0, 1, "a20_gpio"); //动态申请设备号
if(err<0)
{
printk(KERN_INFO "ERROR\n");
return err;
}
major = MAJOR(dev_no);
gpio_dev = kmalloc(sizeof(struct cdev_gpio), GFP_KERNEL);
if(!gpio_dev)
{
result = -ENOMEM;
goto fail_malloc;
}
memset(gpio_dev, 0, sizeof(gpio_dev));
cdev_init(&gpio_dev->cdev,&gpio_fops); // 初始化cdev
gpio_dev->cdev.owner = THIS_MODULE;
result = cdev_add(&gpio_dev->cdev, dev_no, 1); //加载设备
if(result <0)
{
printk(KERN_INFO "error\n");
goto fail_add;
}
gpio_class = class_create(THIS_MODULE, "a20_gpio"); //在sys/class下创建sysfs文件
device_create(gpio_class, NULL, MKDEV(major, 0), NULL, "a20_gpio"); //动态创建设备文件 /dev/mygpio, 以后不用手动创建了
printk(KERN_ERR "----wyb %s:%d/%s()! err=%d, result=%d\n", __FILE__, __LINE__, __func__, err, result);
return 0;
fail_add:
kfree(gpio_dev);
fail_malloc:
unregister_chrdev_region(dev_no, 1);
return result;
}
static void __exit gpio_exit(void)
{
printk(KERN_ERR "****wyb %s:%d/%s()!\n", __FILE__, __LINE__, __func__);
dev_t dev_no=MKDEV(major, 0);
unregister_chrdev_region(dev_no, 1);
cdev_del(&gpio_dev->cdev);
kfree(gpio_dev);
device_destroy(gpio_class, dev_no);
class_destroy(gpio_class);
printk(KERN_ERR "----wyb %s:%d/%s()!\n", __FILE__, __LINE__, __func__);
}
module_init(gpio_init);
module_exit(gpio_exit);
MODULE_AUTHOR("koliy <xxxx@163.com>");
MODULE_DESCRIPTION("ARM test gpio");
MODULE_LICENSE("GPL");
2、驱动模块文件:Makefile( 请严重注意绝对路径的写法)
#
# gpio drirvers
#
PWD :=$(shell pwd)
KERNELDIR := /home/rootroot/wyb/marsboard_hdmi_video1_csi1_ov7670/marsboard_only_ov7670_720p/lichee/linux-3.3
ANDROIDDIR := /home/rootroot/wyb/marsboard_hdmi_video1_csi1_ov7670/marsboard_only_ov7670_720p/android4.2
ARCH=arm
CROSS_COMPILE = $(ANDROIDDIR)/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi-
CC=$(CROSS_COMPILE)gcc
LD=$(CROSS_COMPILE)ld
obj-m += a20_gpio.o
modules:
$(MAKE) -C $(KERNELDIR) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) M=$(PWD) modules
clean:
make -C $(KERNELDIR) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) M=$(PWD) clean
3、APP程序:setgpio.c
// http://blog.youkuaiyun.com/21cnbao/article/details/7919055
#include <stdio.h>
#include <linux/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <assert.h>
#include <string.h>
#include <linux/i2c.h>
int fd;
int main(int argc, char **argv)
{
unsigned int uiSetGPIO = 0;
// fd = open("/dev/gpioset_imx6q", O_RDWR);
fd = open("/dev/a20_gpio", O_RDWR);
// ioctl(fd, 0x00940000, 0);
if(argc>1)
{
sscanf(argv[1], "%x", &uiSetGPIO);
ioctl(fd, uiSetGPIO, 0);
}
// else
// {
// printf("**** wyb f:%s l:%d f:%s !!!!no Parameters\n", __FILE__, __LINE__, __func__);
//
// ioctl(fd, 0x00940001, 0);
// }
close(fd);
return 0;
}
4、APP程序:Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE = setgpio
# LOCAL_SRC_FILES := $(call all-subdir-c-files)
LOCAL_SRC_FILES := setgpio.c
include $(BUILD_EXECUTABLE)