arm7(S3C44B0X)键盘中断驱动程序
2008-10-06 22:18
417 查看
1. uClinux-dist/linux-2.4.x/drivers/char/led.h
#define LED_MAGIC 'k'
#define LED1 _IO (LED_MAGIC, 1)
#define LED4 _IO (LED_MAGIC, 4)
#define LED5 _IO (LED_MAGIC, 5)
#define LED6 _IO (LED_MAGIC, 6)
#define LED7 _IO (LED_MAGIC, 7)
#define TURNON 0
#define TURNOFF 1
static int led_open (struct inode *inode, struct file *file);
static int led_release (struct inode *inode, struct file *file);
int led_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
void led_interrupt(int irq, void *dev_id, struct pt_regs *regs);
2. uClinux-dist/linux-2.4.x/drivers/char/led.c
#include <linux/module.h>
#include <linux/config.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/fs.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/mach/irq.h>
#include <asm/arch/irqs.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include "led.h"
#define LED_NR 2
MODULE_LICENSE ("GPL");
int led_major = 254;
int state[LED_NR];
struct led_local {
unsigned long eint;
void (*interrupt)(int irq, void *dev_id, struct pt_regs *regs);
unsigned long sa;
char *device;
};
struct led_local led_local[LED_NR] = {
{S3C44B0X_INTERRUPT_EINT0, led_interrupt, SA_INTERRUPT, "led4"},
{S3C44B0X_INTERRUPT_EINT1, led_interrupt, SA_INTERRUPT, "led5"},
// {S3C44B0X_INTERRUPT_EINT4567, led_interrupt, SA_INTERRUPT, "led6"},
// {S3C44B0X_INTERRUPT_EINT4567, led_interrupt, SA_INTERRUPT, "led7"}
};
static int led_open (struct inode *inode, struct file *file)
{
printk (KERN_INFO "Hey! device opened/n");
return 0;
}
static int led_release (struct inode *inode, struct file *file)
{
printk (KERN_INFO "Hmmm! device closed/n");
return 0;
}
void led_manager(int arg, int nr)
{
if (arg == 0) {
printk (KERN_INFO "Turn on LED%d/n", nr);
outb(inb(S3C44B0X_PDATE) & ~(1 << (nr - 1)), S3C44B0X_PDATE);
} else if (arg == 1) {
printk (KERN_INFO "Turn off LED%d/n", nr);
outb(inb(S3C44B0X_PDATE) | (1 << (nr - 1)), S3C44B0X_PDATE);
} else
printk (KERN_INFO "Wrong arg/n");
}
int led_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
int ret = 0;
int nr = _IOC_NR(cmd);
led_manager(arg, nr);
return ret;
}
struct file_operations led_fops = {
.owner = THIS_MODULE,
.open = led_open,
.release = led_release,
.ioctl = led_ioctl,
};
void led_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
printk (KERN_WARNING"led_interrupt device = %s /n", (char*)dev_id);
if (irq == S3C44B0X_INTERRUPT_EINT0)
led_manager((++state[0])%2, 4);
else if (irq == S3C44B0X_INTERRUPT_EINT1)
led_manager((++state[1])%2, 5);
else
printk (KERN_WARNING"wrong irq: %d", irq);
}
static int __init led_init (void)
{
int result, i;
request_region(S3C44B0X_PCONE, 12, "led");
result = register_chrdev(led_major, "led", &led_fops);
if (result<0) {
printk (KERN_WARNING "led: can't get major number %d/n", led_major);
return result;
}
outl(0x00025569, S3C44B0X_PCONE);
outb((inl(S3C44B0X_PDATE) & 0x06), S3C44B0X_PDATE);
printk (KERN_INFO "led_ioctl driver done/n");
for (i = 0; i < LED_NR; i ++) {
result = request_irq(led_local[i].eint, led_local[i].interrupt,
led_local[i].sa, led_local[i].device, led_local[i].device);
if (result) {
printk(KERN_INFO "led: can't get assigned irq %i/n", led_local[i].eint);
} else
printk(KERN_INFO "led: get assigned irq %i/n", led_local[i].eint);
enable_irq(led_local[i].eint);
}
printk(KERN_INFO "S3C44B0X_PCONG=0x%x/n", inw(S3C44B0X_PCONG));
// 将多功能端口G设置为中断功能
outw(0xffff, S3C44B0X_PCONG);
printk(KERN_INFO "S3C44B0X_PCONG=0x%x/n", inw(S3C44B0X_PCONG));
return 0;
}
static void __exit led_exit (void)
{
release_region(S3C44B0X_PCONE, 12);
unregister_chrdev(led_major, "led");
printk (KERN_INFO "led_ioctl cleaned up/n");
}
module_init (led_init);
module_exit (led_exit);
3. 输出
# more /proc/interrupts
3: 111 s3c44b0_uart_tx
7: 20 s3c44b0_uart_rx
8: 567 timer
22: 0 ads7843_ts
23: 1 cs89x0
24: 0 led5
25: 0 led4
Err: 0
# led_interrupt device = led5
Turn off LED5
led_interrupt device = led5
Turn on LED5
led_interrupt device = led5
Turn off LED5
# more /proc/interrupts
3: 152 s3c44b0_uart_tx
7: 22 s3c44b0_uart_rx
8: 1365 timer
22: 0 ads7843_ts
23: 1 cs89x0
24: 3 led5
25: 0 led4
Err: 0
#define LED_MAGIC 'k'
#define LED1 _IO (LED_MAGIC, 1)
#define LED4 _IO (LED_MAGIC, 4)
#define LED5 _IO (LED_MAGIC, 5)
#define LED6 _IO (LED_MAGIC, 6)
#define LED7 _IO (LED_MAGIC, 7)
#define TURNON 0
#define TURNOFF 1
static int led_open (struct inode *inode, struct file *file);
static int led_release (struct inode *inode, struct file *file);
int led_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
void led_interrupt(int irq, void *dev_id, struct pt_regs *regs);
2. uClinux-dist/linux-2.4.x/drivers/char/led.c
#include <linux/module.h>
#include <linux/config.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/fs.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/mach/irq.h>
#include <asm/arch/irqs.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include "led.h"
#define LED_NR 2
MODULE_LICENSE ("GPL");
int led_major = 254;
int state[LED_NR];
struct led_local {
unsigned long eint;
void (*interrupt)(int irq, void *dev_id, struct pt_regs *regs);
unsigned long sa;
char *device;
};
struct led_local led_local[LED_NR] = {
{S3C44B0X_INTERRUPT_EINT0, led_interrupt, SA_INTERRUPT, "led4"},
{S3C44B0X_INTERRUPT_EINT1, led_interrupt, SA_INTERRUPT, "led5"},
// {S3C44B0X_INTERRUPT_EINT4567, led_interrupt, SA_INTERRUPT, "led6"},
// {S3C44B0X_INTERRUPT_EINT4567, led_interrupt, SA_INTERRUPT, "led7"}
};
static int led_open (struct inode *inode, struct file *file)
{
printk (KERN_INFO "Hey! device opened/n");
return 0;
}
static int led_release (struct inode *inode, struct file *file)
{
printk (KERN_INFO "Hmmm! device closed/n");
return 0;
}
void led_manager(int arg, int nr)
{
if (arg == 0) {
printk (KERN_INFO "Turn on LED%d/n", nr);
outb(inb(S3C44B0X_PDATE) & ~(1 << (nr - 1)), S3C44B0X_PDATE);
} else if (arg == 1) {
printk (KERN_INFO "Turn off LED%d/n", nr);
outb(inb(S3C44B0X_PDATE) | (1 << (nr - 1)), S3C44B0X_PDATE);
} else
printk (KERN_INFO "Wrong arg/n");
}
int led_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
int ret = 0;
int nr = _IOC_NR(cmd);
led_manager(arg, nr);
return ret;
}
struct file_operations led_fops = {
.owner = THIS_MODULE,
.open = led_open,
.release = led_release,
.ioctl = led_ioctl,
};
void led_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
printk (KERN_WARNING"led_interrupt device = %s /n", (char*)dev_id);
if (irq == S3C44B0X_INTERRUPT_EINT0)
led_manager((++state[0])%2, 4);
else if (irq == S3C44B0X_INTERRUPT_EINT1)
led_manager((++state[1])%2, 5);
else
printk (KERN_WARNING"wrong irq: %d", irq);
}
static int __init led_init (void)
{
int result, i;
request_region(S3C44B0X_PCONE, 12, "led");
result = register_chrdev(led_major, "led", &led_fops);
if (result<0) {
printk (KERN_WARNING "led: can't get major number %d/n", led_major);
return result;
}
outl(0x00025569, S3C44B0X_PCONE);
outb((inl(S3C44B0X_PDATE) & 0x06), S3C44B0X_PDATE);
printk (KERN_INFO "led_ioctl driver done/n");
for (i = 0; i < LED_NR; i ++) {
result = request_irq(led_local[i].eint, led_local[i].interrupt,
led_local[i].sa, led_local[i].device, led_local[i].device);
if (result) {
printk(KERN_INFO "led: can't get assigned irq %i/n", led_local[i].eint);
} else
printk(KERN_INFO "led: get assigned irq %i/n", led_local[i].eint);
enable_irq(led_local[i].eint);
}
printk(KERN_INFO "S3C44B0X_PCONG=0x%x/n", inw(S3C44B0X_PCONG));
// 将多功能端口G设置为中断功能
outw(0xffff, S3C44B0X_PCONG);
printk(KERN_INFO "S3C44B0X_PCONG=0x%x/n", inw(S3C44B0X_PCONG));
return 0;
}
static void __exit led_exit (void)
{
release_region(S3C44B0X_PCONE, 12);
unregister_chrdev(led_major, "led");
printk (KERN_INFO "led_ioctl cleaned up/n");
}
module_init (led_init);
module_exit (led_exit);
3. 输出
# more /proc/interrupts
3: 111 s3c44b0_uart_tx
7: 20 s3c44b0_uart_rx
8: 567 timer
22: 0 ads7843_ts
23: 1 cs89x0
24: 0 led5
25: 0 led4
Err: 0
# led_interrupt device = led5
Turn off LED5
led_interrupt device = led5
Turn on LED5
led_interrupt device = led5
Turn off LED5
# more /proc/interrupts
3: 152 s3c44b0_uart_tx
7: 22 s3c44b0_uart_rx
8: 1365 timer
22: 0 ads7843_ts
23: 1 cs89x0
24: 3 led5
25: 0 led4
Err: 0
相关文章推荐
- S3C44B0X按键键盘的uClinux驱动程序设计
- S3C44B0X键盘的uClinux驱动程序设计
- S3C44B0X键盘的uClinux驱动程序设计
- arm7(S3C44B0X)数码管驱动程序
- S3C44B0X按键键盘的uClinux驱动程序设计
- ARM7键盘工作原理及中断方式实现(C语言)
- 按键驱动程序设计---混杂设备、中断分层处理、工作队列、阻塞型驱动
- Linux中断(interrupt)子系统之四:驱动程序接口层 & 中断通用逻辑层
- 深入浅出分析Linux设备驱动程序中断
- Linux设备驱动程序之中断(下半部机制)
- 键盘和鼠标是如何提请系统中断的
- serio总线------虚拟键盘驱动--键盘中断
- Linux设备驱动程序之中断与时钟(二)
- Linux中断处理驱动程序编写
- 字符设备驱动程序开发之基于中断的按键驱动加去抖动
- CC2541 独立键盘中断触发
- 由一次对arm7的中断选择寄存器(VICIntSelect)赋值而引发的思考
- arm7 键盘扫描程序
- 『转』第二章 Windows CE下驱动程序的中断处理
- 第12课第4.3节 字符设备驱动程序之中断方式的按键驱动_编写代码