本篇主要讲在Android系统中的linux下控制GPIO的方法,android 通过jni控制GPIO可基于本篇内容继续开展;
linux控制GPIO基本上有两种方法,一是通过pinctrl体系,直接使用/sys下的文件进行控制,另一种就是编写驱动,在驱动中进行控制,下面分别进行介绍:
一、是用sys文件系统控制(更深入的介绍请移步:
http://blog.chinaunix.net/uid-27717694-id-3701921.html);
二、编写驱动(rk3128为例,转载自:
http://developer.t-firefly.com/forum.php?mod=viewthread&tid=2436&highlight=gpio)
<span style="font-size:14px;">#include <dt-bindings/gpio/gpio.h> #include <linux/gpio.h> #include <linux/of_gpio.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/platform_device.h> #include <linux/fb.h> #include <linux/backlight.h> #include <linux/err.h> #include <linux/pwm.h> #include <linux/pwm_backlight.h> #include <linux/slab.h> #include <linux/device.h> #include <linux/miscdevice.h> #include <asm/uaccess.h> static struct UserData{ int gpio; int state; }; static struct of_device_id luobogpio_of_match[] = { { .compatible = "luobogpio" }, { } }; MODULE_DEVICE_TABLE(of, luobogpio_of_match); static int luobogpio_open(struct inode *inode, struct file *filp) { printk("luobogpio_open\n"); return 0; } static ssize_t luobogpio_read(struct file *filp, char __user *ptr, size_t size, loff_t *pos) { if (ptr == NULL) printk("%s: user space address is NULL\n", __func__); return sizeof(int); } static long luobogpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { long ret = 0; struct UserData userdata; unsigned char label[10]; printk("luobogpio_ioctl: cmd = %d arg = %ld\n",cmd, arg); switch (cmd){ case 0: printk("gpio_request\n"); if (copy_from_user((void*)&userdata,(void __user *)arg, sizeof(struct UserData))) return -EFAULT; printk("copy_from_user gpio=%d ,state=%d\n",userdata.gpio,userdata.state); sprintf(label,"gpio-%d",userdata.gpio); printk("----->%s\n",label); ret = gpio_request(userdata.gpio, label); if (ret) { printk("failed to request GPIO%d for you ret:%d\n",userdata.gpio,ret); } break; case 1: printk("gpio_direction_output\n"); if (copy_from_user((void*)&userdata,(void __user *)arg, sizeof(struct UserData))) return -EFAULT; printk("copy_from_user gpio=%d ,state=%d\n",userdata.gpio,userdata.state); ret=gpio_direction_output(userdata.gpio, userdata.state); if (ret) { printk("failed to gpio_direction_output for you ret:%d\n",userdata.gpio); } break; case 5: printk("gpio_free\n"); if (copy_from_user((void*)&userdata,(void __user *)arg, sizeof(struct UserData))) return -EFAULT; printk("copy_from_user gpio=%d ,state=%d\n",userdata.gpio,userdata.state); gpio_free(userdata.gpio); break; default: printk("unknown ioctl cmd!\n"); ret = -EINVAL; break; } return ret; } static int luobogpio_release(struct inode *inode, struct file *filp) { printk("luobogpio_release\n"); return 0; } static struct file_operations luobogpio_fops = { .owner = THIS_MODULE, .open = luobogpio_open, .read = luobogpio_read, .unlocked_ioctl = luobogpio_ioctl, .release = luobogpio_release, }; static struct miscdevice luobogpio_dev = { .minor = MISC_DYNAMIC_MINOR, .name = "luobogpio", .fops = &luobogpio_fops, }; static int luobogpio_probe(struct platform_device *pdev) { int ret=-1; ret = misc_register(&luobogpio_dev); if (ret < 0){ printk("ac_usb_switch register err!\n"); return ret; } printk("func: %s\n", __func__); return 0; } static int luobogpio_remove(struct platform_device *pdev) { //printk("func: %s\n", __func__); return 0; } #ifdef CONFIG_PM_SLEEP static int luobogpio_suspend(struct device *dev) { //printk("func: %s\n", __func__); return 0; } static int luobogpio_resume(struct device *dev) { //printk("func: %s\n", __func__); return 0; } #endif static const struct dev_pm_ops luobogpio_pm_ops = { #ifdef CONFIG_PM_SLEEP .suspend = luobogpio_suspend, .resume = luobogpio_resume, .poweroff = luobogpio_suspend, .restore = luobogpio_resume, #endif }; static struct platform_driver luogpio_driver = { .driver = { .name = "luobogpio", .owner = THIS_MODULE, .pm = &luobogpio_pm_ops, .of_match_table = of_match_ptr(luobogpio_of_match), }, .probe = luobogpio_probe, .remove = luobogpio_remove, }; module_platform_driver(luogpio_driver); MODULE_DESCRIPTION("luobogpio Driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:luobogpio"); </span>