• «
  • 1
  • 2
  • »
  • Pages: 1/2     Go
主题 : 写驱动的高手请进 复制链接 | 浏览器收藏 | 打印
级别: 侠客
UID: 3278
精华: 0
发帖: 61
金钱: 600 两
威望: 576 点
综合积分: 122 分
注册时间: 2009-01-03
最后登录: 2011-03-07
楼主  发表于: 2009-04-11 17:11

 写驱动的高手请进

哪位高手知道s3c2440a的usb device controller的中断IRQ?
我搞了很久都测不到它的IRQ.
级别: 侠客
UID: 944
精华: 3
发帖: 71
金钱: 22760 两
威望: 4838 点
综合积分: 202 分
注册时间: 2008-06-27
最后登录: 2017-07-16
1楼  发表于: 2009-04-11 19:52
scc2440芯片手册上有啊,看看EP_INT_EN_REG, USB_INT_EN_REG是不是使能了相关的中断。usb device 产生的中断是INT_USBD
级别: 侠客
UID: 3278
精华: 0
发帖: 61
金钱: 600 两
威望: 576 点
综合积分: 122 分
注册时间: 2009-01-03
最后登录: 2011-03-07
2楼  发表于: 2009-04-12 11:23
问题不是那么简单。
当device controller中断,PIC就会mask掉这个中断源。
假设是为了避免cpu core不断地被中断,那至少会有一个IRQ中断了一次
但我查看/proc/stat, 没有一个IRQ显示为1

想不通这是什么状况
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
3楼  发表于: 2009-04-12 13:04
根据S3C2440A的手册第14章的INTERRUPT SOURCES, USB Device Controller (USBD) 的确只有一个中断源 (INT_USBD USB Device interrupt ARB4)

如果你发现这个中断的处理函数始终没有被调用到,检查一下Interrupt Controller的几个寄存器(SRCPND, INTMSK, INTPND)状态吧, 另外就是USBD本身几个和中断有关的寄存器配置:

EP_INT_REG (EP0–EP4) Endpoint interrupt register 0x148(L) / 0x14B(B)
USB_INT_REG USB interrupt register 0x158(L) / 0x15B(B)
EP_INT_EN_REG (EP0–EP4) Endpoint interrupt enable register 0x15C(L) / 0x15F(B)
USB_INT_EN_REG USB Interrupt enable register 0x16C(L) / 0x16F(B)

方便的话,把你的程序源代码和出现的问题错误信息贴出来吧
"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: 3278
精华: 0
发帖: 61
金钱: 600 两
威望: 576 点
综合积分: 122 分
注册时间: 2009-01-03
最后登录: 2011-03-07
4楼  发表于: 2009-04-12 20:25

 回 3楼(kasim) 的帖子

我的源代码irq_probe.c本来是用来做irq probing的,但怎样都测试不到usb device controller(下面简称USBD)的IRQ.
现在都改得面目全非了,只有输出SRCPND, INTMSK中USBD对应的位。
再者,我在host上实现了一个驱动,经过测试,能够向s3c2440a 的USBD的EP3传送字符串

irq_probe.c的源代码如下:
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/ioport.h>

#include <asm/delay.h>
#include <asm/io.h>

#include "../utils/pic_utils.h"

MODULE_LICENSE("GPL");

int irq = 0;
int *probe_id;
int result[NR_IRQS];

irqreturn_t irq_handler(int irq, void *id){
    printk("key one");
    return IRQ_HANDLED;
}

static void irq_cleanup(void){
    
}

static int irq_init(void){
    void *srcpnd = NULL;
    void *ep_int = NULL;
    void *intmsk = NULL;

        /* 自定义函数iomem_remap()  --  获取并重映射io memory region */
    ep_int = iomem_remap(EP_INT_REG, USBD_LEN, "irq_probe");
    if (!ep_int)
        goto exit0;

    srcpnd = iomem_remap(SRCPND_REG, INT_LEN, "irq_probe");
    if (!srcpnd)
        goto exit1;
    
    intmsk = iomem_remap(INTMSK_REG, INT_LEN, "irq_probe");
    if (!intmsk)
        goto exit2;

    printk(KERN_DEBUG "USBD source pending %i\n",\
                (ioread32(srcpnd) >> 25) & 0x00000001);
    printk(KERN_DEBUG "USBD interrupt mask %i\n", \
                (ioread32(intmsk) >> 25) & 0x00000001);
    printk(KERN_DEBUG "EP3 pending interrupt %i\n",\
                    (ioread8(ep_int) >> 3) & 0x01);

    iowrite32(ioread32(intmsk) & ~(1 << 25), intmsk);
exit2:
    iomem_unmap(INTMSK_REG, INT_LEN, intmsk);
exit1:
    iomem_unmap(SRCPND_REG, INT_LEN, srcpnd);
exit0:
    iomem_unmap(EP_INT_REG, USBD_LEN, ep_int);

    return -EFAULT;
}

module_init(irq_init);
module_exit(irq_cleanup);

我所做的测试步骤是:
A.从host向USBD输入若干字符;/* 这样EP3就会发出中断, 提示EP3 的FIFO中有数据等待处理 */
B.在mini2440上挂载如上的irq_probe.ko模块;
/* 不论挂载多少次irq_probe.ko, 终端中始终显示为
USBD source pending 1
USBD interrupt mask  1
EP3 pending interrupt 1

但若忽略步骤A,那么显示如下
USBD source pending 0
USBD interrupt mask  0
EP3 pending interrupt 0
*/

从上面的结果,我得出USBD源是不断发出终端,而且是从EP3发出的,
但PIC(interrupt controller)把他mask掉了,以致终端不能到达cpu core.
开始的时候以为USBD对应的IRQ会被触发一次后,USBD源才被mask掉(避免cpu core不断被中断)。
但对被/proc/interrupts 和 /proc/stat后发现除了5、6个已被系统占用的IRQ,其他IRQ还是0

对s3c2440a还是不太熟悉,不知道我这样推测对不对。版主帮帮忙吧。
级别: 侠客
UID: 3278
精华: 0
发帖: 61
金钱: 600 两
威望: 576 点
综合积分: 122 分
注册时间: 2009-01-03
最后登录: 2011-03-07
5楼  发表于: 2009-04-12 20:28
忘了说,由于irq_probe.ko只用于输出信息,所以总是返回错误,是不能挂载进内核的
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
6楼  发表于: 2009-04-12 23:46
如果你的内核中,没有驱动申请了USBD的IRQ(通过request_irq()),那该IRQ会默认被Mask起来。
另外,如果你要调试S3C2440的USBD模块,建议你使用内核自带的S3C2440的USBD驱动(drivers/usb/gadget/s3c2410_udc.c)和S3C24x0 interrupt controller驱动自己的debug机制,不要使用自己的debug代码,除非你对Linux内核的IRQ管理非常熟悉。
"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: 3278
精华: 0
发帖: 61
金钱: 600 两
威望: 576 点
综合积分: 122 分
注册时间: 2009-01-03
最后登录: 2011-03-07
7楼  发表于: 2009-04-13 10:30

 回 6楼(kasim) 的帖子

Got it ! and thanks!!
级别: 侠客
UID: 3278
精华: 0
发帖: 61
金钱: 600 两
威望: 576 点
综合积分: 122 分
注册时间: 2009-01-03
最后登录: 2011-03-07
8楼  发表于: 2009-04-13 13:20
还有一个问题,就是应该怎样测试出USBD的IRQ呢?
用内核probe_irq_on(),然后怎样触发USBD的中断呢?
级别: 侠客
UID: 3278
精华: 0
发帖: 61
金钱: 600 两
威望: 576 点
综合积分: 122 分
注册时间: 2009-01-03
最后登录: 2011-03-07
9楼  发表于: 2009-04-13 17:18
很讽刺,probe_irq_on()返回的mask竟然是0,哪还怎样测试IRQ啊?
版主Kasim不要吝啬,赐教一下。
内核是从这里下载的2.6.29
  • «
  • 1
  • 2
  • »
  • Pages: 1/2     Go