fireprime-rk3128 android app 通过jni控制GPIO的代码

本帖最后由 carlinluo 于 2015-8-25 17:27 编辑

驱动

#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");

JNI

static jint getGpio(JNIEnv *env, jobject thiz,jint num){

    jint ret=-1;
    UserData userdata;
    memset(&userdata,0x00, sizeof(UserData));
    //strlcpy(userdata.name, "gpio",10);
    userdata.gpio=num;
    userdata.state=0;

    ret = ioctl(fd, CMD_GET_GPIO, &userdata);
    return ret;
}

static jint releaseGpio(JNIEnv *env, jobject thiz,jint num){

    jint ret=-1;
    UserData userdata;
    memset(&userdata,0x00, sizeof(UserData));
    userdata.gpio=num;
    userdata.state=0;
    ret = ioctl(fd, CMD_RELEASE_GPIO, &userdata);
    return ret;
}

static jint openGpioDev(JNIEnv *env, jobject thiz){

    jint ret=0;

    fd = open("/dev/luobogpio", O_RDWR);
    if (fd < 0) {
        ret=-1;
    }
    return ret;
}

static jint closeGpioDev(JNIEnv *env, jobject thiz){

    jint ret=0;

    ret = close(fd);
    if (fd < 0) {
        ret=-1;
    }
    return ret;
}

static jint setGpioState(JNIEnv *env, jobject thiz,jint num,jint state) {
    jint err=-1;
    UserData userdata;
    memset(&userdata,0x00, sizeof(UserData));
    userdata.gpio=num;
    userdata.state=state;

    err = ioctl(fd, CMD_SET_GPIO, &userdata);
    if(err<0){
        err=-1;
    }
    return err;
}

APP:

public class LuoboHardware {

    static {
        // The runtime will add "lib" on the front and ".o" on the end of
        // the name supplied to loadLibrary.
        System.loadLibrary("app");
    }

    public native int add(int a, int b);
    public native int openGpioDev();
    public native int closeGpioDev();
    public native int getGpio(int num);
    public native int releaseGpio(int num);
    public native int setGpioState(int num,int state);
}


写了个简单的应用,可以用以下这些方法控制GPIO了,记得控制的时候,先给驱动节点权限,adb root ->adb shell chmod 777 dev/luobogpio
public native int openGpioDev();
public native int closeGpioDev();
public native int getGpio(int num);
public native int releaseGpio(int num);
public native int setGpioState(int num,int state);

清晰明了,支持一个:victory:

zhansb 发表于 2015-8-25 17:39
清晰明了,支持一个

:lol偷懒了很多。。。

xuexi ..

直接 在上层app用JNI可以实现吗?

:D请问下,有没有这个工程的源码?能否发一个!:hug:

站在旁边看看,因为脑子里好糊涂。

给版主建议能像 FriendlyARM 友善之臂那样提供 IO/I2C/SPI/PWM… 基本的android studio 的完整例程和文件, 这样有利大家对这平台的使用和学习。

本帖最后由 carlinluo 于 2015-10-8 15:09 编辑

上传源码,里面东西太乱,用android studio 1.3.2编译。没有时间整理,有需要的看看
luobotools.zip (4.02 MB)

–>kernel/drivers/misc/luobo_gpio.c
–>kernel/drivers/misc/Makefile add obj-$(CONFIG_LUOBO_GPIO) += luobo_gpio.o
luobo_gpio.rar (1.36 KB)

请问版主/dev/luobogpio是否有设定存取权限?

之前在FriendlyARM都会在init.rc里面做设定:
chmod 0666 /dev/xxx (xxx依据driver所define的DEVICE_NAME来设定)

mark

不错

学习一下

学习一下!多谢分享!

sunwingman 发表于 2015-10-12 15:04
请问版主/dev/luobogpio是否有设定存取权限?

之前在FriendlyARM都会在init.rc里面做设定:

需要设置权限的,否则app没有权限访问该节点。但是必须说明,这种方法只适用于测试,正式产品是不能用这样的架构的,因为0666或者0777都是过不了CTS的。

站在旁边看看,因为脑子里好糊涂。

好强大,赞一个

carlinluo 发表于 2015-10-8 15:08
上传源码,里面东西太乱,用android studio 1.3.2编译。没有时间整理,有需要的看看

我去恶趣味请问请问企鹅去除

我使用的是rk的平台 没有/dev/luobogpio节点 需要怎么去弄