Linux下CPLD驱动程序

Linux下CPLD驱动程序,第1张

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

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

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;
}
 

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/dianzi/2451962.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-08-04
下一篇 2022-08-04

发表评论

登录后才能评论

评论列表(0条)

保存