tar czvf key4.tgz key4 该课的程序所在的目录 devfs_fs_kernel devfs_register来注册设备 release对应的是close的操作 keys4_clearirq函数用于清当前中断,防止中断的不断执行 sema_init() 查找华恒关于中断的实验手册可见
啊 哦!后来发现是头文件中arch的连接曾经被更改导致没有找到应该找到的头文件,所以没有找到那些arch-s3c2410的头文件
代码
驱动层
#i nclude <linux/module.h>
#i nclude <linux/init.h> #i nclude <linux/kernel.h>
#i nclude <linux/sched.h>
#i nclude <linux/timer.h> #i nclude <linux/interrupt.h> //#i nclude <asm/irq.h> //#i nclude <asm/hardware.h> #i nclude <asm/uaccess.h> //#i nclude <asm/arch/irqs.h> //#i nclude <asm/io.h> #i nclude <asm/semaphore.h> #i nclude <linux/major.h> #i nclude <linux/vmalloc.h> #i nclude <linux/fs.h>
#i nclude <linux/devfs_fs_kernel.h>
#i nclude <asm-arm/arch-s3c2410/irqs.h> #i nclude <asm-arm/arch-s3c2410/hardware.h> #i nclude <asm-arm/arch-s3c2410/S3C2410.h> #i nclude <asm-arm/arch-s3c2410/io.h>
//#define EXT_FALLING_EDGE 2
#define KEYS4_MAJOR 138
#define NOKEY 0
#define KEY1 '1' #define KEY2 '2' #define KEY3 '3' #define KEY4 '4' extern int set_external_irq(int irq, int edge, int pullup); extern void disable_irq(unsigned int); extern void enable_irq(unsigned int);
//static ssize_t keys4_read(struct inode *inode, char *buf, unsigned long count);
//int keys4_open(struct inode *inode, struct file *file); //void keys4_release(struct inode *inode, struct file *filp); static struct semaphore key_sem; static char key = NOKEY;
devfs_handle_t devfs_keys4;
static void keys4_clearirq(void) { /*respond to EINT2-EINT5*/ SRCPND &= (~0x0000001c); //bit2,3,4 INTPND = INTPND; EINTPEND &= (~0x0000003c); //bit2,3,4,5 }
static void key1_irq_isr(int irq, void *dev_id, struct pt_regs *regs)
{ keys4_clearirq(); // SRCPND &= (~0x0000001c); //bit2,3,4 // INTPND = INTPND; // EINTPEND &= (~0x0000003c); //bit2,3,4,5 key=KEY1; up(&key_sem); } static void key2_irq_isr(int irq, void *dev_id, struct pt_regs *regs) { keys4_clearirq(); // SRCPND &= (~0x0000001c); //bit2,3,4 // INTPND = INTPND; // EINTPEND &= (~0x0000003c); //bit2,3,4,5 key=KEY2; up(&key_sem); }
static void key3_irq_isr(int irq, void *dev_id, struct pt_regs *regs)
{ keys4_clearirq(); // SRCPND &= (~0x0000001c); //bit2,3,4 // INTPND = INTPND; // EINTPEND &= (~0x0000003c); //bit2,3,4,5 key=KEY3; up(&key_sem); } static void key4_irq_isr(int irq, void *dev_id, struct pt_regs *regs) { keys4_clearirq(); // SRCPND &= (~0x0000001c); //bit2,3,4 // INTPND = INTPND; // EINTPEND &= (~0x0000003c); //bit2,3,4,5 key=KEY4; up(&key_sem); }
static ssize_t keys4_read(struct file *file, char *buf, size_t size,loff_t *l)
{ down_interruptible(&key_sem); put_user(key,buf); key=NOKEY; return 1; }
int keys4_open(struct inode *inode, struct file *file)
{
// keys4_clearirq();
// enable_irq(IRQ_EINT2); // enable_irq(IRQ_EINT3); // enable_irq(IRQ_EINT4); // enable_irq(IRQ_EINT5); sema_init(&key_sem,0); return 0; }
int keys4_release(struct inode *inode, struct file *filp)
{ // keys4_cleanirq(); // disable_irq(IRQ_EINT2); // disable_irq(IRQ_EINT3); // disable_irq(IRQ_EINT4); // disable_irq(IRQ_EINT5); printk("release ok!/n"); return 0; } struct file_operations keys4_fops = { read:keys4_read, open:keys4_open, release:keys4_release, };
static int __init keys4_init(void)
{ static int rc; // unsigned long gpfup; printk("<1>start init/n");
set_external_irq(IRQ_EINT2,EXT_FALLING_EDGE, GPIO_PULLUP_DIS);
set_external_irq(IRQ_EINT3,EXT_FALLING_EDGE, GPIO_PULLUP_DIS); set_external_irq(IRQ_EINT4,EXT_FALLING_EDGE, GPIO_PULLUP_DIS); set_external_irq(IRQ_EINT5,EXT_FALLING_EDGE, GPIO_PULLUP_DIS); printk("<1>start disable irq/n"); // gpfup = ioremap(0x56000058,4); // gpfup = iomem_valid_addr(0x56000058,4); // (*(volatile unsigned long *)gpfup) &= 0xc3; //bit2,3,4,5 = 0.
disable_irq(IRQ_EINT2);
enable_irq(IRQ_EINT2); disable_irq(IRQ_EINT3); enable_irq(IRQ_EINT3); disable_irq(IRQ_EINT4); enable_irq(IRQ_EINT4); disable_irq(IRQ_EINT5); enable_irq(IRQ_EINT5); printk("<1>start request_irq/n"); rc = request_irq(IRQ_EINT5, key1_irq_isr, SA_INTERRUPT, "keys4", NULL); if (rc) { printk("<1>keys4irq 1 irq not registered. Error: %d/n", rc); } rc = request_irq(IRQ_EINT4, key2_irq_isr, SA_INTERRUPT, "keys4", NULL); if (rc) { printk("<1>keyirq 2 irq not registered. Error: %d/n", rc); } rc = request_irq(IRQ_EINT3, key3_irq_isr, SA_INTERRUPT, "keys4", NULL); if (rc) { printk("<1>keyirq 3 irq not registered. Error: %d/n", rc); }
rc = request_irq(IRQ_EINT2, key4_irq_isr, SA_INTERRUPT, "keys4", NULL);
if (rc) { printk("<1>keyirq 4 irq not registered. Error: %d/n", rc); } // disable_irq(IRQ_EINT2); // disable_irq(IRQ_EINT3); // disable_irq(IRQ_EINT4); // disable_irq(IRQ_EINT5);
printk("<1>*********keys4 init ok!***********/n");
/* Register myirq as character device */ devfs_keys4 = devfs_register(NULL,"keys4",DEVFS_FL_DEFAULT,KEYS4_MAJOR, 0, S_IFCHR |S_IRUSR |S_IWUSR |S_IRGRP |S_IWGRP, &keys4_fops, NULL); /* if ((rc = register_chrdev(keyirq_MAJOR, "keys4", &keys4_fops)) < 0) { printk("keyirq: can't get major %d/n",keyirq_MAJOR); return; } */ return 0; }
static void __exit keys4_exit(void)
{ printk("<1>start exit/n"); disable_irq(IRQ_EINT2); disable_irq(IRQ_EINT3); disable_irq(IRQ_EINT4); disable_irq(IRQ_EINT5);
printk("<1>start freeirq/n");
free_irq(IRQ_EINT5, NULL); free_irq(IRQ_EINT4, NULL); free_irq(IRQ_EINT3, NULL); free_irq(IRQ_EINT2, NULL);
printk("<1>end exit/n");
devfs_unregister(devfs_keys4);
}
module_init(keys4_init);
module_exit(keys4_exit);
//__initcall(keys4_init);
Makefile
CC = /opt/host/armv4l/bin/armv4l-unknown-linux-gcc
LD = /opt/host/armv4l/bin/armv4l-unknown-linux-ld CFLAGS = -D__KERNEL__ -I/HHARM2410-STUDY/kernel/include/linux -I/HHARM2410-STUDY/kernel/include -Wall -Wstrict-prototypes -Wno-trigraphs -Os -mapcs -fno-strict-aliasing -fno-common -fno-common -pipe -mapcs-32 -march=armv4 -mtune=arm9tdmi -mshort-load-bytes -msoft-float -DKBUILD_BASENAME=s3c2410_testirq -I/opt/host/armv4l/src/linux/include -DMODULE
keys4.o: keys4.c
$(CC) $(CFLAGS) -c $< -o $@ # cp keys4.o / -f .PHONY: clean clean: -rm -f *.o
distclean:
@make clean rm -f tags *~
应用层
#i nclude <stdio.h>
#i nclude <sys/types.h> #i nclude <sys/stat.h> #i nclude <fcntl.h>
#define NOKEY 0
int main()
{ int keys4_fd; char ret[2]; keys4_fd = open("/dev/keys4", O_RDONLY); if(keys4_fd<=0) { printf("open keys4 device error!/n"); return 0; } while(1) { read(keys4_fd,ret,1);
if (ret[0] != NOKEY)
{ printf("key = %c/n",ret[0]); } usleep(100000); } close(keys4_fd); return 0; } |