Android应用层访问底层驱动的简易方法

一、底层驱动源文件

/**
 * 这是一个底层驱动源文件:
 * 1.它运行在内核空间;
 * 2.创建了一个特定的文件,可供应用层读写,借此进行通信。
 */

#include 
#include 
#include 


/*
 * This function will be call by:
 * cat /sys/class/wesnoth/wesnoth_param
 * or read() and so on.
 * 当应用层对该特定文件进行读操作时,内核会调用此方法。
 */
static ssize_t wesnoth_param_read(struct class *class, struct class_attribute *attr, char *buf)
{
        int count = 0;
        // do something here, e.g. write count byte(s) to the buf.
        return count;
}

/*
 * This function will be call by:
 * echo VALUE > /sys/class/wesnoth/wesnoth_param
 * or write() and so on.
 * 当应用层对该特定文件进行写操作时,内核会调用此方法。
 */
static ssize_t wesnoth_param_write(struct class *class, struct class_attribute *attr, const char *buf, size_t count)
{
        // do something here, e.g. read count byte(s) from buf.
        return count;
}

/**
 * 这个变量名即是该特定文件的名称
 */
static int wesnoth_param = 0;
/*
 * 0666 means everyone can read/write it.
 * This macro will create a variable named class_attr_wesnoth_param.
 */
static CLASS_ATTR(wesnoth_param, 0666, wesnoth_param_read, wesnoth_param_write);
/**
 * 设置该文件所在的文件夹名称
 */
static struct class wesnoth_class =
{
        .name = "wesnoth",
};

/**
 * 本源文件的入口函数。
 */
static int wesnoth_init(void)
{
        // create dir: /sys/class/wesnoth/
        int error = class_register(&wesnoth_class);
        if (error)
        {
                printk("%s: class_register() failed!\n", __func__);
                return error;
        }
        // create file: /sys/class/wesnoth/wesnoth_param
        error = class_create_file(&wesnoth_class, &class_attr_wesnoth_param);
        if (error)
        {
                printk("%s: class_create_file() failed!\n", __func__);
                class_unregister(&wesnoth_class);
                return error;
        }
        return 0;
}

/**
 * 本源文件的出口函数。
 */
static void wesnoth_exit(void)
{
        class_remove_file(&wesnoth_class, &class_attr_wesnoth_param);
        class_unregister(&wesnoth_class);
}

module_init(wesnoth_init);
module_exit(wesnoth_exit);
MODULE_LICENSE("GPL");
# 这是个Makefile文件,视情况选择其中一种:
# 编进内核,或者做成模块。

# 这行指令可以把这个驱动编进内核
obj-$(CONFIG_WESNOTH_INSTALL) += myDriver.o

# 以下内容用来创建模块
ifneq ($(KERNELRELEASE),)
        obj-m += myDriver.o
else
        KERNELDIR=$(ANDROID_ROOT_DIR)/common
all:
        PWD=$(shell pwd)
        $(MAKE) -C $(KERNELDIR) M=$(PWD)
clean:
        rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions module* Module*
endif
# 这是个Kconfig文件,用于把这个驱动编进内核。
# 如果想把它做成模块,则不需要这个文件
menuconfig WESNOTH_INSTALL
        bool "Wesnoth device driver install to kernel"
    default y
    help
         If y, Wesnoth device driver will install to kernel.

二、应用层源文件

/**
 * 这是一个java层代码对底层驱动特定文件的访问示例。
 */
package com.example.wesnoth;

import java.io.IOException;
import java.io.RandomAccessFile;
import android.util.Log;


public class Wesnoth
{
    private static final String wesnothFile = "/sys/class/wesnoth/wesnoth_param";
    private static final String LOG_TAG = "Wesnoth";

    public static int writeValueToFile(int value)
    {
        RandomAccessFile file = null;
        try
        {
            file = new RandomAccessFile(wesnothFile, "rw");
        } 
        catch (Exception e)
        {
            Log.e(LOG_TAG, "Error: open file " + path + " failed!");
            return -1;
        }
        try
        {
            // write value to the class file, then will call the wesnoth_param_write()
            file.writeBytes(String.valueOf(value));
        } 
        catch (IOException e)
        {
            Log.e(LOG_TAG, "Error: write file " + path + " failed!");
            try
            {
                file.close();
            } 
            catch (IOException e1)
            {
                // do nothing here
                e1.printStackTrace();
            }
            return -1;
        }
        try
        {
            file.close();
        } 
        catch (IOException e)
        {
            Log.e(LOG_TAG, "Error: close file " + path + " failed!");
        }
        return 0;
    }

    public static int readValueFromFile(Integer value)
    {
        // ...
    }
}
/**
 * 这是一个jni层代码对底层驱动特定文件的访问示例。
 */
#include 
#include 
#include 
#include 

char* wesnothFile = "/sys/class/wesnoth/wesnoth_param";

int main(void)
{
        int fd = 0, value = 0, retval = 0;
        fd = open(wesnothFile, O_RDWR);
        if (-1 == fd)
        {
                printf("Error: open %s failed! %s\n", wesnothFile, strerror(errno));
                return -1;
        }
        retval = read(fd, &value, sizeof(value));
        if (-1 == retval)
        {
                printf("Error: read %s failed! %s\n", wesnothFile, strerror(errno));
                return -1;
        }
        write(fd, &value, sizeof(value));
        if (-1 == retval)
        {
                printf("Error: write %s failed! %s\n", wesnothFile, strerror(errno));
                return -1;
        }
        close(fd);
        return 0;
}

你可能感兴趣的:(linux驱动,Android)