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 ...
随机推荐
- 在spring,mybatis整合配置中走的弯路(1)
在接触一个新东西,总免不了走一些弯路,也正是在这些弯路中,我们不断的成长. 从git上把之前写的代码扒下来,看看我在当初使用spring与mybatis中所走的弯路,路过的君子也可引以为戒. < ...
- Devexpress HtmlEditor 上传本地图片
官方Demo地址:https://demos.devexpress.com/MVCxHTMLEditorDemos/Features/Features 控件的一定要包裹在form中 @using(Ht ...
- 给animator动态添加事件
using UnityEngine; using System.Collections; public class setAnimationEvent : MonoBehaviour { public ...
- 【学】常用hash算法的介绍
基本知识 Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值.这种转换是一种压缩映 ...
- php 碎片笔记
1.修改 php.ini 加载路径 添加环境变量 ,新建系统变量 PHPRC ,配置如下: 检验: 通过phpinfo(),查看系统配置 Loaded Configuration File ,识别系统 ...
- 读书笔记_Effective_C++_条款四十一:了解隐式接口和编译期多态
从本条款开始,就进入了全书的第七部分:模板与泛型编程.模板与泛型在C++中是非常重要的部分,还记得本书第一章时,把C++视为一个联邦,它由四个州政府组成,其中一个政府就是模板与泛型了. 本条款是一个介 ...
- smartjs 0.3 DataManager 发布&介绍
在0.3版加入了DataManager,基于策略的数据管理模块:是SmartJS中比较重要的一个系列.整个个DataManager模块包括有:dataManager,dataPolicyManager ...
- IIS限制ip访问
1.禁止IP访问 http://jingyan.baidu.com/article/22fe7ced0462633002617f39.html 2.限制IP访问频率 http://q.cnblogs. ...
- sqlserver -- 学习笔记(七)获取同组数据的前两条记录
不啰嗦,直接上图,大概实现效果如下: 有上面这样一份数据,将他们按照userAccount和submitTime进行分组,然后提前每组数据的前两条记录 提取后数据如下: 实现的SQL如下: selec ...
- bootstrap插件学习-bootstrap.button.js
先看bootstrap.button.js的结构 var Button = function ( element, options ){} //构造器 Button.prototype = {} // ...