|
学写 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 );
} |
|