QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1501|回复: 3

请大家帮我看看问题在哪里(中断服务函数不能被执行)

[复制链接]
发表于 2006-6-29 11:57:53 | 显示全部楼层 |阅读模式
学写 Linux Driver ,用的 虚拟机 Vmware, 串口1 已经链接 并且 Output 到文件。现在 Driver 加载成功, Output 也能够看到 输出的 0x1A ,串口的 发送成功寄存器内容正确,但是 我的中断服务函数却没有被执行,请帮忙分析一下。下面是 code:
------------------------------------ 发送数据以后的 IO Region -----
Port 0x3f8 has value 0x0 (00000000).
Port 0x3f9 has value 0x3 (00000011).
Port 0x3fa has value 0x2 (00000010).
Port 0x3fb has value 0x7 (00000111).
Port 0x3fc has value 0x3 (00000011).
-----------------------------------------------------------------------
      1 #include <linux/module.h>
      2 #include <linux/fs.h>
      3 #include <linux/slab.h>
      4 #include <linux/ioport.h>
      5 #include <asm/uaccess.h>
      6 #include <asm/io.h>
      7 #include <asm/irq.h>
      8
      9 #include "zlz.h"
     10
     11 int  zlz_com1_region ;
     12 int  zlz_com1_irq;
     13
     14 unsigned char com1_pos = 0;
     15 unsigned char com1_inb[ 128 ];
     16
     17
     18 ssize_t zlz_read( struct file * fp, char * buff, size_t size, loff_t * lp )
     19 {
     20         if( com1_pos  ){
     21                 copy_to_user( buff, ( com1_inb + com1_pos-- ) , 1 );
     22                 return 1;
     23         }
     24         else{
     25                 return 0;
     26         }
     27 }
     28 ssize_t zlz_write( struct file * fp , const char * buff , size_t size, loff_t * lp )
     29 {
     30         char port;
     31
     32         copy_from_user(  &port, buff, 1 );
     33         outb( port, 0x3f8 );
     34
     35         return 1;
     36 }
     37 int zlz_open( struct inode * ip , struct file * fp )
     38 {
     39         return 0;
     40 }
     41 int zlz_release( struct inode * ip , struct file * fp )
     42 {
     43         return 0;
     44 }
     45
     46 struct file_operations zlz_fops = {
     47         read    : zlz_read,
     48         write   : zlz_write,
     49         open    : zlz_open,
     50         release : zlz_release,
     51 };
     52
     53 void zlz_com1_hdlr( int irq, void * dev_id, struct pt_regs * regs )
     54 {
     55         unsigned char i;
     56
     57         printk("<1> zlz_com1_hdlr \n");
     58
     59         i = inb( 0x3fa );
     60         if( !( i & 0x01) ){
     61                 switch( i &  0x0E0 ){
     62                         case 0x00: /* modem sts change */
     63                                 break;
     64                         case 0x01: /* snd keep */
     65                                 break;
     66                         case 0x02: /* rcv ok */
     67                                 if( com1_pos < 128 ){
     68                                         com1_inb[ com1_pos++ ] = inb( 0x3f8 );
     69                                 }else{
     70                                         com1_inb[ com1_pos ] = inb( 0x3f8 );
     71                                 }
     72                                 break;
     73                         case 0x03: /*  rcv error */
     74                                 break;
     75                         default:
     76                                 break;
     77                 }
     78         }
     79 }
     80
     81 void zlz_exit( void )
     82 {
     83         unregister_chrdev( 254, "zlz" );
     84
     85         if( zlz_com1_region == 0 ){
     86                 release_region( 0x3f8, 7 );
     87         }
     88         
     89         if( zlz_com1_irq == 0 ){        //success
     90                 free_irq( IRQ_4, NULL );
     91         }
     92 }
     93
     94 int zlz_init( void )
     95 {      
     96         int result;
     97         
     98         result = register_chrdev( 254 , "zlz" , &zlz_fops );
     99         if( result < 0 ){
    100                 return result ;
    101         }      
    102                        
    103         zlz_com1_region = check_region( 0x3f8 , 7 );
    104         if ( zlz_com1_region == 0 ){
    105                 request_region( 0x3f8 , 7 , "zlz_COM1" );
    106         }else{         
    107                 goto fail;      
    108         }                              
    109                                 
    110         /* 8 bits ouput */              
    111         outb( 0x07, 0x3fb );   
    112                                 
    113         /* link our interrupt handler to system */
    114         zlz_com1_irq = request_irq( IRQ_4, zlz_com1_hdlr, SA_INTERRUPT, "zlz_COM1", NULL );
    115         if( zlz_com1_irq != 0 ){        //success
    116                 goto fail;      
    117         }      
    118         
    119         /* enable 8255 irq */
    120         outb( 0x03, 0x3f9 );
    121
    122         return 0;
    123 fail:
    124         zlz_exit();
    125         return result;
    126 }
    127
    128
    129
    130
    131 MODULE_LICENSE("GPL");
    132
    133 module_init( zlz_init );
    134 module_exit( zlz_exit );
    135
    136
-------------------------------------------------
#include <stdio.h>
#include <stdlib.h>

int main( void )
{
        FILE *filp;
        int i;

        filp = fopen( "/dev/zlz0","r+w" );
        if( filp == NULL ){
                return 0;
        }

        i = fputc( 0x1A, filp );
        if( i ){
                printf(" Put Character 0x1A \n ");
        }

        fclose( filp );

}
发表于 2006-6-29 14:31:59 | 显示全部楼层
What is the kernel version of your system?

I suspect the line
zlz_com1_irq = request_irq( IRQ_4, zlz_com1_hdlr, SA_INTERRUPT, "zlz_COM1", NULL );

I think it shoud be:

zlz_com1_irq = request_irq( IRQ_4, zlz_com1_hdlr, SA_INTERRUPT, "zlz_COM1", (void*)zlz_com1_hdlr);
回复

使用道具 举报

 楼主| 发表于 2006-6-29 15:41:39 | 显示全部楼层
内核 是 2.4.26

应该不是  ...... SA_INTERRUPT, (void*)zlz_com1_hdlr);  的问题,因为 按照你的建议进行修改,仍然不好用。谢谢
回复

使用道具 举报

发表于 2006-6-30 09:19:40 | 显示全部楼层
Sorry, I know nothing about 2.4 and Vmware
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-23 03:40 , Processed in 0.070409 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表