• «
  • 1
  • 2
  • »
  • Pages: 1/2     Go
主题 : 请教: MISC设备驱动的问题,急等…… 复制链接 | 浏览器收藏 | 打印
级别: 侠客
UID: 6846
精华: 0
发帖: 55
金钱: 425 两
威望: 215 点
贡献值: 0 点
综合积分: 110 分
注册时间: 2009-06-19
最后登录: 2012-03-21
楼主  发表于: 2010-01-18 11:28

 请教: MISC设备驱动的问题,急等……

  请教: MISC类的驱动和普通字符驱动到底有何区别?
以前老核心板上用的LED和蜂鸣器还有按键,全是字符型驱动,

现在新核心板上全换成MISC型驱动了,就出现问题了,我单独去试LED的,分别让它闪十下、六下、五下,效果全是一样,只闪最后四下……
在我另一个程序里,同时调用按键、LED、蜂鸣器三个驱动,发现LED一点都没有反应(主程序里特意加的循环让LED闪一两下的程序都没反应)。

老板子上字符型LED驱动时上述所有情况,一切正常。

老板子:MICRO2440  LINUX 2.6.13
新板子:MICRO2440  LINUX  2.6.32.2

[ 此帖被kasim在2010-01-20 13:49重新编辑 ]
级别: 侠客
UID: 6846
精华: 0
发帖: 55
金钱: 425 两
威望: 215 点
贡献值: 0 点
综合积分: 110 分
注册时间: 2009-06-19
最后登录: 2012-03-21
1楼  发表于: 2010-01-18 11:38
顶顶!!
级别: 侠客
UID: 6846
精华: 0
发帖: 55
金钱: 425 两
威望: 215 点
贡献值: 0 点
综合积分: 110 分
注册时间: 2009-06-19
最后登录: 2012-03-21
2楼  发表于: 2010-01-18 13:38
坛主老大进来帮帮忙啊……
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
贡献值: 71 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
3楼  发表于: 2010-01-18 13:57
如果你觉得友善之臂提供的驱动有问题,用他们提供的测试程序测试一下先;
别人不知道你的程序是怎么写的,怎么帮你?
"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: 6846
精华: 0
发帖: 55
金钱: 425 两
威望: 215 点
贡献值: 0 点
综合积分: 110 分
注册时间: 2009-06-19
最后登录: 2012-03-21
4楼  发表于: 2010-01-18 14:19


是这样的,我用以前的老核心板 2.6.13 内核的,当时这些驱动全是字符型的。
做了个测试LED的测试程序如下:


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>

#include <sys/select.h>

void Delay(int iSec,int iUsec)
{
    struct timeval tv;
    tv.tv_sec=iSec;
    tv.tv_usec=iUsec;
    select(0,NULL,NULL,NULL,&tv);
}

int main(int argc, char **argv)
{
    int on;
    int led_no;
    int fd;
    unsigned long int  mm,nn,oo;
    if (argc != 5 ||  sscanf(argv[1],"%d", &on) != 1 ||    //sscanf(argv[1], "%d", &led_no) != 1 ||
        on < 0 || on > 1 ) {        //|| led_no < 0 || led_no > 3
        fprintf(stderr, "Usage: leds  0|1  times  ontime  offtime \n");  //led_no
        exit(1);
    }

    sscanf(argv[2],"%d",&mm);
    sscanf(argv[3],"%d",&nn);
    sscanf(argv[4],"%d",&oo);

    fd = open("/dev/greenled", 0);  // leds
    if (fd < 0) {
        perror("open device leds");
        exit(1);
    }
    if(on==1) {
        for(;mm--;mm>0)    {
            ioctl(fd,1);
            Delay(0,nn);
            //usleep(nn*10000);
            ioctl(fd,0);
            Delay(0,oo);
            //usleep(oo*10000);
        }
    }
    else {
        ioctl(fd, 0);  //, led_no
    }
    close(fd);
    return 0;
}




相应驱动程序如下:


#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/string.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <linux/gpio.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <asm/unistd.h>


#define DEVICE_NAME "greenled"

#define MYLED_PORT S3C2410_GPF(1)
#define MYLED_CFG  S3C2410_GPIO_OUTPUT

/*
static unsigned long led_table [] = {
    S3C2410_GPB(5),
    S3C2410_GPB(6),
    S3C2410_GPB(7),
    S3C2410_GPB(8),
};

static unsigned int led_cfg_table [] = {
    S3C2410_GPIO_OUTPUT,
    S3C2410_GPIO_OUTPUT,
    S3C2410_GPIO_OUTPUT,
    S3C2410_GPIO_OUTPUT,
};
*/

static int myled_ioctl(      //  sbc2440_leds_ioctl
    struct inode *inode,
    struct file *file,
    unsigned int cmd,
    unsigned long arg)
{
    switch(cmd) {
    case 0:
    case 1:
        if (arg > 4) {
            return -EINVAL;
        }
        //s3c2410_gpio_setpin(led_table[arg], !cmd);
        s3c2410_gpio_setpin(MYLED_PORT, !cmd);            // control LED port kathode ,so 0 will take the led  shine
        return 0;
    default:
        return -EINVAL;
    }
}

static struct file_operations dev_fops = {
    .owner    =    THIS_MODULE,
    .ioctl    =    myled_ioctl,  //sbc2440_leds_ioctl,
};

static struct miscdevice misc = {
    .minor = MISC_DYNAMIC_MINOR,
    .name = DEVICE_NAME,
    .fops = &dev_fops,
};

static int __init myled_init(void)
{
    int ret;
    
/*    int i;
    for (i = 0; i < 4; i++) {
        s3c2410_gpio_cfgpin(led_table, led_cfg_table);
        s3c2410_gpio_setpin(led_table, 0);
    }      */

    ret = misc_register(&misc);
    
    s3c2410_gpio_cfgpin(MYLED_PORT, MYLED_CFG);
    s3c2410_gpio_setpin(MYLED_PORT, 1);
    
    printk (DEVICE_NAME"\tinitialized\n");

    return ret;
}

static void __exit myled_exit(void)
{
    misc_deregister(&misc);
}

module_init(myled_init);
module_exit(myled_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("FriendlyARM Inc.");



测试程序结果:

./myled 1  10  500000  500000
./myled 1  6  500000  500000
./myled 1  5  500000  500000



按理应该是LED闪10次、6次、五次。

实际现象却是:运行每个,只闪最后四次,四次以内的命令,LED闪的才正常……

老内核时同样的测试程序,一直是正常……
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
贡献值: 71 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
5楼  发表于: 2010-01-18 14:42
你可以
1. 等着友善之臂或者什么好心人去运行你的程序;
2. 在你修改过的驱动程序的ioctl()里加上printk()来debug,看看到底执行了几次,每次间隔多久。

不过我可以很确定的告诉你,misc设备就是字符型设备,你的问题和设备类型没有关系。
"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: 6846
精华: 0
发帖: 55
金钱: 425 两
威望: 215 点
贡献值: 0 点
综合积分: 110 分
注册时间: 2009-06-19
最后登录: 2012-03-21
6楼  发表于: 2010-01-18 16:49
谢谢坛主大人!
其实我另一个程序(从2.6.13移植过来的应用程序)里同时用到了蜂鸣器和LED的驱动,两者同是MISC驱动,设备号同为10,如果说同时用,会不会冲突,因为我那个程序里,LED闪都不闪一下(LED和蜂鸣器程序都放在一个单独的线程里了),GPF1端口电平始终为高,没有变过。

我想方法二我是应该去试试了,呵呵,感觉坛主有点像某个群的群主大人,很热心!

级别: 侠客
UID: 6846
精华: 0
发帖: 55
金钱: 425 两
威望: 215 点
贡献值: 0 点
综合积分: 110 分
注册时间: 2009-06-19
最后登录: 2012-03-21
7楼  发表于: 2010-01-20 10:42
引用第5楼kasim于2010-01-18 14:42发表的  :
你可以
1. 等着友善之臂或者什么好心人去运行你的程序;
2. 在你修改过的驱动程序的ioctl()里加上printk()来debug,看看到底执行了几次,每次间隔多久。

不过我可以很确定的告诉你,misc设备就是字符型设备,你的问题和设备类型没有关系。



刚才试了一下,让发光管闪一下,理应是LED状态被修改两次,我用你说的方法二,发现一个规律:

led  1  10  500000  500000    //让LED闪十下,一个周期是一秒钟。

效果是:
前六下ioctl( ) 里的PRINTK是每一秒一次,后八次是每半秒一次  算了一下,前六次相当于一个LED闪周期只有一次PRINTK,后八次相当于一个LED闪周期有两次PRINTK。  
试验次数变为15    20  效果都一样,现象:后四次闪正常,前 N-4次LED不闪……   坛主大人指点指点我……

change led port times:0
change led port times:1
change led port times:2
change led port times:3
change led port times:4
change led port times:5  // 一秒一次到这里结束  下面是半秒PRINTK一次……
change led port times:6
change led port times:7
change led port times:8
change led port times:9
change led port times:10
change led port times:11
change led port times:12
change led port times:13
级别: 侠客
UID: 6846
精华: 0
发帖: 55
金钱: 425 两
威望: 215 点
贡献值: 0 点
综合积分: 110 分
注册时间: 2009-06-19
最后登录: 2012-03-21
8楼  发表于: 2010-01-20 11:43
级别: 侠客
UID: 6846
精华: 0
发帖: 55
金钱: 425 两
威望: 215 点
贡献值: 0 点
综合积分: 110 分
注册时间: 2009-06-19
最后登录: 2012-03-21
9楼  发表于: 2010-01-20 13:28
喷血的错误啊!!  

测试程序里写到:  for(;mm--;mm>0)    {

其实不仔细看还真看不出来,太马虎啦!   修正为: for(;mm>=0;mm--)    {   就正常了……


    
  • «
  • 1
  • 2
  • »
  • Pages: 1/2     Go