功能是使用内存的4k单元,实现读,写,偏移,清除。
  1. /*********************************************************************************
  2. * Copyright: (C) 2014 zhouguangfeng<zhouguangfeng91@gmail.com>
  3. + plat_globalfifo.c
  4. /*********************************************************************************
  5. * Copyright: (C) 2014 zhouguangfeng<zhouguangfeng91@gmail.com>
  6. * All rights reserved.
  7. *
  8. * Filename: plat_globalfifo.c
  9. * Description: This file is a commom platform driver
  10. *
  11. * Version: 1.0.0(08/19/2014)
  12. * Author: zhouguangfeng <zhouguangfeng91@gmail.com>
  13. * ChangeLog: 1, Release initial version on "08/19/2014 02:31:17 PM"
  14. *
  15. ********************************************************************************/
  16. #include <linux/fs.h>//struct file_operations
  17. #include <linux/types.h>//special type definition,like dev_t off_t defined by typedef
  18. #include <linux/init.h> // init and exit
  19. #include <linux/module.h>//support module load and unload
  20. #include <linux/errno.h>
  21. #include <linux/mm.h> //memory mannage ,include kmalloc.kfree and so on
  22. #include <linux/sched.h>
  23. #include <linux/cdev.h> //char device structure definition
  24. #include <asm/io.h> //io operation function ,like ioremap,iowrite
  25. #include <asm/system.h>
  26. #include <asm/ioctl.h> //for ioctl command
  27. #include <asm/uaccess.h>
  28. #include <linux/platform_device.h> //platform support
  29. #include <linux/kernel.h>
  30. #include <linux/device.h> //class_create() and device_create()
  31.  
  32. #define GLOBALFIFO_SIZE 0x1000 /* 4K */
  33. #define NAME "globalfifo"
  34. #define KELNEL_OLD 0 /* decsion ioctl() */
  35.  
  36. #ifndef GLOBALFIFO_MAJOR
  37. #define GLOBALFIFO_MAJOR 0
  38. #endif
  39.  
  40. //#define GLOBALFIFO_CLEAR 0x17
  41. //#define MEM_CLEAR __IO (GLOBALFIFO_CLEAR, 0x20)
  42. #define MEM_CLEAR 0x20
  43.  
  44. static int globalfifo_major = GLOBALFIFO_MAJOR;
  45. static int globalfifo_minor = ;
  46.  
  47. /* ============================ Platform Device part =============================== */
  48.  
  49. struct globalfifo_dev
  50. {
  51. struct cdev cdev;
  52. unsigned int current_len;
  53. unsigned char mem[GLOBALFIFO_SIZE];
  54. struct class *class;
  55.  
  56. //struct semaphrore sem;
  57. // wait_queue_t r_wait;
  58. //wait_queue_t r_wait;
  59. } globalfifo_dev;
  60.  
  61. static void plat_release(struct device * dev)
  62. {
  63. return;
  64. }
  65.  
  66. static struct platform_device globalfifo_device = {
  67. .name = "globalfifo",
  68. .id = ,
  69. .dev = {
  70. .release = plat_release,
  71. },
  72. };
  73.  
  74. /* ===================== globalfifo driver part ===========================*/
  75.  
  76. int globalfifo_open(struct inode *inode, struct file *filp)
  77. {
  78. struct globalfifo_dev *dev;
  79.  
  80. dev = container_of(inode->i_cdev, struct globalfifo_dev, cdev);
  81. filp->private_data = dev;
  82.  
  83. return ;
  84. }
  85.  
  86. int globalfifo_release(struct inode *inode, struct file *filp)
  87. {
  88. return ;
  89. }
  90.  
  91. #if KELNEL_OLD
  92. static ssize_t globalfifo_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
  93. {
  94. struct globalfifo_dev *dev = filp->private_data;
  95. switch(cmd)
  96. {
  97. case MEM_CLEAR:
  98. memset(dev->mem, , GLOBALFIFO_SIZE);
  99. printk(KERN_INFO "globalfifo is set to zero\n");
  100. break;
  101.  
  102. default:
  103. return -EINVAL;
  104. }
  105.  
  106. return ;
  107. }
  108. #endif
  109.  
  110. static ssize_t globalfifo_read(struct file *filp, char __user *buf, size_t size, loff_t *opps)
  111. {
  112. unsigned long p = *opps;
  113. unsigned int count = size;
  114. int ret = ;
  115.  
  116. struct globalfifo_dev *dev = filp->private_data;
  117.  
  118. if(p >= GLOBALFIFO_SIZE)
  119. {
  120. return count ? -ENXIO : ;
  121. }
  122. if(count > GLOBALFIFO_SIZE - p)
  123. {
  124. count = GLOBALFIFO_SIZE - p;
  125. }
  126.  
  127. if(copy_to_user(buf, (void *)((dev->mem)+p), count))
  128. {
  129. ret = -EFAULT;
  130. }
  131. else
  132. {
  133. *opps += count;
  134. ret = count;
  135. printk(KERN_INFO"read %u bytes(s) from %lu\n", count, p);
  136. }
  137.  
  138. return ret;
  139. }
  140.  
  141. static ssize_t globalfifo_write(struct file *filp, const char __user *buf, size_t size, loff_t *opps)
  142. {
  143. unsigned long p = *opps;
  144. unsigned int count = size;
  145. int ret;
  146.  
  147. struct globalfifo_dev *dev = filp->private_data;
  148.  
  149. if(p >= GLOBALFIFO_SIZE)
  150. {
  151. return count ? -ENXIO : ;
  152. }
  153.  
  154. if(count > GLOBALFIFO_SIZE - p)
  155. {
  156. count = GLOBALFIFO_SIZE - p;
  157. }
  158.  
  159. if(copy_from_user(((dev->mem)+p), buf, count))
  160. {
  161. ret = -EFAULT;
  162. }
  163. else
  164. {
  165. *opps =+ count;
  166. ret = count;
  167. printk(KERN_INFO "written %u bytes(s) from %lu\n", count, p);
  168. }
  169. return ret;
  170. }
  171.  
  172. #if 1
  173. static loff_t globalfifo_llseek(struct file *filp, loff_t offset, int orig)
  174. {
  175. loff_t ret = ;
  176.  
  177. switch(orig)
  178. {
  179. case :
  180. if(offset < )
  181. {
  182. ret = -EINVAL;
  183. break;
  184. }
  185.  
  186. if((unsigned int )offset > GLOBALFIFO_SIZE)
  187. {
  188. ret = -EINVAL;
  189. break;
  190. }
  191. filp->f_pos = (unsigned int)offset;
  192. ret = filp->f_pos;
  193. break;
  194.  
  195. case :
  196. if((filp->f_pos + offset) > GLOBALFIFO_SIZE)
  197. { ret = -EINVAL;
  198. break;
  199. }
  200.  
  201. if((filp->f_pos + offset) < )
  202. {
  203. ret = -EINVAL;
  204. break;
  205. }
  206. filp->f_pos += offset;
  207. ret = filp->f_pos;
  208. break;
  209.  
  210. default:
  211. ret = -EINVAL;
  212. break;
  213. }
  214.  
  215. return ret;
  216. }
  217. #endif
  218.  
  219. static const struct file_operations globalfifo_fops ={
  220. .owner = THIS_MODULE,
  221. .read = globalfifo_read,
  222. .write = globalfifo_write,
  223. .open = globalfifo_open,
  224. .release = globalfifo_release,
  225. .llseek = globalfifo_llseek,
  226.  
  227. #if KELNEL_OLD
  228. .unlocked_ioctl = globalfifo_ioctl,
  229. #endif
  230. };
  231.  
  232. static int globalfifo_probe(struct platform_device *dev)
  233. {
  234. int ret;
  235. dev_t devno;
  236.  
  237. /* Alloc for device major */
  238. if(globalfifo_major)
  239. {
  240. devno = MKDEV(globalfifo_major, globalfifo_minor);
  241. ret = register_chrdev_region(devno, , NAME);
  242. }
  243. else
  244. {
  245. ret = alloc_chrdev_region(&devno, , , NAME);
  246. globalfifo_major= MAJOR(devno);
  247. }
  248.  
  249. /* Alloc for device major failure */
  250. if (ret < )
  251. {
  252. printk("%s driver can't get major %d\n", NAME, globalfifo_major);
  253. return ret;
  254. }
  255.  
  256. /* Initialize globalfifo structure and register cdev*/
  257. memset(&globalfifo_dev, , sizeof(struct globalfifo_dev));
  258. cdev_init (&(globalfifo_dev.cdev), &globalfifo_fops);
  259. globalfifo_dev.cdev.owner = THIS_MODULE;
  260.  
  261. ret = cdev_add (&(globalfifo_dev.cdev), devno , );
  262. if (ret)
  263. {
  264. printk (KERN_NOTICE "error %d add %s device", ret, NAME);
  265. goto fail_cdev_add;
  266. }
  267.  
  268. globalfifo_dev.class = class_create(THIS_MODULE, NAME);
  269. if(IS_ERR(globalfifo_dev.class))
  270. {
  271. printk("%s driver create class failure\n", NAME);
  272. goto fail_class;
  273. }
  274.  
  275. device_create(globalfifo_dev.class, NULL, devno, NULL, NAME);
  276.  
  277. return ;
  278. fail_class:
  279. cdev_del(&(globalfifo_dev.cdev));
  280.  
  281. fail_cdev_add:
  282. unregister_chrdev_region(devno, );
  283. printk("failure to insmod!\n");
  284. return ret;
  285. }
  286.  
  287. static int globalfifo_remove(struct platform_device *pdev)
  288. {
  289. dev_t devno = MKDEV(globalfifo_major, globalfifo_minor);
  290.  
  291. cdev_del(&globalfifo_dev.cdev);
  292. device_destroy(globalfifo_dev.class, devno);
  293. class_destroy(globalfifo_dev.class);
  294.  
  295. unregister_chrdev_region(devno, );
  296. printk("s3c %s driver removed\n", NAME);
  297.  
  298. return ;
  299. }
  300.  
  301. static struct platform_driver globalfifo_driver = {
  302. .probe = globalfifo_probe,
  303. .remove = globalfifo_remove,
  304. .driver = {
  305. .name = "globalfifo",
  306. .owner = THIS_MODULE,
  307. },
  308. };
  309.  
  310. static int __init globalfifo_init(void)
  311. {
  312. int ret = ;
  313.  
  314. ret = platform_device_register(&globalfifo_device);
  315. if(ret)
  316. {
  317. printk(KERN_ERR "%s:%d: Can't register platform device %d\n", __FUNCTION__, __LINE__ ,ret);
  318. goto fail_reg_plat_dev;
  319. }
  320. printk("Register S3C %s Platform Device successfully.\n", NAME);
  321.  
  322. ret = platform_driver_register(&globalfifo_driver);
  323. if(ret)
  324. {
  325. printk(KERN_ERR "%s:%d: Can't register platform driver %d\n", __FUNCTION__, __LINE__, ret);
  326. goto fail_reg_plat_drv;
  327. }
  328. printk("Register S3C %s Platform Driver successfully.\n", NAME);
  329.  
  330. return ;
  331.  
  332. fail_reg_plat_drv:
  333. platform_device_unregister(&globalfifo_device);
  334. fail_reg_plat_dev:
  335. return ret;
  336. }
  337.  
  338. static void __exit globalfifo_exit(void)
  339. {
  340. printk("%s():%s remove %d platform drvier\n", __FUNCTION__, NAME, __LINE__);
  341. platform_driver_unregister(&globalfifo_driver);
  342.  
  343. printk("%s():%s remove %d platform device\n", __FUNCTION__, NAME, __LINE__);
  344. platform_device_unregister(&globalfifo_device);
  345. }
  346.  
  347. module_init(globalfifo_init);
  348. module_exit(globalfifo_exit);
  349. MODULE_ALIAS("platform: globalfifo");
  350. MODULE_LICENSE("GPL");

Makefile:

  1. #ARCH=x86
  2. ARCH=arm920t
  3. #PROJ=fl2440
  4. PWD=$(shell pwd)
  5.  
  6. ifneq ("${ARCH}", "x86")
  7. CROSS_COMPILE ?= /opt/buildroot-2011.11/${ARCH}/usr/bin/arm-linux-
  8. KERNEL_DIR = ../../kernel/linux-3.8/
  9. else
  10. KERNEL_DIR = /lib/modules/$(shell uname -r)/build
  11. endif
  12.  
  13. obj-m += plat_globalfifo.o
  14.  
  15. all:
  16. make -C $(KERNEL_DIR) SUBDIRS=$(PWD) modules
  17. @make clear
  18.  
  19. clear:
  20. @rm -f *.o *.cmd *.mod.c
  21. @rm -rf *~ core .depend .tmp_versions Module.symvers modules.order -f
  22. @rm -f .*ko.* *ko.* .*.o.cmd
  23.  
  24. clean:
  25. rm -f *.ko *.o
  26. rm -f cscope.* tags

测试程序:

  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #include <fcntl.h>
  5. #include <unistd.h>
  6. #include <sys/ioctl.h>
  7. #include <string.h>
  8.  
  9. #define MEM_CLEAR 0x20
  10. #define MAX 0x1000
  11.  
  12. int main (int argc, char **argv)
  13. {
  14. int fd;
  15. char buf[MAX] = "hello world";
  16. char buf2[MAX];
  17.  
  18. fd = open("/dev/globalfifo", O_RDWR, );
  19. write(fd, buf, sizeof(buf));
  20. lseek(fd, , SEEK_SET);
  21. read(fd, buf2, sizeof(buf2));
  22. printf("buf=%s, buf2=%s\n", buf, buf2);
  23.  
  24. close(fd);
  25. return ;
  26. } /* ----- End of main() ----- */

platform总线globalfifo驱动的更多相关文章

  1. Linux驱动中的platform总线分析

    copy from :https://blog.csdn.net/fml1997/article/details/77622860 概述 从Linux2.6内核起,引入一套新的驱动管理和注册机制:pl ...

  2. 详解Linux2.6内核中基于platform机制的驱动模型 (经典)

    [摘要]本文以Linux 2.6.25 内核为例,分析了基于platform总线的驱动模型.首先介绍了Platform总线的基本概念,接着介绍了platform device和platform dri ...

  3. linux driver ------ platform模型,驱动开发分析

    一.platform总线.设备与驱动 在Linux 2.6 的设备驱动模型中,关心总线.设备和驱动3个实体,总线将设备和驱动绑定.在系统每注册一个设备的时候,会寻找与之匹配的驱动:相反的,在系统每注册 ...

  4. linux设备驱动归纳总结(九):1.platform总线的设备和驱动【转】

    本文转载自:http://blog.chinaunix.net/uid-25014876-id-111745.html linux设备驱动归纳总结(九):1.platform总线的设备和驱动 xxxx ...

  5. platform总线,设备,驱动的注册

    linux设备驱动归纳总结(九):1.platform总线的设备和驱动 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...

  6. platform总线驱动代码分析

    /************************************************************************/ Linux内核版本:2.6.35.7 运行平台:三 ...

  7. fl2440 platform总线button字符设备驱动

    驱动程序: #include "s3c_driver.h" #define DRV_DESC "S3C24XX button driver" /* Driver ...

  8. fl2440 platform总线led字符设备驱动

    首先需要知道的是,设备跟驱动是分开的.设备通过struct device来定义,也可以自己将结构体封装到自己定义的device结构体中: 例如:struct platform_device: 在inc ...

  9. 【Linux开发】linux设备驱动归纳总结(九):1.platform总线的设备和驱动

    linux设备驱动归纳总结(九):1.platform总线的设备和驱动 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...

随机推荐

  1. freemarker springmvc配置异常

    异常信息 java.lang.IllegalAccessError: tried to access method freemarker.ext.servlet.AllHttpScopesHashMo ...

  2. 老鼠跑猫叫主人惊醒c++观察者模式实现

    这个题目算是比较经典的观察者模式了,老鼠作为一个Subject,主动发出跑的动作,紧跟着猫由于老鼠的跑而发出叫声,主人也被惊醒,在这里猫跟主人都是被动的,是观察者角色,代码实现如下: class CS ...

  3. arcgis ERROR:000824 该工具未获得许可

    当时上面还说点击000824进入帮助文档,它说是由于扩展功能未勾选,于是我勾上,结果还是不行,后来它说可能是没有许可,于是我把license重新授权了一遍,结果,还是不行 其实,解决方法是在catal ...

  4. VMware的使用

    1.问题的提出   现在所有的组装台式机,均以64位操作系统作为平台   而且USB接口均以USB3.0默认   windows7 64位和windows 10 64位是主流   那么建立在windo ...

  5. Apache配置多个网站的方法

    Apache的虚拟主机是一种允许在同一台机器上,运行超过一个网站的解决方案.虚拟主机有两种,一种叫基于IP的(IP-based),另一种叫基于名字的(name-based).虚拟主机的存在,对用户来说 ...

  6. VC++之自定义消息

    用户可以自定义消息,在应用程序中主动发出,这种消息一般用于应用程序的某一部分内部处理. 实例说明: 当用户按键盘上的光标上移键时,程序发送用户自定义消息,在对应的消息响应函数中弹出消息对话框,显示消息 ...

  7. 十一、EnterpriseFrameWork框架的分层与系统业务的结合

    上章详细讲了EnterpriseFrameWork框架中的每个分层,这都是从技术层面来说明,也就是我们知道怎么来建一个控制器或一个业务对象,但开发过程中应该建一个什么样的控制器或业务对象了?本章的主要 ...

  8. JAVA和C# 3DES加密解密

    最近 一个项目.net 要调用JAVA的WEB SERVICE,数据采用3DES加密,涉及到两种语言3DES一致性的问题, 下面分享一下, 这里的KEY采用Base64编码,便用分发,因为Java的B ...

  9. [转]Visual Studio技巧之打造拥有自己标识的代码模板

    可能经过很多博客的介绍,大家都知道代码段的使用,使用代码段可以很方便地生成一些常用的代码格式,确实对我们开发很方便.在团队开发中或者在某些情况下我们经常可能还会希望使用Visual Studio生成的 ...

  10. Asp.Net(C#)自动执行计划任务的程序实例分析

    在业务复杂的应用程序中,有时候会要求一个或者多个任务在一定的时间或者一定的时间间隔内计划进行,比如定时备份或同步数据库,定时发送电子邮件等,我们称之为计划任务.实现计划任务的方法也有很多,可以采用SQ ...