- 论坛徽章:
- 0
|
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/interrupt.h>
//#include <asm/memory.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#define KEYNUM 5
#define KEY_UP 0
#define KEY_DOWN 1
#define KEY_DOWNX 2
#define MAJOR 255
#define KEY_TIMER_DELAY (HZ/50)
#define GPIOG_REG_ADDR 0x56000064//gpio_g data register phys address
struct b_dev
{
struct cdev b_cdev;
char key_state_buf[KEYNUM];//up or down
unsigned int irq[KEYNUM];
struct timer_list tl;
};
struct b_dev *pb_dev;
int b_open(struct inode * inodep,struct file * filp)
{
return 0;
}
int b_release(struct inode * inodep,struct file * filp)
{
return 0;
}
int b_read(struct file * filp,char * buf,size_t size,loff_t offset)
{
if(!access_ok(VERIFY_WRITE,buf,size))
{
printk(KERN_INFO "buf can't write\n"
return -EFAULT;
}
int key_num,count=0;
for(key_num=0;key_num!=KEYNUM;key_num++)
{
if(pb_dev->key_state_buf[key_num]==KEY_DOWNX && count<size)
{
put_user('0'+key_num,buf+count);
pb_dev->key_state_buf[key_num]=KEY_UP;
count++;
}
}
return count;
}
struct file_operations f_ops=
{
.open=b_open,
.read=b_read,
.release=b_release,
.owner=THIS_MODULE,
};
void timer_handler(unsigned long sleep_time)
{
unsigned int *p_gpiog=__va(GPIOG_REG_ADDR);//phys address to virtual address
unsigned int gpio_g=*p_gpiog;
if(gpio_g & 0x0001 && pb_dev->key_state_buf[0] == KEY_DOWN){
//button 1
pb_dev->key_state_buf[0]=KEY_DOWNX;
}
else if(gpio_g & 0x0008 && pb_dev->key_state_buf[1] == KEY_DOWN){
//button 2
pb_dev->key_state_buf[1]=KEY_DOWNX;
}
else if(gpio_g & 0x0020 && pb_dev->key_state_buf[2] == KEY_DOWN){
//button 3
pb_dev->key_state_buf[2]=KEY_DOWNX;
}
else if(gpio_g & 0x0040 && pb_dev->key_state_buf[3] == KEY_DOWN){
//button 4
pb_dev->key_state_buf[3]=KEY_DOWNX;
}
else if(gpio_g & 0x0080 && pb_dev->key_state_buf[4] == KEY_DOWN){
//button 5
pb_dev->key_state_buf[4]=KEY_DOWNX;
}
else if(gpio_g & 0x0800 && pb_dev->key_state_buf[5] == KEY_DOWN){
//button 6
pb_dev->key_state_buf[5]=KEY_DOWNX;
}
printk(KERN_INFO "timer\n"
}
void irq_handler(int irq,void *dev_id,struct pt_regs *regs)
{
pb_dev->tl.expires=jiffies+KEY_TIMER_DELAY;
add_timer(&pb_dev->tl);
switch(irq)
{
case 16+36:
pb_dev->key_state_buf[0]=KEY_DOWN;
break;
case 16+39:
pb_dev->key_state_buf[1]=KEY_DOWN;
break;
case 16+41:
pb_dev->key_state_buf[2]=KEY_DOWN;
break;
case 16+42:
pb_dev->key_state_buf[3]=KEY_DOWN;
break;
case 16+43:
pb_dev->key_state_buf[4]=KEY_DOWN;
break;
case 16+47:
pb_dev->key_state_buf[5]=KEY_DOWN;
break;
default:
break;
}
printk(KERN_INFO "IRQ\n"
}
void init_irqs()
{
pb_dev->irq[0]=16+36;
pb_dev->irq[1]=16+39;
pb_dev->irq[2]=16+41;
pb_dev->irq[3]=16+42;
pb_dev->irq[4]=16+43;
pb_dev->irq[5]=16+47;
int key_num;
for(key_num=0;key_num<KEYNUM;key_num++)
{
request_irq(pb_dev->irq[key_num],irq_handler,SA_SHIRQ,"buttons",pb_dev);
set_irq_type(pb_dev->irq[key_num],IRQ_TYPE_EDGE_FALLING);
}
}
static int b_init(void)
{
pb_dev=kmalloc(sizeof(struct b_dev),GFP_KERNEL);
memset(pb_dev,0,sizeof(struct b_dev));
int key_num;
for(key_num=0;key_num<KEYNUM;key_num++)
{
pb_dev->key_state_buf[key_num]=KEY_UP;
}
dev_t devno;
devno=MKDEV(MAJOR,0);
cdev_init(&pb_dev->b_cdev,&f_ops);
pb_dev->b_cdev.owner=THIS_MODULE;
pb_dev->b_cdev.ops=&f_ops;
int err=cdev_add(&pb_dev->b_cdev,devno,1);
if(err)
printk(KERN_NOTICE "Error %d\n",err);
setup_timer(&pb_dev->tl,timer_handler,20);
init_irqs();
printk(KERN_INFO "init over\n"
}
static void b_exit(void)
{
int key_num;
for(key_num=0;key_num<KEYNUM;key_num++)
{
free_irq(pb_dev->irq[key_num],pb_dev);
}
cdev_del(&pb_dev->b_cdev);
kfree(pb_dev);
unregister_chrdev_region(MKDEV(MAJOR,0),1);
}
MODULE_AUTHOR("scy"
MODULE_LICENSE("Dual BSD/GPL"
module_init(b_init);
module_exit(b_exit);
当有按键时,系统就会报错
[root@FriendlyARM /]# IRQ
irq event 59: bogus return value 7
[ <c02d37e8>] (dump_stack+0x0/0x14) from [ <c00606ac>] (__report_bad_irq+0x28/0x94
)
[ <c0060684>] (__report_bad_irq+0x0/0x94) from [ <c006088c>] (note_interrupt+0x174
/0x1f0)
r5:c03d5be0 r4:c03d5be0
[ <c0060718>] (note_interrupt+0x0/0x1f0) from [ <c0060fb4>] (handle_edge_irq+0xc0/
0x160)
[ <c0060ef4>] (handle_edge_irq+0x0/0x160) from [ <c0032764>] (s3c_irq_demux_extint
8+0x9c/0xa
r7:c03ff284 r6:00000001 r5:00000000 r4:0000003b
[ <c00326c8>] (s3c_irq_demux_extint8+0x0/0xa from [ <c0028044>] (__exception_tex
t_start+0x44/0x70)
r7:c03ff284 r6:00000000 r5:c0425474 r4:00000015
[ <c0028000>] (__exception_text_start+0x0/0x70) from [ <c0028a44>] (__irq_svc+0x24
/0xa0)
Exception stack(0xc03cdf40 to 0xc03cdf8
df40: f4100000 00000032 f4100000 60000013 c0029edc c03cc000 c0029edc c03ff284
df60: 3001c920 41129200 3001c8ec c03cdf94 c03cdf98 c03cdf88 c002a4f8 c0029f3c
df80: 60000013 ffffffff
r7:c03ff284 r6:00000020 r5:f4000000 r4:ffffffff
[ <c0029edc>] (default_idle+0x0/0xac) from [ <c002a4f8>] (cpu_idle+0x4c/0x6
[ <c002a4ac>] (cpu_idle+0x0/0x6 from [ <c02d2124>] (rest_init+0x5c/0x70)
r7:c03d0440 r6:c001e000 r5:c03ff240 r4:c0423264
[ <c02d20c8>] (rest_init+0x0/0x70) from [ <c0008930>] (start_kernel+0x200/0x26
[ <c0008730>] (start_kernel+0x0/0x26 from [ <30008034>] (0x30008034)
r6:c001ed34 r5:c03ff35c r4:c0007175
handlers:
[ <bf000440>] (irq_handler+0x0/0x130 [my_bdri])
Unable to handle kernel paging request at virtual address e6000064
pgd = c3acc000
[e6000064] *pgd=00000000
Internal error: Oops: 5 [#1]
Modules linked in: my_bdri
CPU: 0 Not tainted (2.6.29.4-FriendlyARM #2)
PC is at timer_handler+0x10/0x118 [my_bdri]
LR is at run_timer_softirq+0x1b0/0x230
pc : [ <bf0000cc>] lr : [ <c0044c80>] psr: 20000013
sp : c03cde80 ip : c03cde90 fp : c03cde8c
r10: c04211c8 r9 : c03d4140 r8 : c03cc000
r7 : bf0000bc r6 : c03cdea0 r5 : 00000100 r4 : c04209c0
r3 : e6000000 r2 : c03cdea0 r1 : c3a612dc r0 : 00000014
Flags: nzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel
Control: c000717f Table: 33acc000 DAC: 00000017
Process swapper (pid: 0, stack limit = 0xc03cc26
Stack: (0xc03cde80 to 0xc03ce000)
de80: c03cded4 c03cde90 c0044c80 bf0000cc c03cdeb4 c04217c8 c04215c8 c04213c8
dea0: c03cdea0 c03cdea0 c03cdecc 00000004 00000001 00000100 c03cc000 c04207e0
dec0: 00000001 0000000a c03cdf0c c03cded8 c0040204 c0044ae0 c03d5514 c03d2c58
dee0: 0000001e 0000001e c0425474 00000000 c03ff284 3001c920 41129200 3001c8ec
df00: c03cdf1c c03cdf10 c00402cc c0040198 c03cdf3c c03cdf20 c0028048 c0040294
df20: ffffffff f4000000 00004000 c03ff284 c03cdf94 c03cdf40 c0028a44 c0028010
df40: f4100000 00000032 f4100000 60000013 c0029edc c03cc000 c0029edc c03ff284
df60: 3001c920 41129200 3001c8ec c03cdf94 c03cdf98 c03cdf88 c002a4f8 c0029f3c
df80: 60000013 ffffffff c03cdfb4 c03cdf98 c002a4f8 c0029eec c0423264 c03ff240
dfa0: c001e000 c03d0440 c03cdfc4 c03cdfb8 c02d2124 c002a4bc c03cdff4 c03cdfc8
dfc0: c0008930 c02d20d8 c0008470 00000000 00000000 c001ed38 00000000 c0007175
dfe0: c03ff35c c001ed34 00000000 c03cdff8 30008034 c0008740 00000000 00000000
Backtrace:
[ <bf0000bc>] (timer_handler+0x0/0x118 [my_bdri]) from [ <c0044c80>] (run_timer_so
ftirq+0x1b0/0x230)
[ <c0044ad0>] (run_timer_softirq+0x0/0x230) from [ <c0040204>] (__do_softirq+0x7c/
0xfc)
[ <c0040188>] (__do_softirq+0x0/0xfc) from [ <c00402cc>] (irq_exit+0x48/0x50)
[ <c0040284>] (irq_exit+0x0/0x50) from [ <c0028048>] (__exception_text_start+0x48/
0x70)
[ <c0028000>] (__exception_text_start+0x0/0x70) from [ <c0028a44>] (__irq_svc+0x24
/0xa0)
Exception stack(0xc03cdf40 to 0xc03cdf8
df40: f4100000 00000032 f4100000 60000013 c0029edc c03cc000 c0029edc c03ff284
df60: 3001c920 41129200 3001c8ec c03cdf94 c03cdf98 c03cdf88 c002a4f8 c0029f3c
df80: 60000013 ffffffff
r7:c03ff284 r6:00004000 r5:f4000000 r4:ffffffff
[ <c0029edc>] (default_idle+0x0/0xac) from [ <c002a4f8>] (cpu_idle+0x4c/0x6
[ <c002a4ac>] (cpu_idle+0x0/0x68) from [ <c02d2124>] (rest_init+0x5c/0x70)
r7:c03d0440 r6:c001e000 r5:c03ff240 r4:c0423264
[ <c02d20c8>] (rest_init+0x0/0x70) from [ <c0008930>] (start_kernel+0x200/0x268)
[ <c0008730>] (start_kernel+0x0/0x268) from [ <30008034>] (0x30008034)
r6:c001ed34 r5:c03ff35c r4:c0007175
Code: e1a0c00d e92dd800 e24cb004 e3a034e6 (e5931064)
Kernel panic - not syncing: Fatal exception in interrupt
==================================================================================
求高手帮助解决。。 |
|