07 Orangepi H3 Android上的Led设备驱动调用

版权声明:本文为博主原创文章,未经博主允许转载。 https://blog.csdn.net/jklinux/article/details/79853414

设备驱动代码:

/* myled.c */

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <mach/gpio.h>
#include <linux/gpio.h>
#include <linux/miscdevice.h>


#define LED_IO   GPIOA(15)

long myioctl(struct file *fl, unsigned int cmd, unsigned long arg)
{
    if (cmd) // led on
        gpio_set_value(LED_IO, 1);      
    else  // led off
        gpio_set_value(LED_IO, 0);

    return 0;
}


struct file_operations fops = {
    .owner = THIS_MODULE,
    .unlocked_ioctl = myioctl,
};

struct miscdevice mdev = {
    .minor = MISC_DYNAMIC_MINOR,
    .fops = &fops,
    .name = "myled",
};

static int __init test_init(void)
{
    gpio_request(LED_IO, "mydev"); //请求gpio口
    gpio_direction_output(LED_IO, 0); //配置gpio口为输出,先输出低电平

    return misc_register(&mdev);
}

static void __exit test_exit(void)
{
    misc_deregister(&mdev);
    gpio_free(LED_IO); //释放gpio
}

module_init(test_init);
module_exit(test_exit);

MODULE_LICENSE("GPL");

/* Makefile */

obj-m += myled.o

KSRC := /home/jk/Downloads/h3_android/lichee/linux-3.4
export ARCH := arm
export CROSS_COMPILE := arm-linux-gnueabi-

all:
    make -C $(KSRC) modules M=`pwd` 


.PHONY : clean
clean:
    make -C $(KSRC) modules clean M=`pwd` 

编译完成后,可通过”adb push myled.ko /” 推送到板子上,然后在板上”insmod myled.ko”加载驱动模块. 加载后, 会在产生一个”/dev/myled”设备文件.
注意,加载驱动模块前须确认”gpio_sunxi”模块是否已加载,因此模块也会占用gpio口,所以可能需要卸载gpio_sunxi模块后才可以加载myled模块


通过应用程序来测试驱动的工作:

/* myapp.c */

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

int main(int argc, char *argv[])
{
    int fd = open("/dev/myled", O_RDWR);

    if (fd < 0)
        return 1;

    ioctl(fd, atoi(argv[1]));

    close(fd);
    return 0;
}

可以把通过静态编译产生的程序推送到板子上执行。
也可以编译出使用Android系统动态库的程序,需要编写Android.mk:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := myapp.c
LOCAL_MODULE := myapp
LOCAL_MODULE_TAGS := optional
include $(BUILD_EXECUTABLE)

然后,进入Android系统源码目录下:

. ./build/envsetup.sh
lunch dolphin_fvd_p1-eng
mmm   myapp.c所在的目录路径

编译完成后, 生成的程序在out/target/product/dolphin-fvd-p1/system/bin/myapp



Android App上的调用:

/* MyJni.java */
package com.jk;

public class MyJni {
    static {
        System.loadLibrary("myjni");
    }

    public native int ledOn();
    public native int ledOff();
}

生成的JNI文件:

/* com_jk_MyJni.h */
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_jk_MyJni */

#ifndef _Included_com_jk_MyJni
#define _Included_com_jk_MyJni
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_jk_MyJni
 * Method:    ledOn
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_com_jk_MyJni_ledOn
  (JNIEnv *, jobject);

/*
 * Class:     com_jk_MyJni
 * Method:    ledOff
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_com_jk_MyJni_ledOff
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif
/* com_jk_MyJni.cpp */

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include "com_jk_MyJni.h"

JNIEXPORT jint JNICALL Java_com_jk_MyJni_ledOn
  (JNIEnv *env, jobject obj)
{
    int fd = open("/dev/myled", O_RDWR);
    if (fd < 0)
        return -1;

    ioctl(fd, 1);
    close(fd);
    return 0;
}

JNIEXPORT jint JNICALL Java_com_jk_MyJni_ledOff
  (JNIEnv *env, jobject obj)
{
    int fd = open("/dev/myled", O_RDWR);
    if (fd < 0)
        return -1;

    ioctl(fd, 0);
    close(fd);
    return 0;
}
/* MainActivity.java */

package com.example.helloworld;

import com.jk.MyJni;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;


public class MainActivity extends Activity {
    private Button btn1, btn2;
    private MyJni myjni = new MyJni();
    private byte [] data = new byte[1024];

    private OnClickListener lt = new OnClickListener() {
        public void onClick(View arg0) {
            if (btn1 == arg0) {
                // led on
                myjni.ledOn();
            }
            if (btn2 == arg0) {
                myjni.ledOff();

            }
        }
    }; 

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btn1 = (Button)findViewById(R.id.btn_ledon);
        btn2 = (Button)findViewById(R.id.btn_ledoff);

        btn1.setOnClickListener(lt);
        btn2.setOnClickListener(lt);

    }
}

同时需要注意,设备驱动产生的/dev/myled设备文件默认Android app是无权限访问的,可以通过”chmod 0666 /dev/myled”设置权限,以便访问调用.

猜你喜欢

转载自blog.csdn.net/jklinux/article/details/79853414
h3