一、底层驱动源文件
/**
* 这是一个底层驱动源文件:
* 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;
}