各位大神,麻烦帮忙看一下如下程序,我在应用程序调用底层的open函数时,在jni那里老是open失败,字符设备已经注册进系统,相应的文件节点也有,就是fd返回老是-1,还请各位帮忙看一下
jni file:
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "HardControl hardcontrol.cpp"
#include <utils/Log.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include "jni.h"
jint fd;
jint ledOpen(JNIEnv *env, jobject cls)
{
ALOGI("jkk native ledOpen 1:%d",fd);
fd = open("/dev/leds_test", O_RDWR);
ALOGI("jkk native ledOpen 2:%d",fd);
if (fd >= 0)
return 0;
else{
ALOGI("jkk native ledOpen failed,fd=%d",fd);
return -1;
}
// return 0;
}
jint ledClose(JNIEnv *env, jobject cls)
{
ALOGI("native ledClose ...");
return 0;
}
jint ledCtrl(JNIEnv *env, jobject cls, jint which, jint status)
{
int ret = ioctl(fd, status, which);
ALOGI("native ledCtrl: %d, %d, %d",which,status,ret);
return ret;
}
static const char *classPathName = "com/lenovo/hardlibrary/HardControl";
static JNINativeMethod methods[] = {
{"ledOpen", "()I", (void *)ledOpen},
{"ledClose", "()I", (void *)ledClose},
{"ledCtrl", "(II)I", (void *)ledCtrl},
};
/*
* Register several native methods for one class.
*/
static int registerNativeMethods(JNIEnv* env, const char* className,
JNINativeMethod* gMethods, int numMethods)
{
jclass clazz;
clazz = env->FindClass(className);
if (clazz == NULL) {
ALOGE("Native registration unable to find class '%s'", className);
return JNI_FALSE;
}
if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {
ALOGE("RegisterNatives failed for '%s'", className);
return JNI_FALSE;
}
return JNI_TRUE;
}
/*
* Register native methods for all classes we know about.
*
* returns JNI_TRUE on success.
*/
static int registerNatives(JNIEnv* env)
{
if (!registerNativeMethods(env, classPathName,
methods, sizeof(methods) / sizeof(methods[0]))) {
return JNI_FALSE;
}
return JNI_TRUE;
}
// ----------------------------------------------------------------------------
/*
* This is called by the VM when the shared library is first loaded.
*/
typedef union {
JNIEnv* env;
void* venv;
} UnionJNIEnvToVoid;
jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
UnionJNIEnvToVoid uenv;
uenv.venv = NULL;
jint result = -1;
JNIEnv* env = NULL;
ALOGI("JNI_OnLoad");
if (vm->GetEnv(&uenv.venv, JNI_VERSION_1_4) != JNI_OK) {
ALOGE("ERROR: GetEnv failed");
goto bail;
}
env = uenv.env;
if (registerNatives(env) != JNI_TRUE) {
ALOGE("ERROR: registerNatives failed");
goto bail;
}
result = JNI_VERSION_1_4;
bail:
return result;
}
driver file:
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/leds.h>
#include <linux/of_platform.h>
#include <linux/of_gpio.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/cdev.h>
static int major;
static struct class *cls;
//struct cdev *my_cdev;
static int led_open(struct inode * inode, struct file * file)
{
/*
int err;
err = gpio_request(0, "led1");
err = gpio_direction_output(0,1);
err = gpio_request(1, "led2");
err = gpio_direction_output(1,1);
err = gpio_request(2, "led3");
err = gpio_direction_output(2,1);
err = gpio_request(3, "led4");
err = gpio_direction_output(3,1);
*/
printk("jkk led_open.\n");
return 0;
}
static long led_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
printk("jkk led_ioctl, %d,%lu.\n",cmd,arg);
return 0;
}
static struct file_operations leds_ops={
.owner = THIS_MODULE,
.open = led_open,
.unlocked_ioctl = led_ioctl,
};
int leds_init(void)
{
// int err,devno = MKDEV(major,minor);
// cdev_init(my_cdev,&leds_ops);
// my_cdev->owner = THIS_MODULE;
// my_cdev->ops = &leds_ops;
// err = cdev_add(my_cdev,devno,1);
// if(err)
// printk("add failed,err=%d.\n",err);
printk("jkk leds_init.\n");
major = register_chrdev(0, "leds_test", &leds_ops);
printk("jkk leds_init major=%d.\n",major);
cls = class_create(THIS_MODULE, "leds_test");
device_create(cls, NULL, MKDEV(major, 0), NULL, "leds_test"); /* /dev/leds_jkk */
return 0;
}
void leds_exit(void)
{
device_destroy(cls, MKDEV(major, 0));
class_destroy(cls);
unregister_chrdev(major, "leds_test");
}
module_init(leds_init);
module_exit(leds_exit);
MODULE_LICENSE("GPL");
open返回-1后,看下errno这个全局变量,根据这个确认是啥类别的错误
jni调用设备,是否是权限的问题?