您当前的位置:五五电子网电子知识单片机-工控设备源码-程序Linux系统下的CPLD驱动程序 正文
Linux系统下的CPLD驱动程序

Linux系统下的CPLD驱动程序

点击数:7982 次   录入时间:03-04 11:42:55   整理:http://www.55dianzi.com   源码-程序

    ========================================================================== */
/*                                                                            */
/*  Filename.c                                                              */
/*  (c) 2001 Author  Zhang Haibo                                            */
/*                                                                            */
/*  Description  driver program with interrupt and poll                      */
/*                                                                            */
/* ========================================================================== */

    #include <linux/devICe.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/uaCCess.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/cdev.h>
#include <linux/kdev_t.h>
#include <asm/system.h>
#include <linux/poll.h>
#include <linux/IRQ.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <linux/gpio.h>

    static struct class *cpld_class;                  //自动创建设备文件时需要先创建类
static struct class_device *cpld_class_dev;      //再创建驱动
static DECLARE_WAIT_QUEUE_HEAD(eint1_waitq);      //将中断放入等待队列
static struct fasync_struct *eint1_async;        //
static volatile int ev_eint1 = 0;                //中断标志,为1表示中断发生,在中断服务程序里置1
volatile unsigned long *cpld_data = NULL;        //CPLD的物理地址映射的虚拟地址指针  0x08000000
volatile unsigned long *gpfcon = NULL;            //GPF控制寄存器
volatile unsigned long *gpfdat = NULL;            //GPF数据寄存器,0位为使能位

    static irqreturn_t eint1_irq(int irq, void *dev_id) //中断服务程序
{
    ev_eint1 = 1;                                  //中断标志位置1
    *gpfdat &= ~(1<<2);                            //进入中断GPF2清0
    wake_up_interruptible(&eint1_waitq);            //唤醒休眠的进程
    kill_fasync (&eint1_async, SIGIO, POLL_IN);    //产生中断后,驱动向应用程序发送信号     
    return IRQ_RETVAL(IRQ_HANDLED);
}

    static int cpld_drv_open(struct inode *inode, struct file *file)
{
    request_irq(IRQ_EINT1,  eint1_irq, IRQ_TYPE_EDGE_FALLING, "EINT1", 1);//注册中断:中断号,中断程序入口,中断方式,中断名,代号
    return 0;
}
 
static ssize_t cpld_drv_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
{
    int val;
    *gpfdat &=~(1<<0);                //使能位置0,使能CPLD产生PWM,计数器开始计数
    copy_from_user(&val, buf, count); //产生PWM的值从用户空间传入
    iowrite16(val,cpld_data);        //写入CPLD
    return 0;
}
 

 

www.55dianzi.com

     

    statIC unsigned cpld_drv_poll(struct file *file, poll_table *wait)
{
   unsigned int mask = 0;
   poll_wait(file, &eint1_waitq, wait);      //不会立即休眠
   if (ev_eint1)
   mask |= POLLIN | POLLRDNORM;              //若产生中断,mask赋值,表示有数据可读
   return mask;
}
 
static int cpld_drv_fasync (int fd, struct file *filp, int on)
{
 //printk("driver: cpld_drv_fasyncn");
 return fasync_helper (fd, filp, on, &eint1_async);
}

    int cpld_drv_close(struct inode *inode, struct file *file)
{
    free_IRQ(IRQ_EINT1, 1);      //释放中断 
    return 0;
}
 
static struct file_operations cpld_drv_fops = {
    .owner    = THIS_MODULE,                 
    .write    = cpld_drv_write,
    .read    = cpld_drv_read,
    .open    = cpld_drv_open,
    .release  = cpld_drv_close,
    .poll    = cpld_drv_poll,
    .fasync  = cpld_drv_fasync, 
};
 

 


本文关键字:程序  Linux  源码-程序单片机-工控设备 - 源码-程序