平台:MICRO2440
内核:LINUX2.6.32.2
编译器版本:4.4.3
操作系统:Ubuntu10.04
一、驱动程序:
/*********************************
** TIMER0 驱动程序 **
*********************************/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "s3c24xx-adc.h"
#define DEVICE_NAME "timer0_micro2440_drv"
static void __iomem *base_addr;
#define MINI2440_TCFG0 (*(volatile unsigned long *)(base_addr + 0)) //定时器配置寄存器0
#define MINI2440_TCFG1 (*(volatile unsigned long *)(base_addr+4))//定时器配置寄存器1
#define MINI2440_TCON (*(volatile unsigned long *)(base_addr+8))//定时器控制寄存器1
#define MINI2440_TCNTB0 (*(volatile unsigned long *)(base_addr+0x0c))//定时器0计数缓冲寄存器
#define MINI2440_TCMPB0 (*(volatile unsigned long *)(base_addr+0x10))//定时器0比较缓冲寄存器
#define MINI2440_TCNTO0 (*(volatile unsigned long *)(base_addr+0x14))//定时器0计数监视寄存器
#define MINI2440_TCNTB1 (*(volatile unsigned long *)(base_addr+0x18))//定时器1计数缓冲寄存器
#define MINI2440_TCMPB1 (*(volatile unsigned long *)(base_addr+0x1c))//定时器1比较缓冲寄存器
#define MINI2440_TCNTO1 (*(volatile unsigned long *)(base_addr+0x20))//定时器1计数监测寄存器
#define MINI2440_TCNTB2 (*(volatile unsigned long *)(base_addr+0x24))//定时器2计数缓冲寄存器
#define MINI2440_TCMPB2 (*(volatile unsigned long *)(base_addr+0x28))//定时器2比较缓冲寄存器
#define MINI2440_TCNTO2 (*(volatile unsigned long *)(base_addr+0x2c))//定时器2计数监测寄存器
#define MINI2440_TCNTB3 (*(volatile unsigned long *)(base_addr+0x30))//定时器3计数缓冲寄存器
#define MINI2440_TCMPB3 (*(volatile unsigned long *)(base_addr+0x34))//定时器3比较缓冲寄存器
#define MINI2440_TCNTO3 (*(volatile unsigned long *)(base_addr+0x38))//定时器3计数监测寄存器
#define MINI2440_TCNTB4 (*(volatile unsigned long *)(base_addr+0x3c))//定时器4计数缓冲寄存器
#define MINI2440_TCNTO4 (*(volatile unsigned long *)(base_addr+0x40))//定时器4计数监测寄存器
static struct semaphore lock;
typedef struct {
wait_queue_head_t wait;
}ADC_DEV;
static ADC_DEV adcdev;
static volatile int ev_adc = 0;
struct clk *clock;
unsigned long pclk;
static irqreturn_t timer0_interupt_handler(int irq, void *dev_id)
{
ev_adc = 1;
wake_up_interruptible(&adcdev.wait);
return IRQ_HANDLED;
}
static timer0_micro2440_start(void)
{
//struct clk *clk_p;
//unsigned long pclk;
base_addr=ioremap(0x51000000,0x20);
clock = clk_get(NULL, "pclk");//获取PCLK
clk_enable(clock);
pclk = clk_get_rate(clock);
MINI2440_TCFG0=(MINI2440_TCFG0&(~0xff))|249;
MINI2440_TCFG1=0x0001;
MINI2440_TCNTB0=(pclk/250)/4;
MINI2440_TCMPB0=0;
MINI2440_TCON=0x02;//注意在此一定手动更新一下,否则定时器瘫痪
MINI2440_TCON=0x08;
MINI2440_TCON=MINI2440_TCON|0x01;//启动定时器
request_irq(IRQ_TIMER0,timer0_interupt_handler,IRQF_SHARED|IRQF_SAMPLE_RANDOM,DEVICE_NAME,&adcdev);
init_waitqueue_head(&(adcdev.wait));
}
static timer0_micro2440_stop(void)
{
//1.注销中断
free_irq(IRQ_TIMER0,&adcdev);
//2.取消寄存器映射
iounmap(base_addr);
//3.停止ADC时钟
clk_disable(clock);
clk_put(clock);
clock=NULL;
MINI2440_TCON=MINI2440_TCON&(~0x01);//关闭定时器
}
static int timer0_open(struct inode *inode,struct file *file)
{
int ret;
ret=down_trylock(&lock);
if(ret==0)
{
timer0_micro2440_start();
return 0;
}
else
return -EBUSY;
}
static int timer0_close(struct inode *inodep,struct file *file)
{
timer0_micro2440_stop();
up(&lock);//释放互斥锁
return 0;
}
static ssize_t timer0_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
{
char str[10];
long int value;
size_t len;
if(ev_adc==1)
{
value=1;
wait_event_interruptible(adcdev.wait, ev_adc);
ev_adc = 0;
}
else
{
value=0;
}
up(&lock);
len = sprintf(str, "%d\n", value);//将value打印成一个字符串保存在str中
if (count >= len) {
int r = copy_to_user(buffer, str, len);
return r ? r : len;
} else {
return -EINVAL;
}
}
static struct file_operations dev_fops={
.owner=THIS_MODULE,
.open=timer0_open,
.release=timer0_close,
.read=timer0_read,
};
static struct miscdevice misc={
.name=DEVICE_NAME,
.minor=MISC_DYNAMIC_MINOR,
.fops=&dev_fops,
};
static int __init timer0_micro2440_init(void)
{
int ret;
init_MUTEX(&lock);
ret=misc_register(&misc);
return ret;
}
void __exit timer0_micro2440_exit(void)
{
misc_deregister(&misc);
}
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("xubin");
module_init(timer0_micro2440_init);
module_exit(timer0_micro2440_exit);
二、应用程序:
#include
#include
#include
#include
#include
#include
char buffer[50];
unsigned long time_lambda=0;
int main(int argc,char **argv)
{
unsigned long i=1;
unsigned long value=0;
int fd;
fd=open("/dev/timer0_micro2440_drv",O_RDWR);
if(fd<0)
{
printf("error\n");
exit(1);
}
while(1)
{
int len = read(fd, buffer, sizeof buffer -1);
if (len > 0) {
buffer[len] = '\0';
value = 0;
sscanf(buffer, "%d", &value);//将字符串buffer按照整数的形式存在value中
if(value==1)
{
time_lambda++;
printf("timer Value x: %d\n", time_lambda);
}
}
}
close(fd);
return 0;
}
阅读(1693) | 评论(0) | 转发(0) |