supercjb
一般會員
發表:14 回覆:6 積分:4 註冊:2004-11-09
發送簡訊給我
|
我是使用altera nios 架設uclinux系統,且我在\driver\chart目錄底下找到有一個altera_pio_button.c 內容如下:
--------------------------------------------------------------
/*
* linux/drivers/char/altera_pio_button.c
* A simple character driver that takes buttons on Nios Development
* Kit as an input device (major 62)
*
* The characters input can be '1', '2', '4' or '8'
*
* Copyright (C) 2004 Microtronix Datacom Ltd
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Written by Wentao Xu
*/ #include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include #define BUTTON_MAJOR 62 #define PIO_BUTTON_BASE na_button_pio
#define PIO_BUTTON_IRQ na_button_pio_irq
#define PIO_BUTTON_SIZE sizeof(np_pio) #define PDEBUG printk #define BUTTON_BUF_SIZE 100
struct _button_info {
int count;
int head;
int tail;
char buf[BUTTON_BUF_SIZE];
} button_info; static int button_in_use=0;
static struct file_operations button_fops; static DECLARE_MUTEX(button_mutex);
static DECLARE_WAIT_QUEUE_HEAD(button_wait_queue); static void button_handle_event(void *dev_id)
{
static int old = 0;
int status, key;
np_pio* pio = (np_pio *)dev_id; outl(0, &pio->np_pioedgecapture);
/* read input, check 4 buttons */
status = (~inl(&pio->np_piodata)) & 0xF;
key = status - old;
old = status;
if (key > 0) {
down(&button_mutex);
/* we simply discard new inputs if buffer overflows */
if (button_info.count < BUTTON_BUF_SIZE) {
button_info.buf[button_info.tail] = key '0';
button_info.tail = (button_info.tail 1) % BUTTON_BUF_SIZE;
button_info.count ;
}
up(&button_mutex);
/* wake up any waiting reader */
if (waitqueue_active(&button_wait_queue)) {
wake_up_interruptible(&button_wait_queue);
}
} /* re-enable interrupts */
outl(-1, &pio->np_piointerruptmask);
} static DECLARE_WORK(button_work, button_handle_event, (void*)PIO_BUTTON_BASE);
static irqreturn_t pio_button_isr(int irq, void *dev_id, struct pt_regs *regs)
{
np_pio* pio = (np_pio *)dev_id;
if (!pio)
return IRQ_NONE; /* disable interrupt */
outl(0, &pio->np_pioedgecapture);
outl(0, &pio->np_piointerruptmask); /* activate the bottom half */
schedule_work(&button_work);
return IRQ_HANDLED;
}
static int button_start(void)
{
np_pio *pio=(np_pio *)(PIO_BUTTON_BASE);
outl(0, &pio->np_pioedgecapture);
outl(0, &pio->np_piodirection); /* register interrupt */
if (request_irq(PIO_BUTTON_IRQ, pio_button_isr, SA_INTERRUPT, "pio_button",
(void*)(PIO_BUTTON_BASE))) {
printk("pio_button: unable to register interrupt %d\n", PIO_BUTTON_IRQ);
return -1;
}
outl(-1, &pio->np_piointerruptmask); return 0;
}
/*
* Open/close .
*/
static int button_open(struct inode *inode, struct file *filp)
{
const int minor = iminor(inode); if (minor == 0) {
preempt_disable();
if (button_in_use) {
preempt_enable();
return -EBUSY;
}
/* open succeeds */
button_in_use=1;
preempt_enable();
/* init buffon info */
button_info.count=0;
button_info.head=0;
button_info.tail=0;
/* init buttons */
button_start();
return 0;
}
else
return -ENODEV;
} /*
*/
static int button_release(struct inode *inode, struct file *filp)
{
button_in_use=0;
free_irq(PIO_BUTTON_IRQ, (void*)(PIO_BUTTON_BASE));
return 0;
} /*
*/
static int
button_ioctl(struct inode *inode, struct file *filp,
unsigned int command, unsigned long arg)
{
return -EINVAL;
} static ssize_t button_read(struct file *file, char *buf,
size_t count, loff_t * ppos)
{
int i, total;
if (button_info.count==0) {
DEFINE_WAIT(wait);
if (file->f_flags & O_NONBLOCK)
return -EAGAIN;
while (!signal_pending(current) && (button_info.count == 0)) {
prepare_to_wait(&button_wait_queue, &wait, TASK_INTERRUPTIBLE);
if (!signal_pending(current) && (button_info.count == 0))
schedule();
finish_wait(&button_wait_queue, &wait);
}
}
if (signal_pending(current))
return -ERESTARTSYS;
/* return data */
down(&button_mutex);
total = (count < button_info.count) ? count : button_info.count;
for (i=0; i < total; i ) {
put_user(button_info.buf[button_info.head], buf i);
button_info.head = (button_info.head 1) % BUTTON_BUF_SIZE;
button_info.count--;
}
up(&button_mutex);
return total;
}
static struct file_operations button_fops = {
.read = button_read,
.open = button_open,
.release= button_release,
.ioctl = button_ioctl,
.owner = THIS_MODULE,
}; static int __init button_init(void)
{
int i;
if (!(request_mem_region((unsigned long)PIO_BUTTON_BASE, PIO_BUTTON_SIZE, "pio_button")))
return -1;
if ((i=register_chrdev(BUTTON_MAJOR, "pio_button", &button_fops))<0) {
printk("buttons: fail to get major %d\n", BUTTON_MAJOR);
release_mem_region((unsigned long)PIO_BUTTON_BASE, PIO_BUTTON_SIZE);
return i;
}
return 0;
} static void __exit button_exit(void)
{
unregister_chrdev(BUTTON_MAJOR, "pio_button");
release_mem_region((unsigned long)PIO_BUTTON_BASE, PIO_BUTTON_SIZE);
} module_init(button_init);
module_exit(button_exit);
MODULE_LICENSE("GPL");
----------------------------------------------------------------
請問我該如何調用這驅動程式裡面的一些function到我的程式裏面,還有就是該如何更改中斷服務程式?
|