• «
  • 1
  • 2
  • »
  • Pages: 1/2     Go
主题 : 求助:linux 里测试程序调用不到驱动 open函数老是返回-1 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 33474
精华: 0
发帖: 11
金钱: 55 两
威望: 11 点
综合积分: 22 分
注册时间: 2010-12-01
最后登录: 2011-02-11
楼主  发表于: 2010-12-01 17:01

 求助:linux 里测试程序调用不到驱动 open函数老是返回-1

管理提醒: 本帖被 kasim 从 Linux技术交流区 移动到本区(2010-12-02)
求救::
在测试程序里open("/dev/led",O_RDWR); 返回-1值,老调用不到驱动程,不知何解???

资料:

第一部分:在2.6.25 kernel的驱动里:drivers / char里的驱动ledctl.c:
...
#define LED_MAJOR    231    
#define LED_MINOR    0    
#define DEVICE_NAME    "led"
...
static const struct file_operations leds_fops={
    .owner    = THIS_MODULE,
    .open  = leds_open,
    .ioctl = leds_ioctl,
};
...
static int __init leds_init(void){
...
ret = register_chrdev(LED_MAJOR, DEVICE_NAME, &leds_fops);  
  
     leds_class=class_create(THIS_MODULE,DEVICE_NAME);
     class_device_create(leds_class,NULL,MKDEV(LED_MAJOR,LED_MINOR),NULL,DEVICE_NAME);
...
}
static int __exit leds_exit(void)
{
    unregister_chrdev(LED_MAJOR, DEVICE_NAME);  
    return 0;
}

module_init(leds_init);  
module_exit(leds_exit);

第二部分:应用测试程序
...
#define LED_DEVICE "/dev/led"
...
static int led_device_open(...)
{
...
   fd =open(LED_DEVICE,O_RDRW);  //打不开LED_DEVICE ????
   if(fd < 0)            
     return -1;
...
}

操作过程:
在命令行终端里可以查到/dev/led,
而且能查到

crw------- root root  231 ,0  2010-12-01 08:20  led

但串口监测出在应用程序里的led_device_open函数中open返回的fd是-1;
这是何解呢?困惑中~~~~~
级别: 新手上路
UID: 33474
精华: 0
发帖: 11
金钱: 55 两
威望: 11 点
综合积分: 22 分
注册时间: 2010-12-01
最后登录: 2011-02-11
1楼  发表于: 2010-12-01 17:05
补充已经写好Kconfig 和makefile 而且在make menuconfig,选中该驱动为编译进内核的!
级别: 新手上路
UID: 33474
精华: 0
发帖: 11
金钱: 55 两
威望: 11 点
综合积分: 22 分
注册时间: 2010-12-01
最后登录: 2011-02-11
2楼  发表于: 2010-12-01 18:00
再补充:
补充:串口已经打印出 驱动程序里init函数里的 调试信息:
...
[1] **test:led --initialized
...
在终端里也能进入dev/下找到led节点
但应用程序就是open 返回的是 -1值
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
3楼  发表于: 2010-12-01 20:27
我想你可以
1. 在驱动源代码里的leds_open()函数里加上debug信息来确认这个函数是否被正常调用到;
2. 在open()返回出错的情况下,用perror()来打印出具体的出错原因,perror的用法参考http://linux.die.net/man/3/perror; open()返回值含义参考http://linux.die.net/man/2/open
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."
级别: 新手上路
UID: 33474
精华: 0
发帖: 11
金钱: 55 两
威望: 11 点
综合积分: 22 分
注册时间: 2010-12-01
最后登录: 2011-02-11
4楼  发表于: 2010-12-02 14:38
谢谢斑竹~~~
1. 驱动里的leds_open()添加了printk(),没打印信息处理,感觉没被调用到,而该程序里的init部分则有调试信息出来。
2.我是在android系统上写了一个java应用调用jni的**.so,然后在调用HAL的 **.so,HAL里的.so源代码就是用到上述老是返回-1的open函数,HAL里的.so我放在hardware/libhardware/modules/led/下的!logcat看出java的apk已经调用到jni的.so,也进入了HAL里的.so就是在运行到HAL的led.c里的open时出错,我也添加了perror可打印不出该信息!!!

附上HAL里的led.c源码:
/***********led.c******* **/
//***/hardwar/modules/led/***/

#define LOG_TAG "LedStub"
#include <cutils/log.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>

#include <sys/ioctl.h>
#include <sys/types.h>

#include <hardware/led.h>

#define LED_DEVICE "/dev/led"

#define IOCTL_LED0_ON    0    
#define IOCTL_LED1_ON    1
#define IOCTL_LED0_OFF    2
#define IOCTL_LED1_OFF    3

static int led_set_on(struct led_control_device_t *dev,int32_t led)
{
//FIXME: do system call to control gpio led

   int fd;
   LOGI("LED Stub: set %d on.\r\n",led);
   fd=dev->fd;
   switch(led)
     {
       case IOCTL_LED0_ON :
           ioctl(fd,0,0);
       break;
       case IOCTL_LED1_ON :
           ioctl(fd,1,0);
           break;
       default: return -1;
     }

   LOGI("led_set_on\r\n");
   return 0;

}

static int led_set_off(struct led_control_device_t *dev,int32_t led)
{
   int fd;
   LOGI("LED Stub: set %d off.\r\n",led);
   fd=dev->fd;
   switch(led)
     {
       case IOCTL_LED0_OFF :
        LOGI("LED Stub: set  IOCTL_LED0_OFF.\r\n");
         ioctl(fd,2,0);
     break;
       case IOCTL_LED1_ON :
    LOGI("LED Stub: set  IOCTL_LED1_ON .\r\n");
         ioctl(fd,3,0);
         break;
       default: return -1;
  }

  LOGI("led_set_off\r\n");
  return 0;

}

static int led_device_close(struct led_control_device_t *dev)
{
   close(dev->fd);
   if (dev)
    {
     free(dev);
    }
   return 0;

}

static int led_device_open(const struct hw_module_t *module, const char *name ,struct hw_device_t **device)
{
   struct led_control_device_t  *dev;

   dev = (struct led_control_device_t *)malloc(sizeof(*dev));
   memset(dev,0,sizeof(*dev));
   dev->common.tag     = HARDWARE_DEVICE_TAG;
   dev->common.version =0;
   dev->common.module  =(struct hw_module_t*)(module);
   dev->common.close   =led_device_close;

   dev->set_on  =led_set_on;
   dev->set_off =led_set_off;

   *device =&dev->common;    

  dev->fd =open("/dev/led",O_RDWR);                  #define LED_DEVICE "/dev/leds"
  LOGI("**led.c-->led_device_open 2 fd=%d",dev->fd);  ////该句子打印出来了,fd=-1
   if(dev->fd < 0)
   {    
     LOGI("**\r\nprint perror:");    //该句子打印出来了
     perror("/dev/led");                  //该句信息没打印出来
     LOGI("** print_end\r\n");    //该句子打印出来了
     return -1;
   }
   led_set_on(dev,IOCTL_LED0_ON);  
   led_set_on(dev,IOCTL_LED1_ON);

success:
    return 0;
}


static struct hw_module_methods_t led_module_methods ={

    open:led_device_open
    
};

const struct led_module_t HAL_MODULE_INFO_SYM={

    common:{
        tag:HARDWARE_MODULE_TAG,
        version_major:1,
        version_minor:0,
        id:LED_HARDWARE_MODULE_ID,
        name:"Sample LED Stub",
        author:"LWJ Open Source Project",
        methods:&led_module_methods,
    }

};
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
5楼  发表于: 2010-12-02 22:04
对于Android上的HAL来说,perror()这种依赖于标准输出的函数是行不通的(这种情况下,进程的标准输出是重定向到/dev/null的)。我想你需要用Android的LOGI()宏直接打印出保存出错值的全局变量errno, 我不确定在Android上它是否叫这个名字。
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."
级别: 新手上路
UID: 33474
精华: 0
发帖: 11
金钱: 55 两
威望: 11 点
综合积分: 22 分
注册时间: 2010-12-01
最后登录: 2011-02-11
6楼  发表于: 2010-12-07 19:38
版主啊~~~有新新情况啊~~~::

I/Java Service(  982): Load Native Serivce LIB
D/dalvikvm(  982): Trying to load lib /system/lib/libled_runtime.so 0x0
D/dalvikvm(  982): Added shared lib /system/lib/libled_runtime.so 0x0
I/LedService(  982): **LedService.cpp-->JNI_OnLoad
I/Java Service(  982): do init Native Call
I/LedService(  982): **LedService.cpp-->led_init
I/LedService(  982): **LedService.cpp-->get Module OK
I/LedService(  982): **LedService.cpp-->led_control_ope
I/LedStub (  982): **led.c-->led_device_open 2 fd=-1              //open返回-1
I/LedStub (  982): **print perror:Permission denied                 // 打印error   发现时权限问题
I/LedService(  982): **LedService.cpp-->led_init error             //
I/LedService(  982): **LedService.cpp-->get_count                
D/Java Service(  982): Init OK
I/Java App(  982): Load Java Serivce

我修改了驱动程序的 属性:
chmod 777 myledsctl.c
然后再编译,下载执行还是同样的错误,
还有修改HAL里的led.c代码:
dev->fd=open("/dev/led",O_RDWR,0);
  LOGI("**led.c-->led_device_open 2 fd=%d",dev->fd);  ////该句子打印出来了,fd=-1
   if(dev->fd < 0)
   {    
     LOGI("**print perror:%s \r\n",strerror(errno));    //该句子打印出Permission denied    
     return -1;
   }

编译后下载运行,还是上述错误提示
请问如何修改权限处理上述问题?
级别: 新手上路
UID: 33474
精华: 0
发帖: 11
金钱: 55 两
威望: 11 点
综合积分: 22 分
注册时间: 2010-12-01
最后登录: 2011-02-11
7楼  发表于: 2010-12-08 14:38
版主啊,你显显灵啊~~~~
级别: 新手上路
UID: 33474
精华: 0
发帖: 11
金钱: 55 两
威望: 11 点
综合积分: 22 分
注册时间: 2010-12-01
最后登录: 2011-02-11
8楼  发表于: 2010-12-08 16:29
哈哈~~~版主,问题解决了,问题点在我的SDK包里的源码 在main.mk里被设置为普通用户了,把它改为root就ok了!!!
级别: 新手上路
UID: 33474
精华: 0
发帖: 11
金钱: 55 两
威望: 11 点
综合积分: 22 分
注册时间: 2010-12-01
最后登录: 2011-02-11
9楼  发表于: 2010-12-08 16:30
谢谢版主的提示啊,可以结了~
  • «
  • 1
  • 2
  • »
  • Pages: 1/2     Go