一个uclinux s3c4510b 下的外部中断的驱动
一直都前一段一直在学这个东西,最后找到杜云海前辈写的一篇文章,照抄了一下,编译通过了,因为原文档是个不允许复制粘贴的pdf,所以我只能自己手工敲了.谢谢李明老师一直的热心指导.两个文件,一个.c另一个.h
如下:
/*
*extint.c : external interrupt demo device driver of uClinux, making use of GPIO 8
*as external interrupt source on samsung s3c 4510b.
*see extint.h for MACRO DEFINITION
*Copyright(C) 2005.millionwood <[email protected]>
*This software is released under the GPL licence.
*version 0.15 july, 2005
*/
#include "extint.h"
static int extint_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
{
return 0;
}
static int extint_write(struct file *filp, char *buf, size_t count, loff_t *f_pos)
{
return 0;
}
static int extint_ioctl(struct inode *inode, struct file *flip,unsigned int cmd, unsigned longarg)
{
return 0;
}
static int extint_open(struct inode *inode, struct file *flip)
{
MOD_INC_USE_COUNT;
printk("<0>somebody open extint\n");
return 0;
}
static int extint_release(struct inode *inode, struct file *flip)
{
MOD_DEC_USE_COUNT;
printk("<0>somebody close extint\n");
return 0;
}
void extint_handle(int irq, void *dev_id, struct pt_regs *regs)
{
CLEAR_PEND_INT(EXTINT_IRQ);
printk("somebody touches the extint button\n\r");
printk("setting and starting the DMA \n\r");
GDMASRC0=0x3600000;// DMA source addr
GDMADST0=(unsigned long)data_collum0; // DMA destination addr
GDMACNT0=320; // DMA counts
GDMACON0=0x2881; //DMA control register
printk(" DMA finished\n\r");
}
/*
* BELOW is initialization, setting its irq number and set it as FIQ(fast interrupt request) mode
*/
void extint_init(viod)
{
int ret;
int extint_irq = EXTINT_IRQ;
ret = register_chrdev(EXTINT_MAJOR, "extint", &extint_fops);
if(ret<0) {
printk("failed to register EXTINT_NAME\n");
}
CLEAR_PEND_INT(EXTINT_IRQ);
if(extint_irq>=0){
ret = request_irq(EXTINT_IRQ, extint_handle, SA_INTERRUPT, "extint", NULL) ;
if(ret){
printk("extint: can NOT get assignedirq %i\n", extint_irq);
}
else{
printk("extint: request external interrupt %i\n",extint_irq);
INT_ENABLE(EXTINT_IRQ); // clear the corresponding INTMASK register bit to open the interrupt
SET_EXTINT(EXTINT_IRQ); //set the corresponding bit in register IOPCON
}
}
}
/*
*extint.h: external interrupt demo device drvier of uClinux
*
*Copyright(C) 2005,millionwood <[email protected]>
*
*This software is released under the GPL-license.
*
*version 01.5july, 2005
*
*
*/
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/ioctl.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <asm-armnommu/uaccess.h>
#include <asm-armnommu/arch-snds100/hardware.h>
#include <asm-armnommu/arch-snds100/irq.h>
#include <asm-armnommu/arch-snds100/irqs.h>
#include <asm-armnommu/signal.h>
#ifdef MODULE
#include <linux/module.h>
#include <linux/version.h>
#else
#define MOD_INC_USE_COUNT
#define MOD_DEC_USE_COUNT
#endif
#define VPint *(volatile unsigned int *)
#define outl(data,addr) (VPint(addr) = (data))
#define inl(addr) (VPint(addr))
#define IopCon (VPint(IOPCON))
#define SET_EXTINT(n)IopCon |=(0x10<<(5*n))//set as external interrupt
#define EXTINT_NAME "extint"
#define EXTINT_MAJOR 240
#define EXTINT_IRQ INT_EXTINT0 //irq0=0,INT_EXTINT0 defined in file uclinux\linux2.4x\include\asm-armnommu\arch-snds100\irqs.h
/******GDMA CONTROL****/
#define GDMACON0(*(volatile long *)0x3ffB000)
#define GDMACON1(*(volatile long *)0x3ffC000)
#define GDMASRC0(*(volatile long *)0x3ffB004)
#define GDMASRC1(*(volatile long *)0x3ffC004)
#define GDMADST0(*(volatile long *)0x3ffB008)
#define GDMADST1(*(volatile long *)0x3ffC008)
#define GDMACNT0(*(volatile long *)0x3ffB00C)
#define GDMACNT1(*(volatile long *)0x3ffC00C)
unsigned long data_collum0; // for DMA
void extint_int(void);
static int extint_read(struct file *filp, char *buf, size_t count, loff_t *f_pos);
static int extint_write(struct file *filp, char *buf, size_t count, loff_t *f_pos);
static int extint_ioctl(struct inode *inode, struct file *flip,unsigned int cmd, unsigned longarg);
static int extint_open(struct inode *inode, struct file *flip);
static int extint_release(struct inode *inode, struct file *flip);
void extint_handle(int irq, void *dev_id, struct pt_regs *regs);
struct file_operations extint_fops = {
read: extint_read,
write: extint_write,
ioctl:extint_ioctl,
open:extint_open,
release: extint_release,
};
使用的是2.4kernel,完了编译,分几步,如下:
1.将这两个文件复制到uclinux/linux2.2.x/driver/char下,在当前目录下的mem.c中的int chr_dev_int()函数里面增加
#ifdef CONFIG_EXTINT
extint()
#endif
2.在同目录makefile中增加
ifeq($(CONFIG_EXTINT),y)
obj-y +=extint.o
endif
3.在同目录config.in文件中加
bool 'support for extint' CONFIG_EXTINT y
4.在uclinux/vendors/samsung/4510b/makefile里面增加
extint,c,240,c
说明,分别表示设备名,字符型驱动,主设备号,从设备号
5.make menuconfig,勾上customize kernel setting,退出以后,在后续的菜单中,会有让你选择的步骤,在character devices中把extint勾上
6.最后make如
make dep
make lib_only
make user_only
make romfs
make image
make
7.最终生成image.rom文件在源码images文件夹中
声明:几乎是照抄杜云海前辈的[email protected] 感谢,这个程序以后可以加入 lumit4510 的 uclinux 实验中!
页:
[1]