FirePrime-RK3128 Android app use jni to control GPIO code

Sharing by carlinluo

Driver

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

Wrote a simple app, you can control GPIO by the following method , DO remember to give permissions to driven node first.

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

This article is absolutely amazing, thank you for sharing it with us. The Latest C_BCFIN_2502 exam sims test questions are key to your promotion and salary boost—free for all!

I am so grateful for your share, this article is truly impressive! I got promoted and earned a raise using this Reliable study guide 300-810 free. Now it’s available for free. Best of luck with your promotions!

Your article is truly phenomenal, I’m so grateful for you sharing it! Enhance your IT knowledge—free New test HPE6-A86 camp sheet shared! Wishing you success!