• 5646阅读
  • 2回复

定时器中断问题 [复制链接]

上一主题 下一主题
离线0354030w
 

只看楼主 正序阅读 楼主  发表于: 2010-05-22
S3C2440步进电机驱动中用定时器0实现1ms延时,现在延时可以实现,输出波形也比较满意,但是问题是定时器中断过大概40m就停止了
超级终端上提示:Disabling IRQ #26 禁止了定时器中断,不知掉怎么回事?纠结蛋疼中!!!!!!!
程序如下
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/fcntl.h>
#include <linux/slab.h>
#include <linux/poll.h>
#include <asm/system.h>
#include <linux/delay.h>
#include <linux/miscdevice.h>
#include <linux/sched.h>
#include <asm/hardware.h>
#include <asm/delay.h>
#include <asm/arch/irqs.h>
#include <asm/arch/s3c2440.h>
#include <asm/arch/regs-gpio.h>
#include <linux/ioport.h>
#include <linux/input.h>
#include <linux/device.h>
#include <asm/io.h>
#include <asm/arch/regs-irq.h>
#include <linux/interrupt.h>
#include <linux/regs-timer.h>

#define DEVICE_NAME "mytimer"
#define CB_MAJOR 250
MODULE_AUTHOR("0354030w");

MODULE_DESCRIPTION("S3C2440 MOTO Driver");

MODULE_LICENSE("GPL");



/*
#define TCON=(*(volatile unsigned int *)0x51000008)
#define TCNTB0=(*(volatile unsigned int *)0x5100000c)
#define TCMPB0=(*(volatile unsigned int *)0x51000010)
#define MPLLCON=(*(volatile unsigned int *)0x4C000004)
#define CLKDIVN= (*(volatile unsigned int *)0x4C000014)
*/
static bool found=0;
static unsigned char m_step[8]={0xef,0xef,0xdf,0xdf,0xbf,0xbf,0x7f,0x7f};
static unsigned int flag=0;
static int flag_1=7;
static unsigned long arg_1,GPFCON,GPFDAT;
static unsigned int cmd_1;
static unsigned long tmp;
void initial_timer(void)
{  
     printk("time init is on!");
  
     unsigned long Ftclk; //s3c2440a的默认Fpclk为50MHz

    
     iowrite32(0,S3C2410_TCFG0); //设置预分频
    
     iowrite32(0,S3C2410_TCFG1);   //设置分频和模式
     Ftclk=12500;  //计数值 实现1ms延时
     iowrite16(Ftclk,S3C2410_TCNTB(0));  //写入定时初值
     iowrite16(0,S3C2410_TCMPB(0));  //写入终点比较值
     tmp=(ioread32(S3C2410_TCON)&(~0x0f))|2;
     iowrite32(tmp,S3C2410_TCON); //手动刷新一次,将数据装入TCNT和TCMP
     tmp=(ioread32(S3C2410_TCON)&(~0x0f))|9;
     iowrite32(tmp,S3C2410_TCON);   //设置自动装载初值,开始计数
    
  
}
//以下几个接口都是空壳
static ssize_t timer_open(struct inode *inode,struct file *file)
{    
     printk("timer_open in!");
     printk("found=%d",found);
     GPFCON=(unsigned long)ioremap(0x56000050,4);
     GPFDAT=(unsigned long)ioremap(0x56000054,4);

     GPFCON |=0x5500;

     return 0;
}


static ssize_t timer_ioctl(struct inode *inode, struct file *file ,unsigned int cmd, unsigned long arg)
{  
    
     found=1;
     cmd_1=cmd;
     arg_1=arg;
        

    return 0;
    
  
}
//发生中断时执行此函数
static void timer_irq(int irq,void *dev_id,struct pt_regs *reg)
{
    
    
   // printk("into the ISR\n");
    if(irq==IRQ_TIMER0)
    {   //printk("time out irq%d",irq);
        if(found==1)
        {
         if(arg_1==1)
          {
             (*(volatile unsigned long *)GPFDAT) =m_step[flag++];
             if(flag>7)flag=0;
          }
          else
          {
             (*(volatile unsigned long *)GPFDAT) =m_step[flag_1--];
              if(flag_1<0)flag_1=7;
          }
        }
        
    }
}

static struct file_operations timer_fops={
    .owner= THIS_MODULE,
    .ioctl =timer_ioctl,  
    .open = timer_open,  
};

//整个驱动的初始化入口
static int __init timer_init(void)
{
    int ret;
    ret=register_chrdev(CB_MAJOR,DEVICE_NAME,&timer_fops);
    
    initial_timer();

    printk("after initial_timer()\n");
    if(ret<0)
    {
        printk(DEVICE_NAME" can't register major number\n");
        return ret;
    }
    //关联中断和中断函数
    if(request_irq(IRQ_TIMER0,(void *)&timer_irq,SA_INTERRUPT,DEVICE_NAME,NULL))
    {
        printk(DEVICE_NAME "can't request irqs\n");
        return -1;
    }
    
    return 0;
}

static void __exit timer_exit(void)
{   found=0;
    free_irq(IRQ_TIMER0,NULL);
    unregister_chrdev(CB_MAJOR, DEVICE_NAME);
}
module_init(timer_init);
module_exit(timer_exit);
希望大家指教!
离线0354030w

只看该作者 2楼 发表于: 2010-06-05
呵呵,就是没写返回值,感谢沙发!
离线conciser
只看该作者 1楼 发表于: 2010-06-01
static irqreturn_t timer_interrupt(void)
{
    printk("Timer0 interrupt occured!\n");
    return IRQ_HANDLED;
}
最后一行要返回return IRQ_HANDLED;
快速回复
限100 字节
 
上一个 下一个