QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 2144|回复: 1

一个uclinux s3c4510b 下的外部中断的驱动

[复制链接]
发表于 2005-7-8 15:21:19 | 显示全部楼层 |阅读模式
一直都前一段一直在学这个东西,最后找到杜云海前辈写的一篇文章,照抄了一下,编译通过了,因为原文档是个不允许复制粘贴的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.1  5 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 long  arg)
{
     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 assigned  irq %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.  5  july, 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 *)0x3ffB00

#define GDMADST1  (*(volatile long *)0x3ffC00

#define GDMACNT0  (*(volatile long *)0x3ffB00C)

#define GDMACNT1  (*(volatile long *)0x3ffC00C)





unsigned long data_collum0[320]; // 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 long  arg);
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]
发表于 2005-7-8 23:24:06 | 显示全部楼层
感谢,这个程序以后可以加入 lumit4510 的 uclinux 实验中!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-22 01:02 , Processed in 0.039925 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表