• «
  • 1
  • 2
  • 3
  • »
  • Pages: 3/3     Go
主题 : linux驱动问题 (TIMER0)定时器 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 64748
精华: 0
发帖: 27
金钱: 135 两
威望: 27 点
贡献值: 0 点
综合积分: 54 分
注册时间: 2012-03-09
最后登录: 2012-10-09
20楼  发表于: 2012-06-20 22:35
不是说,arm只有IO内存,没有IO端口吗?
这里怎么用了outl inl这些操作IO端口的函数啊?
版主。
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
贡献值: 71 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
21楼  发表于: 2012-06-21 16:15

 回 20楼(吻使520) 的帖子

内核中S3C2440部分的代码已经重新定义了outl和inl,参考arch/arm/mach-s3c2410/include/mach/io.h中的定义
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."
级别: 新手上路
UID: 64748
精华: 0
发帖: 27
金钱: 135 两
威望: 27 点
贡献值: 0 点
综合积分: 54 分
注册时间: 2012-03-09
最后登录: 2012-10-09
22楼  发表于: 2012-06-23 13:53

 回 21楼(kasim) 的帖子

明白了。
谢谢版主。
级别: 新手上路
UID: 72525
精华: 0
发帖: 3
金钱: 15 两
威望: 3 点
贡献值: 0 点
综合积分: 6 分
注册时间: 2012-06-23
最后登录: 2013-03-16
23楼  发表于: 2012-07-06 22:05
多谢贴主和版主的问题
级别: 新手上路
UID: 72525
精华: 0
发帖: 3
金钱: 15 两
威望: 3 点
贡献值: 0 点
综合积分: 6 分
注册时间: 2012-06-23
最后登录: 2013-03-16
24楼  发表于: 2012-07-09 10:10
kasim版主
2410 linux timer0驱动中可以实现100us的中断么?我发现总是有问题,是不是中断太快?
问题的表现是中断间隔会越来越慢。
级别: 新手上路
UID: 72525
精华: 0
发帖: 3
金钱: 15 两
威望: 3 点
贡献值: 0 点
综合积分: 6 分
注册时间: 2012-06-23
最后登录: 2013-03-16
25楼  发表于: 2012-07-09 10:30
忘了贴代码

/* timer0.c
* Copyright (C) by Tymanium from china
* this is a device module file used for SBC2410
* it can drive timer0, and in interrupt routine it will inverse GPB0 to generate tooth wave. Surely, it's very easy
*/
/*Usage:
     1. arm-linux-gcc -D__KERNEL__ -I/friendly-arm/kernel/include -DKBUILD_BADENAME=test -DMODULE -c -o timer0.o timer0.c
    2. start your SBC2410 EVBOARD
    3. copy timer0.o to /lib
    4. in your board bash run # insmod /lib/timer0.o ,and now you can inspect GPB0 on your OSC
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/miscdevice.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <linux/spinlock.h>
#include <linux/irq.h>
#include <linux/delay.h>
#include <asm/hardware.h>
//#include "S3C2410SFR.h"

#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/arch/regs-rtc.h>
#include <asm/arch/regs-timer.h>
#include <asm/arch/regs-gpio.h>

#define DEVICE_NAME        "timer0_test"        //
#define IOPORT_MAJOR         200
//#define  Ftclk      1000000  
#define  FCLK   (202.80*1000000)              // Output Frequency        202.80MHz.
#define  HCLK   (FCLK/2)                      // 101.40MHz
#define  PCLK   (FCLK/4)                      // 50.70MHz

#define LED_ON  0
#define LED_OFF 1

#define LED1_PIN S3C2410_GPF4
#define LED2_PIN S3C2410_GPF5
#define LED3_PIN S3C2410_GPF6
#define LED4_PIN S3C2410_GPF7

#define DEVICE_NAME        "timer0_test"        //
#define IOPORT_MAJOR         200
static unsigned int counter;
static unsigned char flag;
static DECLARE_WAIT_QUEUE_HEAD(timer0_wait);

/*timer0 interrupt routine*/
static irqreturn_t timer0_interrupt(int irq , void *dev_id, struct pt_regs *reg)
{
    if(flag != 1)
    {
    s3c2410_gpio_setpin(LED1_PIN,LED_ON);
    //s3c2410_gpio_setpin(LED2_PIN,LED_ON);
    //s3c2410_gpio_setpin(LED3_PIN,LED_ON);
    //s3c2410_gpio_setpin(LED4_PIN,LED_ON);
    flag = 1;        
    }
    else
    {
    s3c2410_gpio_setpin(LED1_PIN,LED_OFF);
    //s3c2410_gpio_setpin(LED2_PIN,LED_OFF);
    //s3c2410_gpio_setpin(LED3_PIN,LED_OFF);
    //s3c2410_gpio_setpin(LED4_PIN,LED_OFF);
    flag = 0;
    }
    return IRQ_HANDLED;
}    

/*this function is called when you use insmod */
static int __init timer0_init(void)
{
    int ret;
    unsigned long Ftclk;
    unsigned int tcfg0,tcfg1,tcon;
    tcfg0 = inl(S3C2410_TCFG0);
        tcfg1 = inl(S3C2410_TCFG1);
        tcon = inl(S3C2410_TCON);
    outl((tcfg0 &= ~0xff) | 49,S3C2410_TCFG0); //设置预分频
        outl((tcfg1 &= ~0xf) | 0,S3C2410_TCFG1);   //设置分频和模式

    Ftclk=50000000/49/2/10000;  //参考datasheet公式
    outl(Ftclk,S3C2410_TCNTB(0));  //写入定时初值
    outl(0,S3C2410_TCMPB(0));  //写入终点比较值

    outl(tcon | S3C2410_TCON_T0MANUALUPD,S3C2410_TCON); //手动刷新一次,将数据装入TCNT和TCMP

    tcon = inl(S3C2410_TCON) & ~S3C2410_TCON_T0MANUALUPD;
    outl(tcon | (S3C2410_TCON_T0START|S3C2410_TCON_T0RELOAD),S3C2410_TCON);

    ret=request_irq(IRQ_TIMER0,&timer0_interrupt,SA_INTERRUPT,DEVICE_NAME,NULL);
    if(ret<0){
        printk("Register IRQ_TIMER0 failed!\n");
        return ret;
    }
    /*配置IO口*/
    s3c2410_gpio_cfgpin(LED1_PIN,S3C2410_GPF4_OUTP);
    s3c2410_gpio_cfgpin(LED2_PIN,S3C2410_GPF5_OUTP);
    s3c2410_gpio_cfgpin(LED3_PIN,S3C2410_GPF6_OUTP);
    s3c2410_gpio_cfgpin(LED4_PIN,S3C2410_GPF7_OUTP);

    /*初始化IO电平*/
    s3c2410_gpio_setpin(LED1_PIN,LED_OFF);
    s3c2410_gpio_setpin(LED2_PIN,LED_OFF);
    s3c2410_gpio_setpin(LED3_PIN,LED_OFF);
    s3c2410_gpio_setpin(LED4_PIN,LED_OFF);
    counter = 0;
    return ret;

}

/*this function is called when you use rmmod*/
static void __exit timer0_cleanup(void)
{
    free_irq(IRQ_TIMER0,NULL);
}

module_init(timer0_init);
module_exit(timer0_cleanup);
MODULE_LICENSE("GPL");
  • «
  • 1
  • 2
  • 3
  • »
  • Pages: 3/3     Go