全志A20控制GPIO口的一种方法:

全志A20控制GPIO口的一种方法:




1、驱动模块文件:a20_gpio.c
// printk(KERN_ERR "****wyb %s:%d/%s()!\n", __FILE__, __LINE__, __func__);


// http://blog.csdn.net/mirkerson/article/details/8844997
// android驱动学习---gpio实验 


#include               /* For module specific items */  
#include          /* For new moduleparam's */  
#include                /* For standard types (like size_t) */  
#include                /* For the -ENODEV/... values */  
#include               /* For printk/panic/... */  
#include                   /* For file operations */ 
#include               /* For io-port access */  
#include      /* For platform_driver framework */  
#include                 /* For __init/__exit/... */  
#include              /* For copy_to_user/put_user/... */  
#include                   /* For inb/outb/... */  
#include  
#include  
#include  
#include               /*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 ");  
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.csdn.net/21cnbao/article/details/7919055


#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  








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)

你可能感兴趣的:(全志)