millionwood 发表于 2005-7-8 15:21:19

一个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]

limingth 发表于 2005-7-8 23:24:06

感谢,这个程序以后可以加入 lumit4510 的 uclinux 实验中!
页: [1]
查看完整版本: 一个uclinux s3c4510b 下的外部中断的驱动