当前位置:首页 > 嵌入式 > 嵌入式软件
[导读]Linux下CPLD驱动程序

========================================================================== */
/*                                                                            */
/*   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;
}
 

 

static ssize_t cpld_drv_read(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
{
    int val;
    wait_event_interruptible(eint1_waitq, ev_eint1);  //若无中断产生,即ev_eint1=0,则休眠
    val=ioread16(cpld_data);                          //若中断产生,则从CPLD读取数据,即编码器值
    copy_to_user(buf,&val,count);                     //将读取值传递到用户空间
    ev_eint1 = 0;                                     //中断标志清0
    *gpfdat |= (1<<2);                               //中断读数后,GPF2置1
    return 0;
} [!--empirenews.page--]

 

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

 

int major;
static int cpld_drv_init(void)
{
    major = register_chrdev(0, "cpld_drv", &cpld_drv_fops);                 //注册设备
    cpld_class = class_create(THIS_MODULE, "cplddrv");                      //创建类
    cpld_class_dev = device_create(cpld_class, NULL, MKDEV(major, 0), NULL, "cpld_drv"); //自动创建设备文件 /dev/cpld_drv
    cpld_data = (volatile unsigned long *)ioremap(0x08000000,4);            //映射CPLD物理地址到虚拟地址
    gpfcon = (volatile unsigned long *)ioremap(0x56000050, 8);              //映射GPF寄存器物理地址到虚拟地址
    gpfdat = gpfcon+1;
    *gpfcon &=~((0x3<<0) | (0x3<<(2*2)));
    *gpfcon |=((0x1<<0) | (0x01<<(2*2)));     //设置GPF0、2为输出
    *gpfdat |=0x1;          //将使能位置1,加载驱动时CPLD不输出PWM
    printk("cpld_drv initialized!n");
    return 0;
}
 
static void cpld_drv_exit(void)
{
    *gpfdat |=0x1;          //将使能位置1,卸载驱动后CPLD不输出PWM
    unregister_chrdev(major, "cpld_drv"); //注销驱动
    device_unregister(cpld_class_dev);    //注销设备
    class_destroy(cpld_class);            //注销类
    iounmap(cpld_data);                   //取消映射
    iounmap(gpfcon);
}
 
module_init(cpld_drv_init);
module_exit(cpld_drv_exit);
 
MODULE_LICENSE("GPL");

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

特朗普集团近日取消了其新推出的T1智能手机“将在美国制造”的宣传标语,此举源于外界对这款手机能否以当前定价在美国本土生产的质疑。

关键字: 特朗普 苹果 AI

美国总统特朗普在公开场合表示,他已要求苹果公司CEO蒂姆·库克停止在印度建厂,矛头直指该公司生产多元化的计划。

关键字: 特朗普 苹果 AI

4月10日消息,据媒体报道,美国总统特朗普宣布,美国对部分贸易伙伴暂停90天执行新关税政策,同时对中国的关税提高到125%,该消息公布后苹果股价飙升了15%。这次反弹使苹果市值增加了4000多亿美元,目前苹果市值接近3万...

关键字: 特朗普 AI 人工智能 特斯拉

3月25日消息,据报道,当地时间3月20日,美国总统特朗普在社交媒体平台“真实社交”上发文写道:“那些被抓到破坏特斯拉的人,将有很大可能被判入狱长达20年,这包括资助(破坏特斯拉汽车)者,我们正在寻找你。”

关键字: 特朗普 AI 人工智能 特斯拉

1月22日消息,刚刚,新任美国总统特朗普放出重磅消息,将全力支持美国AI发展。

关键字: 特朗普 AI 人工智能

特朗普先生有两件事一定会载入史册,一个是筑墙,一个是挖坑。在美墨边境筑墙的口号确保边境安全,降低因非法移民引起的犯罪率过高问题;在中美科技产业之间挖坑的口号也是安全,美国企业不得使用对美国国家安全构成威胁的电信设备,总统...

关键字: 特朗普 孤立主义 科技产业

据路透社1月17日消息显示,知情人士透露,特朗普已通知英特尔、铠侠在内的几家华为供应商,将要撤销其对华为的出货的部分许可证,同时将拒绝其他数十个向华为供货的申请。据透露,共有4家公司的8份许可被撤销。另外,相关公司收到撤...

关键字: 华为 芯片 特朗普

曾在2018年时被美国总统特朗普称作“世界第八奇迹”的富士康集团在美国威斯康星州投资建设的LCD显示屏工厂项目,如今却因为富士康将项目大幅缩水并拒绝签订新的合同而陷入了僵局。这也导致富士康无法从当地政府那里获得约40亿美...

关键字: 特朗普 富士康

今年5月,因自己发布的推文被贴上“无确凿依据”标签而与推特发生激烈争执后,美国总统特朗普签署了一项行政令,下令要求重审《通信规范法》第230条。

关键字: 谷歌 facebook 特朗普

众所周知,寄往白宫的所有邮件在到达白宫之前都会在他地进行分类和筛选。9月19日,根据美国相关执法官员的通报,本周早些时候,执法人员截获了一个寄给特朗普总统的包裹,该包裹内包含蓖麻毒蛋白。

关键字: 美国 白宫 特朗普
关闭