之前 已经让android studio能访问c库 这时候编写c的硬件驱动代码 让app实现对LED的控制
写出 LEDS_4412.c 文件 拿去内核里编译(按照 之前的方法编译好内核)
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <mach/gpio.h>
#include <plat/gpio-cfg.h>
static int led_gpios[] = {
EXYNOS4212_GPM4(0),
EXYNOS4212_GPM4(1),
EXYNOS4212_GPM4(2),
EXYNOS4212_GPM4(3),
};
static int led_open(struct inode *inode, struct file *file)
{
/* 配置GPIO为输出引脚 */
int i;
for (i = 0; i < 4; i++)
s3c_gpio_cfgpin(led_gpios[i], S3C_GPIO_OUTPUT);
return 0;
}
/* app : ioctl(fd, cmd, arg) */
static long led_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg)
{
/* 根据传入的参数设置GPIO */
/* cmd : 0-off, 1-on */
/* arg : 0-3, which led */
if ((cmd != 0) && (cmd != 1))
return -EINVAL;
if (arg > 4)
return -EINVAL;
gpio_set_value(led_gpios[arg], !cmd);
return 0;
}
static struct file_operations leds_ops = {
.owner = THIS_MODULE, /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
.open = led_open,
.unlocked_ioctl = led_ioctl,
};
static int major;
static struct class *cls;
int leds_init(void)
{
major = register_chrdev(0, "leds", &leds_ops);
/* 为了让系统udev,mdev给我们创建设备节点 */
/* 创建类, 在类下创建设备 : /sys */
cls = class_create(THIS_MODULE, "leds");
device_create(cls, NULL, MKDEV(major, 0), NULL, "leds"); /* /dev/leds */
return 0;
}
void leds_exit(void)
{
device_destroy(cls, MKDEV(major, 0));
class_destroy(cls);
unregister_chrdev(major, "leds");
}
module_init(leds_init);
module_exit(leds_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("www.100ask.net");
放入内核 drivers/char
修改 drivers/char/Makefile,添加:
obj-y += leds_4412.o
重新编译内核
在 linux_kerne的跟目录下 编译 zImage
在 arch/arm/boot 就有了 新的 zImage内核
烧写内核
重新写驱动程序 hardcontrol.c
#include <jni.h> /* /usr/lib/jvm/java-1.7.0-openjdk-amd64/include/ */
#include <stdio.h>
#include <stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<sys/ioctl.h>
#include<android/log.h>
#if 0
typedef struct {
char *name; /* JavaÀïµ÷Óõĺ¯ÊýÃû */
char *signature; /* JNI×Ö¶ÎÃèÊö·û, ÓÃÀ´±íʾJavaÀïµ÷Óõĺ¯ÊýµÄ²ÎÊýºÍ·µ»ØÖµÀàÐÍ */
void *fnPtr; /* CÓïÑÔʵÏֵı¾µØº¯Êý */
} JNINativeMethod;
#endif
static jint fd;
jint ledOpen(JNIEnv *env, jobject cls)
{
fd = open("/dev/leds",O_RDWR);
__android_log_print(ANDROID_LOG_DEBUG, "LEDDemo", "native ledOpen " );
if(fd>=0)
return 0;
else
return -1;
return 0;
}
void ledClose(JNIEnv *env, jobject cls)
{
__android_log_print(ANDROID_LOG_DEBUG, "LEDDemo", "native ledclose " );
close(fd);
}
jint ledCtrl(JNIEnv *env, jobject cls,jint which ,jint status)
{
int ret = ioctrl(fd,status,which);
__android_log_print(ANDROID_LOG_DEBUG, "LEDDemo", "native ledCtrl : %d, %d,%d,) ",which,status,ret );
return ret;
}
static const JNINativeMethod methods[] = {
{"ledOpen", "()I", (void *)ledOpen},
{"ledClose", "()V", (void *)ledClose},
{"ledCtrl", "(II)I", (void *)ledCtrl},
};
/* System.loadLibrary */
JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM *jvm, void *reserved)
{
JNIEnv *env;
jclass cls;
if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_4)) {
return JNI_ERR; /* JNI version not supported */
}
cls = (*env)->FindClass(env, "com/thisway/hardlibrary/HardControl");
if (cls == NULL) {
return JNI_ERR;
}
/* 2. map java hello <-->c c_hello */
if ((*env)->RegisterNatives(env, cls, methods, sizeof(methods)/sizeof(methods[0])) < 0)
return JNI_ERR;
return JNI_VERSION_1_4;
}
放入内核编译出 lib库 放入 android studio
成功运行
文件放在下面 zimage 编译好的内核 led_4412.c 在内核中编译好了 生成led_4412.o 被内核调用的 硬件程序 lib库 连接 java和c
hardcontrol 生成lib库 readme 在生成lib库时候 在linux 输入的命令 有多处连接了 安卓源码的库单独注释