主题 : 编写camera  ov9650驱动中遇到的问题 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 1648
精华: 0
发帖: 4
金钱: 40 两
威望: 4 点
综合积分: 8 分
注册时间: 2008-09-17
最后登录: 2008-12-19
楼主  发表于: 2008-12-09 15:08

 编写camera  ov9650驱动中遇到的问题

自己编写的ov9650驱动,在GEC2440(内核为2.6.12)上面测试很好使,但在咱们qq2440(内核为2.6.13)板子上面遇到了问题,发现IIC初始化可以正常读取camera的ID,之后发现可以不断的进入中断,却无法唤醒在read中的睡眠进程,我在内核中跟踪睡眠和唤醒函数,一直跟到调度器,目前没发现什么问题,再往下跟能力不够了,我怀疑camera驱动是不是还要依赖于其他的驱动,或者需要做什么特别设置,因为在GEC2440上面,它本来是支持camera模块的,而咱们的qq买的时候是不支持的,唉,郁闷坏了,望各位知道的帮帮我吧~~~非常感谢。。
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
1楼  发表于: 2008-12-10 06:53
贴出你写的驱动源代码;
贴出驱动加载后的dmesg命令输出
"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: 1648
精华: 0
发帖: 4
金钱: 40 两
威望: 4 点
综合积分: 8 分
注册时间: 2008-09-17
最后登录: 2008-12-19
2楼  发表于: 2008-12-10 12:21
中断处理程序如下:
// run in irq disabled state
static irqreturn_t s3c2440_camif_isr_c(int irq, void *dev_id, struct pt_regs *regs)
{
    unsigned long tmp;

    struct s3c2440_camif *dev = (struct s3c2440_camif*)dev_id;


    tmp = __raw_readl(S3C2410_GPFDAT);
    tmp ^= 1<<4;    //LED0
    __raw_writel(tmp,S3C2410_GPFDAT);


#if 1
    if(dev->flag&1) {
        if(dev->flag&0x200) {
            dev->flag = 0;
            complete(&dev->stop);
        } else if(dev->flag&0x100) {
            stop_capture(dev);
#ifdef CAMERA_STOP_QUICKLY
            dev->flag = 0;
            complete(&dev->stop);
#endif
        } else
#ifdef SKIP_FIRST_FRAME
        if(dev->flag&4)
#endif
        {
            if(!(dev->flag&2)) {
                stop_capture(dev);
#ifdef CAMERA_STOP_QUICKLY
                dev->flag = 0;
#endif
            }
//            register_wake_pid();

            count++;
            dev->rdy = 1;
            wake_up_interruptible(&dev->wait);

        }
        dev->flag |= 4;
    } else {
        printk(KERN_ERR "flag is 0x%08x\n", dev->flag);
        dev->flag = 1;    //error state, must not happen
        stop_capture(dev);
        printk(KERN_ERR "%s.%d: camera BUG!\n", __FILE__, __LINE__);
    }
#endif
    return IRQ_HANDLED;
}

读函数:
static long v4l_cam_read(struct video_device *v, char *buf, unsigned long count, int noblock)
{
    unsigned long flags;
    int retval = 0;
    struct s3c2440_camif *dev = (struct s3c2440_camif *)(v->priv);

            
    if(noblock) {
        if(down_trylock(&dev->change))
            return -EAGAIN;
    } else {
        if(down_interruptible(&dev->change))
            return -EINTR;
    }

    local_irq_save(flags);
    if(!dev->rdy) {
        if(noblock)
            retval = -EAGAIN;
        else {

            printk("v4l_cam_read:wait for camera frame\n");
            interruptible_sleep_on(&dev->wait);
            if(!dev->rdy)
                retval = -EINTR;
        }
    }
    local_irq_restore(flags);

    if(!retval) {        //now if retval==0, dev->rdy must be 1
        dev->rdy = 0;    //clear ready flag
        retval = min(count, dev->size);
        if(copy_to_user(buf, (void *)camif_yuv_buf, retval))    //can copy 0 byte
            retval = -EFAULT;
        //printk("%d,%d\n", count, dev->size);
    }
    
    up(&dev->change);

    return retval;
}

插入模块后dmesg的输出信息如下:
<5>Linux version 2.6.13 (root@localhost.localdomain) (gcc version 3.4.1) #104 Mon Dec 8 16:10:12 CST 2008
<4>CPU: ARM920Tid(wb) [41129200] revision 0 (ARMv4T)
<4>Machine: SBC2440
<7>Converting old-style param struct to taglist
<4>ATAG_INITRD is deprecated; please update your bootloader.
<4>Memory policy: ECC disabled, Data cache writeback
<4>CPU S3C2440A (id 0x32440001)
<4>BUG: mapping for 0x19000000 at 0xd0000000 overlaps vmalloc space
<4>S3C2440: core 405.000 MHz, memory 101.250 MHz, peripheral 50.625 MHz
<6>S3C2410 Clocks, (c) 2004 Simtec Electronics
<7>On node 0 totalpages: 16384
<7>  DMA zone: 16384 pages, LIFO batch:7
<7>  Normal zone: 0 pages, LIFO batch:1
<7>  HighMem zone: 0 pages, LIFO batch:1
<4>CPU0: D VIVT write-back cache
<4>CPU0: I cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets
<4>CPU0: D cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets
<4>Built 1 zonelists
<5>Kernel command line: console=ttySAC0 root=/dev/nfs nfsroot=192.168.1.104:/opt/FriendlyARM/QQ2440/root_qtopia_tp  ip=192.168.1.110:192.168.1.104:192.168.1.1:255.255.255.0:matrix4.arm9.net:eth0:off
<4>irq: clearing pending ext status 00000300
<4>irq: clearing subpending status 00000002
<4>PID hash table entries: 512 (order: 9, 8192 bytes)
<4>timer tcon=00000000, tcnt a4ca, tcfg 00000200,00000000, usec 00001e57
<4>Console: colour dummy device 80x30
<7>selected clock c02abc40 (pclk) quot 26, calc 117187
<4>Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)
<4>Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)
<6>Memory: 64MB = 64MB total
<5>Memory: 61696KB available (2329K code, 581K data, 148K init)
<7>Calibrating delay loop... 202.34 BogoMIPS (lpj=505856)
<4>Mount-cache hash table entries: 512
<6>CPU: Testing write buffer coherency: ok
<6>NET: Registered protocol family 16
<4>USB Power Control, (c) 2004 Simtec Electronics
<4>S3C2440: Initialising architecture
<4>S3C2440: IRQ Support
<4>S3C2440: Clock Support, UPLL 48.000 MHz
<5>SCSI subsystem initialized
<6>usbcore: registered new driver hub
<4>S3C2410 DMA Driver, (c) 2003-2004 Simtec Electronics
<4>DMA channel 0 at c4800000, irq 33
<4>DMA channel 1 at c4800040, irq 34
<4>DMA channel 2 at c4800080, irq 35
<4>DMA channel 3 at c48000c0, irq 36
<4>NetWinder Floating Point Emulator V0.97 (double precision)
<6>devfs: 2004-01-31 Richard Gooch (rgooch@atnf.csiro.au)
<6>devfs: boot_options: 0x1
<4>yaffs Dec  8 2008 16:07:52 Installing.
<6>Initializing Cryptographic API
<4>Console: switching to colour frame buffer device 64x30
<6>S3C24X0 fb0: s3c2410fb frame buffer device initialize done
<4>GPIO L3 bus interface for S3C2440, installed
<4>S3C2410 RTC, (c) 2004 Simtec Electronics
<6>s3c2410-rtc s3c2410-rtc: rtc disabled, re-enabling
<4>leds initialized
<6>Serial: 8250/16550 driver $Revision: 1.90 $ 4 ports, IRQ sharing disabled
<4>s3c2410_serial0 at MMIO 0x50000000 (irq = 70) is a S3C2440
<4>devfs_mk_dev: could not append to parent for tts/0
<4>s3c2410_serial1 at MMIO 0x50004000 (irq = 73) is a S3C2440
<4>devfs_mk_dev: could not append to parent for tts/1
<4>s3c2410_serial2 at MMIO 0x50008000 (irq = 76) is a S3C2440
<4>devfs_mk_dev: could not append to parent for tts/2
<6>io scheduler noop registered
<6>io scheduler anticipatory registered
<6>io scheduler deadline registered
<6>io scheduler cfq registered
<4>RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize
<6>loop: loaded (max 8 devices)
<6>nbd: registered device at major 43
<4>Cirrus Logic CS8900A driver for Linux (Modified for SMDK2410)
<6>eth0: CS8900A rev E at 0xd0000300 irq=53, no eeprom , addr: 08: 0:3E:26:0A:5B
<6>Uniform Multi-Platform E-IDE driver Revision: 7.00alpha2
<6>ide: Assuming 50MHz system bus speed for PIO modes; override with idebus=xx
<4>ide_s3c2440_init
<4>ide0: S3C2410 IDE interface
<7>Probing IDE interface ide0...
<4>S3C24XX NAND Driver, (c) 2004 Simtec Electronics
<7>s3c2410_nand_probe(c027929c)
<6>s3c2410-nand: mapped registers at c4880000
<7>result 1 from 101250, 0
<7>result 297 from 101250, 30
<4>30 ns is too big for current clock rate 101250
<7>result 1 from 101250, 0
<6>s3c2410-nand: timing: Tacls 0ns, Twrph0 4294ns, Twrph1 0ns
<7>s3c2410-nand: NF_CONF is 0xfffffe00
<7>initialising set 0 (c3c62400, info c3d119e0)
<6>NAND device: Manufacturer ID: 0xec, Chip ID: 0x76 (Samsung NAND 64MiB 3,3V 8-bit)
<6>Scanning device for bad blocks
<5>Creating 3 MTD partitions on "NAND 64MiB 3,3V 8-bit":
<5>0x00000000-0x00030000 : "bootloader"
<6>mtd: Giving out device 0 to bootloader
<5>0x00050000-0x00250000 : "kernel"
<6>mtd: Giving out device 1 to kernel
<5>0x00250000-0x03ffc000 : "root"
<6>mtd: Giving out device 2 to root
<7>initialised ok
<6>s3c2410-ohci s3c2410-ohci: S3C24XX OHCI
<6>s3c2410-ohci s3c2410-ohci: new USB bus registered, assigned bus number 1
<6>s3c2410-ohci s3c2410-ohci: irq 42, io mem 0x49000000
<6>hub 1-0:1.0: USB hub found
<6>hub 1-0:1.0: 2 ports detected
<6>Initializing USB Mass Storage driver...
<6>usbcore: registered new driver usb-storage
<6>USB Mass Storage support registered.
<6>usbcore: registered new driver usbhid
<6>drivers/usb/input/hid-core.c: v2.01:USB HID core driver
<6>mice: PS/2 mouse device common for all mice
<6>ts: Compaq touchscreen protocol output
<7>Entering s3c2410ts_init
<7>got and enabled clock
<6>s3c2410 TouchScreen successfully loaded
<6>i2c /dev entries driver
<7>i2c-core: driver dev_driver registered.
<7>s3c2440-i2c s3c2440-i2c: clock source c0277c68
<7>s3c2440-i2c s3c2440-i2c: registers c4b80000 (c3d454a0, c0278d9c)
<6>s3c2440-i2c s3c2440-i2c: slave address 0x10
<7>s3c2440-i2c s3c2440-i2c: pdata c02b27f4, freq 100000 0..400000
<6>s3c2440-i2c s3c2440-i2c: bus frequency set to 98 KHz
<7>s3c2440-i2c s3c2440-i2c: S3C2410_IICCON=0xe0
<7>s3c2440-i2c s3c2440-i2c: S3C2440_IICLC=00000005
<7>s3c2440-i2c s3c2440-i2c: irq resource c0278db8 (43)
<7>i2c_adapter i2c-0: Registered as minor 0
<7>i2c_adapter i2c-0: registered as adapter #0
<6>s3c2440-i2c s3c2440-i2c: i2c-0: S3C I2C adapter
<6>mmci-s3c2410: probe: mapped sdi_base=c4d00000 irq=37 irq_cd=60 dma=0.
<6>mmci-s3c2410: initialisation done.
<4>SBC2440 SOUND driver register
<4>SBC2440 SOUND driver probe!
<4>SBC2440 UDA1341 audio driver initialized
<6>NET: Registered protocol family 2
<4>IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
<4>TCP established hash table entries: 4096 (order: 3, 32768 bytes)
<4>TCP bind hash table entries: 4096 (order: 2, 16384 bytes)
<6>TCP: Hash tables configured (established 4096 bind 4096)
<6>TCP reno registered
<6>TCP bic registered
<6>NET: Registered protocol family 1
<6>NET: Registered protocol family 17
<7>MMC: starting cmd 00 arg 00000000 flags 00000000
<7>MMC: sd_app_op_cond to 00100000
<7>MMC: starting cmd 37 arg 00000000 flags 00000009
<3>MMC: sd_app_op_cond: at least one card is busy - trying again.
<7>MMC: starting cmd 37 arg 00000000 flags 00000009
<3>MMC: sd_app_op_cond: at least one card is busy - trying again.
<7>MMC: starting cmd 37 arg 00000000 flags 00000009
<3>MMC: sd_app_op_cond: at least one card is busy - trying again.
<7>MMC: starting cmd 37 arg 00000000 flags 00000009
<3>MMC: sd_app_op_cond: at least one card is busy - trying again.
<7>MMC: starting cmd 37 arg 00000000 flags 00000009
<3>MMC: sd_app_op_cond: at least one card is busy - trying again.
<7>MMC: starting cmd 37 arg 00000000 flags 00000009
<3>MMC: sd_app_op_cond: at least one card is busy - trying again.
<7>MMC: starting cmd 37 arg 00000000 flags 00000009
<3>MMC: sd_app_op_cond: at least one card is busy - trying again.
<7>MMC: starting cmd 37 arg 00000000 flags 00000009
<3>MMC: sd_app_op_cond: at least one card is busy - trying again.
<7>MMC: starting cmd 37 arg 00000000 flags 00000009
<3>MMC: sd_app_op_cond: at least one card is busy - trying again.
<7>MMC: starting cmd 37 arg 00000000 flags 00000009
<3>MMC: sd_app_op_cond: at least one card is busy - trying again.
<3>MMC: sd_app_op_cond locked busy. Probably have broken SD-Card.
<7>MMC: starting cmd 02 arg 00000000 flags 00000002
<7>MMC: starting cmd 01 arg 00100000 flags 00000001
<7>MMC: starting cmd 02 arg 00000000 flags 00000002
<4>IP-Config: Complete:
<4>      device=eth0, addr=192.168.1.110, mask=255.255.255.0, gw=192.168.1.1,
<4>     host=matrix4, domain=, nis-domain=arm9.net,
<4>     bootserver=192.168.1.104, rootserver=192.168.1.104, rootpath=
<5>Looking up port of RPC 100003/2 on 192.168.1.104
<5>Looking up port of RPC 100005/1 on 192.168.1.104
<4>VFS: Mounted root (nfs filesystem).
<6>Mounted devfs on /dev
<6>Freeing init memory: 148K
<7>selected clock c02abc40 (pclk) quot 26, calc 117187
<7>selected clock c02abc40 (pclk) quot 26, calc 117187
<7>selected clock c02abc40 (pclk) quot 26, calc 117187
<7>selected clock c02abc40 (pclk) quot 26, calc 117187
<7>selected clock c02abc40 (pclk) quot 26, calc 117187
<7>selected clock c02abc40 (pclk) quot 26, calc 117187
<6>Linux video capture interface: v1.00
<4>Product ID is 0x9652
<4>Initial camera now,Please wait several minutes...
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
3楼  发表于: 2008-12-11 06:48
我没有看到read()函数里面的"v4l_cam_read:wait for camera frame"这句log打印出来啊;
另外,在中断处理函数里,wake_up_interruptible(&dev->wait);之前以及read()里的interruptiable_sleep_on()之后最好也加上log来验证
"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: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
4楼  发表于: 2008-12-11 07:07
方便的话,把你写的完整的驱动程序源代码发给我吧.ling_kasim@yahoo.cn
"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: 1648
精华: 0
发帖: 4
金钱: 40 两
威望: 4 点
综合积分: 8 分
注册时间: 2008-09-17
最后登录: 2008-12-19
5楼  发表于: 2008-12-11 08:28
引用第3楼kasim于2008-12-11 06:48发表的  :
我没有看到read()函数里面的"v4l_cam_read:wait for camera frame"这句log打印出来啊;
另外,在中断处理函数里,wake_up_interruptible(&dev->wait);之前以及read()里的interruptiable_sleep_on()之后最好也加上log来验证


没有打出来,是因为我没有运行测试程序,指示插入了模块,因为一运行程序后,中断唤醒不了read,就会不断的陷入中断中死机。好的,我这就给您发过去,多谢哈
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
6楼  发表于: 2008-12-11 09:54
就算是中断唤醒不了read,也不会陷入中断死机吧.你可以试试先跑一个cat /proc/kmsg &, 然后跑测试程序,看看串口上能输出什么
"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: 1648
精华: 0
发帖: 4
金钱: 40 两
威望: 4 点
综合积分: 8 分
注册时间: 2008-09-17
最后登录: 2008-12-19
7楼  发表于: 2008-12-11 11:29
版主,问题搞定了,在你们的内核文件中发现一个问题,不知道是你们当初的bug还是什么,源码如下:
arch/arm/mach-s3c2410/s3c2440-irq.c中:
/* camera irq */

static void s3c_irq_demux_cam(unsigned int irq,
                  struct irqdesc *desc,
                  struct pt_regs *regs)
{
    unsigned int subsrc, submsk;
    struct irqdesc *mydesc;

    /* read the current pending interrupts, and the mask
     * for what it is available */

    subsrc = __raw_readl(S3C2410_SUBSRCPND);
    submsk = __raw_readl(S3C2410_INTSUBMSK);

    subsrc &= ~submsk;
    subsrc >>= 11;
    subsrc &= 3;

    if (subsrc != 0) {
        if (subsrc & 1) {
            mydesc = irq_desc + IRQ_S3C2440_CAM_C;
            mydesc->handle( IRQ_S3C2440_WDT, mydesc, regs);
        }
        if (subsrc & 2) {
            mydesc = irq_desc + IRQ_S3C2440_CAM_P;
            mydesc->handle(IRQ_S3C2440_AC97, mydesc, regs);
        }
    }
}

camera的中断,在handle中却定义的是音频和看门狗的中断,把这个改了就成了
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
8楼  发表于: 2008-12-11 17:28
谢谢, 不过不要把这个bug算到"你们"头上,友善之臂可不付我钱的
"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."