platform总线globalfifo驱动
/*********************************************************************************
* Copyright: (C) 2014 zhouguangfeng<zhouguangfeng91@gmail.com>
+ plat_globalfifo.c
/*********************************************************************************
* Copyright: (C) 2014 zhouguangfeng<zhouguangfeng91@gmail.com>
* All rights reserved.
*
* Filename: plat_globalfifo.c
* Description: This file is a commom platform driver
*
* Version: 1.0.0(08/19/2014)
* Author: zhouguangfeng <zhouguangfeng91@gmail.com>
* ChangeLog: 1, Release initial version on "08/19/2014 02:31:17 PM"
*
********************************************************************************/
#include <linux/fs.h>//struct file_operations
#include <linux/types.h>//special type definition,like dev_t off_t defined by typedef
#include <linux/init.h> // init and exit
#include <linux/module.h>//support module load and unload
#include <linux/errno.h>
#include <linux/mm.h> //memory mannage ,include kmalloc.kfree and so on
#include <linux/sched.h>
#include <linux/cdev.h> //char device structure definition
#include <asm/io.h> //io operation function ,like ioremap,iowrite
#include <asm/system.h>
#include <asm/ioctl.h> //for ioctl command
#include <asm/uaccess.h>
#include <linux/platform_device.h> //platform support
#include <linux/kernel.h>
#include <linux/device.h> //class_create() and device_create() #define GLOBALFIFO_SIZE 0x1000 /* 4K */
#define NAME "globalfifo"
#define KELNEL_OLD 0 /* decsion ioctl() */ #ifndef GLOBALFIFO_MAJOR
#define GLOBALFIFO_MAJOR 0
#endif //#define GLOBALFIFO_CLEAR 0x17
//#define MEM_CLEAR __IO (GLOBALFIFO_CLEAR, 0x20)
#define MEM_CLEAR 0x20 static int globalfifo_major = GLOBALFIFO_MAJOR;
static int globalfifo_minor = ; /* ============================ Platform Device part =============================== */ struct globalfifo_dev
{
struct cdev cdev;
unsigned int current_len;
unsigned char mem[GLOBALFIFO_SIZE];
struct class *class; //struct semaphrore sem;
// wait_queue_t r_wait;
//wait_queue_t r_wait;
} globalfifo_dev; static void plat_release(struct device * dev)
{
return;
} static struct platform_device globalfifo_device = {
.name = "globalfifo",
.id = ,
.dev = {
.release = plat_release,
},
}; /* ===================== globalfifo driver part ===========================*/ int globalfifo_open(struct inode *inode, struct file *filp)
{
struct globalfifo_dev *dev; dev = container_of(inode->i_cdev, struct globalfifo_dev, cdev);
filp->private_data = dev; return ;
} int globalfifo_release(struct inode *inode, struct file *filp)
{
return ;
} #if KELNEL_OLD
static ssize_t globalfifo_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
struct globalfifo_dev *dev = filp->private_data;
switch(cmd)
{
case MEM_CLEAR:
memset(dev->mem, , GLOBALFIFO_SIZE);
printk(KERN_INFO "globalfifo is set to zero\n");
break; default:
return -EINVAL;
} return ;
}
#endif static ssize_t globalfifo_read(struct file *filp, char __user *buf, size_t size, loff_t *opps)
{
unsigned long p = *opps;
unsigned int count = size;
int ret = ; struct globalfifo_dev *dev = filp->private_data; if(p >= GLOBALFIFO_SIZE)
{
return count ? -ENXIO : ;
}
if(count > GLOBALFIFO_SIZE - p)
{
count = GLOBALFIFO_SIZE - p;
} if(copy_to_user(buf, (void *)((dev->mem)+p), count))
{
ret = -EFAULT;
}
else
{
*opps += count;
ret = count;
printk(KERN_INFO"read %u bytes(s) from %lu\n", count, p);
} return ret;
} static ssize_t globalfifo_write(struct file *filp, const char __user *buf, size_t size, loff_t *opps)
{
unsigned long p = *opps;
unsigned int count = size;
int ret; struct globalfifo_dev *dev = filp->private_data; if(p >= GLOBALFIFO_SIZE)
{
return count ? -ENXIO : ;
} if(count > GLOBALFIFO_SIZE - p)
{
count = GLOBALFIFO_SIZE - p;
} if(copy_from_user(((dev->mem)+p), buf, count))
{
ret = -EFAULT;
}
else
{
*opps =+ count;
ret = count;
printk(KERN_INFO "written %u bytes(s) from %lu\n", count, p);
}
return ret;
} #if 1
static loff_t globalfifo_llseek(struct file *filp, loff_t offset, int orig)
{
loff_t ret = ; switch(orig)
{
case :
if(offset < )
{
ret = -EINVAL;
break;
} if((unsigned int )offset > GLOBALFIFO_SIZE)
{
ret = -EINVAL;
break;
}
filp->f_pos = (unsigned int)offset;
ret = filp->f_pos;
break; case :
if((filp->f_pos + offset) > GLOBALFIFO_SIZE)
{ ret = -EINVAL;
break;
} if((filp->f_pos + offset) < )
{
ret = -EINVAL;
break;
}
filp->f_pos += offset;
ret = filp->f_pos;
break; default:
ret = -EINVAL;
break;
} return ret;
}
#endif static const struct file_operations globalfifo_fops ={
.owner = THIS_MODULE,
.read = globalfifo_read,
.write = globalfifo_write,
.open = globalfifo_open,
.release = globalfifo_release,
.llseek = globalfifo_llseek, #if KELNEL_OLD
.unlocked_ioctl = globalfifo_ioctl,
#endif
}; static int globalfifo_probe(struct platform_device *dev)
{
int ret;
dev_t devno; /* Alloc for device major */
if(globalfifo_major)
{
devno = MKDEV(globalfifo_major, globalfifo_minor);
ret = register_chrdev_region(devno, , NAME);
}
else
{
ret = alloc_chrdev_region(&devno, , , NAME);
globalfifo_major= MAJOR(devno);
} /* Alloc for device major failure */
if (ret < )
{
printk("%s driver can't get major %d\n", NAME, globalfifo_major);
return ret;
} /* Initialize globalfifo structure and register cdev*/
memset(&globalfifo_dev, , sizeof(struct globalfifo_dev));
cdev_init (&(globalfifo_dev.cdev), &globalfifo_fops);
globalfifo_dev.cdev.owner = THIS_MODULE; ret = cdev_add (&(globalfifo_dev.cdev), devno , );
if (ret)
{
printk (KERN_NOTICE "error %d add %s device", ret, NAME);
goto fail_cdev_add;
} globalfifo_dev.class = class_create(THIS_MODULE, NAME);
if(IS_ERR(globalfifo_dev.class))
{
printk("%s driver create class failure\n", NAME);
goto fail_class;
} device_create(globalfifo_dev.class, NULL, devno, NULL, NAME); return ;
fail_class:
cdev_del(&(globalfifo_dev.cdev)); fail_cdev_add:
unregister_chrdev_region(devno, );
printk("failure to insmod!\n");
return ret;
} static int globalfifo_remove(struct platform_device *pdev)
{
dev_t devno = MKDEV(globalfifo_major, globalfifo_minor); cdev_del(&globalfifo_dev.cdev);
device_destroy(globalfifo_dev.class, devno);
class_destroy(globalfifo_dev.class); unregister_chrdev_region(devno, );
printk("s3c %s driver removed\n", NAME); return ;
} static struct platform_driver globalfifo_driver = {
.probe = globalfifo_probe,
.remove = globalfifo_remove,
.driver = {
.name = "globalfifo",
.owner = THIS_MODULE,
},
}; static int __init globalfifo_init(void)
{
int ret = ; ret = platform_device_register(&globalfifo_device);
if(ret)
{
printk(KERN_ERR "%s:%d: Can't register platform device %d\n", __FUNCTION__, __LINE__ ,ret);
goto fail_reg_plat_dev;
}
printk("Register S3C %s Platform Device successfully.\n", NAME); ret = platform_driver_register(&globalfifo_driver);
if(ret)
{
printk(KERN_ERR "%s:%d: Can't register platform driver %d\n", __FUNCTION__, __LINE__, ret);
goto fail_reg_plat_drv;
}
printk("Register S3C %s Platform Driver successfully.\n", NAME); return ; fail_reg_plat_drv:
platform_device_unregister(&globalfifo_device);
fail_reg_plat_dev:
return ret;
} static void __exit globalfifo_exit(void)
{
printk("%s():%s remove %d platform drvier\n", __FUNCTION__, NAME, __LINE__);
platform_driver_unregister(&globalfifo_driver); printk("%s():%s remove %d platform device\n", __FUNCTION__, NAME, __LINE__);
platform_device_unregister(&globalfifo_device);
} module_init(globalfifo_init);
module_exit(globalfifo_exit);
MODULE_ALIAS("platform: globalfifo");
MODULE_LICENSE("GPL");
Makefile:
#ARCH=x86
ARCH=arm920t
#PROJ=fl2440
PWD=$(shell pwd) ifneq ("${ARCH}", "x86")
CROSS_COMPILE ?= /opt/buildroot-2011.11/${ARCH}/usr/bin/arm-linux-
KERNEL_DIR = ../../kernel/linux-3.8/
else
KERNEL_DIR = /lib/modules/$(shell uname -r)/build
endif obj-m += plat_globalfifo.o all:
make -C $(KERNEL_DIR) SUBDIRS=$(PWD) modules
@make clear clear:
@rm -f *.o *.cmd *.mod.c
@rm -rf *~ core .depend .tmp_versions Module.symvers modules.order -f
@rm -f .*ko.* *ko.* .*.o.cmd clean:
rm -f *.ko *.o
rm -f cscope.* tags
测试程序:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <string.h> #define MEM_CLEAR 0x20
#define MAX 0x1000 int main (int argc, char **argv)
{
int fd;
char buf[MAX] = "hello world";
char buf2[MAX]; fd = open("/dev/globalfifo", O_RDWR, );
write(fd, buf, sizeof(buf));
lseek(fd, , SEEK_SET);
read(fd, buf2, sizeof(buf2));
printf("buf=%s, buf2=%s\n", buf, buf2); close(fd);
return ;
} /* ----- End of main() ----- */
platform总线globalfifo驱动的更多相关文章
- Linux驱动中的platform总线分析
copy from :https://blog.csdn.net/fml1997/article/details/77622860 概述 从Linux2.6内核起,引入一套新的驱动管理和注册机制:pl ...
- 详解Linux2.6内核中基于platform机制的驱动模型 (经典)
[摘要]本文以Linux 2.6.25 内核为例,分析了基于platform总线的驱动模型.首先介绍了Platform总线的基本概念,接着介绍了platform device和platform dri ...
- linux driver ------ platform模型,驱动开发分析
一.platform总线.设备与驱动 在Linux 2.6 的设备驱动模型中,关心总线.设备和驱动3个实体,总线将设备和驱动绑定.在系统每注册一个设备的时候,会寻找与之匹配的驱动:相反的,在系统每注册 ...
- linux设备驱动归纳总结(九):1.platform总线的设备和驱动【转】
本文转载自:http://blog.chinaunix.net/uid-25014876-id-111745.html linux设备驱动归纳总结(九):1.platform总线的设备和驱动 xxxx ...
- platform总线,设备,驱动的注册
linux设备驱动归纳总结(九):1.platform总线的设备和驱动 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...
- platform总线驱动代码分析
/************************************************************************/ Linux内核版本:2.6.35.7 运行平台:三 ...
- fl2440 platform总线button字符设备驱动
驱动程序: #include "s3c_driver.h" #define DRV_DESC "S3C24XX button driver" /* Driver ...
- fl2440 platform总线led字符设备驱动
首先需要知道的是,设备跟驱动是分开的.设备通过struct device来定义,也可以自己将结构体封装到自己定义的device结构体中: 例如:struct platform_device: 在inc ...
- 【Linux开发】linux设备驱动归纳总结(九):1.platform总线的设备和驱动
linux设备驱动归纳总结(九):1.platform总线的设备和驱动 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...
随机推荐
- XSHELL配色方案及导入配色方案的方法
[ubuntu] text(bold)=ffffff magenta(bold)=ad7fa8 text=ffffff white(bold)=eeeeec green=4e9a06 red(bold ...
- vim中多标签和多窗口的使用
用vim进行编辑的时候常常因为要编辑多个文件或者是编辑一个文件要参考其他文件而烦恼,这里介绍两种方法: 1.多标签 直接在编辑的时候输入: vim -p 要编辑的文件名 如vim -p * 就是编辑当 ...
- JVM内存溢出及合理配置
Tomcat本身不能直接在计算机上运行,需要依赖于硬件基础之上的操作系统和一个Java虚拟机.Tomcat的内存溢出本质就是JVM内存溢出,所以在本文开始时,应该先对Java JVM有关内存方面的知识 ...
- MYSQL 的一些文件及说明
1.MySQL库目录下db.opt文件的作用 http://my.oschina.net/u/1462678/blog/232719 2.复制MySQL数据库A到另外一个MySQL数据库B(仅仅针对i ...
- iOS开发之时间格式的转化
在开发iOS程序时,有时候需要将时间格式调整成自己希望的格式,这个时候我们可以用NSDateFormatter类来处理. 例如:如何将格式为“12-May-14 05.08.02.000000 PM” ...
- ux.form.field.KindEditor 所见所得编辑器
注意需要引入KindEditor相关资源 //所见所得编辑器 Ext.define('ux.form.field.KindEditor', { extend: 'Ext.form.field.Text ...
- MemSQL start[c]up Round 2 - online version C. More Reclamation(博弈)
题目大意 额,写来写去,我还是直接说抽象之后的题目大意吧: 有一个 r*2 的矩形,两个人轮流的在矩形上面减去一个 1*1 的小正方形,要求在减的过程中,不能使矩形“断开”,也就是说,如果一个人减去了 ...
- [转]UML八大误解
潘加宇 本文删节版发表于<程序员>2013年11期 UML(统一建模语言)是软件建模的表示法标准.我从2002年开始专门从事研究和推广UML的工作,在为软件组织提供UML相关需求和设计技能 ...
- 使用GROUP BY统计记录条数 COUNT(*) DISTINCT
例如这样一个表,我想统计email和passwords都不相同的记录的条数 CREATE TABLE IF NOT EXISTS `test_users` ( `email_id` ) unsigne ...
- mysql 启动错误-server PID file could not be found
[root@centos var]# service mysqld stop MySQL manager or server PID file could not be found! [F ...