功能是使用内存的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. (原)win8下编译GLUT

    1.到opengl官网下载glut源代码 2.修改glutwin32.mak下 # MSVC install directoriesLIBINSTALL     = XXXXX\VC\lib //vs ...

  2. linux上java路径设置

    linux上java路径设置 标签: javalinuxpath 2012-04-30 22:14 1843人阅读 评论(0) 收藏 举报 版权声明:本文为博主原创文章,未经博主允许不得转载. 往/e ...

  3. Qt编写自定义控件插件路过的坑及注意事项

    在一日一控件的口号下,终于写好了五十几个自定义控件,包括各种仪表盘,各种温度计,各种进度条,各种按钮等,具体可参见(http://www.cnblogs.com/feiyangqingyun/p/61 ...

  4. Auto CAD 2013的故障解决方法

    一.问题的提出 Auto CAD 2013在使用过程中出现了错误:“安全系统(软件锁许可管理器) 不起作用或未正确安装.” 二.问题的分析 网络上很多地方转载了这么一个方法: 1) 启动Windows ...

  5. MAC 入门

    1.安装java jdk eclipse 后发现运行不了,原因是JAVA_HOME 没有设置,真操蛋 export JAVA_HOME=`/usr/libexec/java_home` 2.安装bre ...

  6. sql server版本

    10.00.1600 :SQL 2008 10.50.1600:SQL 2008 R2 10.50.2500:SQL 2008 R2 SP1

  7. 未能找到类型或命名空间名称“Coco”(是否缺少 using 指令或程序集引用)

    未能找到类型或命名空间名称"Coco"(是否缺少 using 指令或程序集引用),如果你确实引用了,那说明你引用的和你的项目环境版本不一样,.NET framework的问题,修改 ...

  8. 路由器换大Flash

    使用winhex自建编程器固件(我的是TP-WR941N V6) 1:使用winhex新建一个8M,16M的文件,编辑-全选,填充选块,填充十六进制数值 FF : 2:打开4M的原厂编程器固件(或者自 ...

  9. 自己动手搭建 MongoDB 环境,并建立一个 .NET HelloWorld 程序测试

    关于 MongoDB,下面来自百度百科: MongoDB[1]是一个基于分布式文件存储的数据库.由C++语言编写.旨在为WEB应用提供可扩展的高性能数据存储解决方案.   mongoDB[1] Mon ...

  10. codeforces George and Job

    /* 题意:给一个长度为n的序列, 从中选择长度为m的k个区间(任意两个区间不会有公共部分) 使得所选择的区间的和最大! 思路:这是一种很常见的dp dp[i][j] 表示的是前 i 个数选择 j 个 ...