#include <linux/module.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <asm/io.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
#define GLOBAL_MAJOR 0
#define GLOBAL_MAXMEM 0x1000
#define DEV_NAME ("globalmem")
int globalmem_major = GLOBAL_MAJOR;
struct globalmem_dev{
struct cdev cdev;
unsigned char mem[GLOBAL_MAXMEM];
};
struct globalmem_dev *globalmem_devp;
static int globalmem_open(struct inode *inode, struct file *filp)
{
filp->private_data = globalmem_devp;
return 0;
}
static int globalmem_release(struct inode *inode, struct file *filp)
{
return 0;
}
static ssize_t globalmem_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)
{
unsigned long p = *ppos;
unsigned int count = size;
int ret = 0;
struct globalmem_dev *dev = filp->private_data;
if(p >= GLOBAL_MAXMEM)
return 0;
if(count + p > GLOBAL_MAXMEM)
count = GLOBAL_MAXMEM - p;
if(copy_to_user(buf, (void*)dev->mem, count))
{
return -EFAULT;
}
else
{
*ppos += count;
ret = count;
}
return ret;
}
static ssize_t globalmem_write(struct file *filp, const char __user *buf, size_t size, loff_t *ppos)
{
unsigned long p = *ppos;
unsigned int count = size;
int ret = 0;
struct globalmem_dev *dev = filp->private_data;
if(p > GLOBAL_MAXMEM)
return 0;
if(count + p > GLOBAL_MAXMEM)
count = GLOBAL_MAXMEM - p;
if(copy_from_user(dev->mem, buf, count))
{
return -EFAULT;
}
else
{
*ppos += count;
ret = count;
}
return ret;
}
static const struct file_operations globalmem_ops = {
.owner = THIS_MODULE,
.open = globalmem_open,
.read = globalmem_read,
.write = globalmem_write,
.release = globalmem_release,
};
static void globalmem_setup(struct globalmem_dev *dev, int index)
{
int err, devno = MKDEV(globalmem_major, index);
cdev_init(&dev->cdev, &globalmem_ops);
dev->cdev.owner = THIS_MODULE;
err = cdev_add(&dev->cdev, devno, 1);
if(err)
printk(KERN_ERR "### cdev_add fail \n");
}
static int __init globalmem_init(void)
{
int res;
dev_t devno = MKDEV(globalmem_major, 0);
if(globalmem_major)
res = register_chrdev_region(devno, 1, DEV_NAME);
else
{
res = alloc_chrdev_region(&devno, 0, 1, DEV_NAME);
globalmem_major = MAJOR(devno);
}
if(res < 0)
return res;
globalmem_devp = kmalloc(sizeof(struct globalmem_dev), GFP_KERNEL);
if(!globalmem_devp)
{
res = -ENOMEM;
goto fail_malloc;
}
memset(globalmem_devp, 0, sizeof(struct globalmem_dev));
globalmem_setup(globalmem_devp, 0);
return 0;
fail_malloc:
unregister_chrdev_region(devno, 1);
return res;
}
static void __exit globalmem_exit(void)
{
cdev_del(&globalmem_devp->cdev);
kfree(globalmem_devp);
unregister_chrdev_region(MKDEV(globalmem_major, 0), 1);
}
MODULE_LICENSE("GPL");
module_init(globalmem_init);
module_exit(globalmem_exit);
Makefile
obj-m := globalmem_dev.o
globalmem_dev-objs := dev_globalmem.o
KID :=/lib/modules/`uname -r`/build
PWD := ${shell pwd}
defalt:
make -C $(KID) M=${PWD} modules
clean:
rm -rf *.o *.cmd *.ko *.mod.c *.tmp_versions *.order *.symvers .*.*.cmd
分享到:
相关推荐
linux设备驱动学习之-----字符驱动
Linux设备驱动开发详解-第6章字符设备驱动(一)-globalmem[参照].pdf
Linux设备驱动开发详解-第6章字符设备驱动(二)-支持2个globalmem[归纳].pdf
Linux设备驱动程序学习(3)-并发和竞态 - Linux设备驱动程序
这是字符设备驱动的经典程序,globalmem可以实现对设备的读写操作,很有意思,希望大神们多多指教。
本电子稿是我买书时附送的全部电子稿,非常详细,示例代码方便学习。 linuxdriver_code_tool |-- 03 | `-- 2.6内核升级工具 | |-- device-mapper-...| `-- 秒设备驱动与应用程序 | |-- second.c | `-- second_test.c
Linux 设备驱动开发详解 linuxdriver_code_tool |-- 03 | `-- 2.6内核升级工具 | |-- device-mapper-1.00.19-2.i386.rpm | |-- lvm2-2.00.25-1.01.i386.rpm | |-- mkinitrd-4.2.0.3.tar.tar | |-- module-init-tools...
这个文档是我的期末作业,里面有详细的设计说明和完整的代码!包括运行的操作步骤,对于想熟悉字符设备驱动的同学有很大帮助!
linux驱动程序设计的字符设备驱动一章中的例子的源代码
linux虚拟字符设备驱动程序 globalmem虚拟字符设备 不依赖硬件
| | `-- 作为普通字符设备 | | `-- s3c2410-ts.c | |-- 看门狗驱动 | | `-- s3c2410_wdt.c | `-- 平台设备 | `-- devs.c |-- 13 | |-- IDE驱动 | | |-- ide-disk.c | | `-- ide-h8300.c | `-- RAMDISK驱动 | `-- rd....
| | `-- 作为普通字符设备 | | `-- s3c2410-ts.c | |-- 看门狗驱动 | | `-- s3c2410_wdt.c | `-- 平台设备 | `-- devs.c |-- 13 | |-- IDE驱动 | | |-- ide-disk.c | | `-- ide-h8300.c | `-- RAMDISK驱动 | `-- rd....
| | `-- 作为普通字符设备 | | `-- s3c2410-ts.c | |-- 看门狗驱动 | | `-- s3c2410_wdt.c | `-- 平台设备 | `-- devs.c |-- 13 | |-- IDE驱动 | | |-- ide-disk.c | | `-- ide-h8300.c | `-- RAMDISK驱动 | `-- rd....
详细介绍如何写驱动程序 的过程以及相关的步骤,方法,使你更容易入门嵌入式开发
基于Ubuntu16.04 的globalmem驱动测试 。包含驱动文件,makefile,直接可用。 见博客http://blog.csdn.net/qq_33728573/article/details/78802386
globalmme驱动模块源代码,包括Makefile 在Ubuntu10上成功运行
一个简单的字符设备globalmem的驱动程序
含并发控制的globalmem驱动,Linux设备驱动开发
Linux驱动_globalmem实验[参照].pdf
1.驱动中的异步通知当按键按下,内存中有数据等关键事件发生时,可以发送SIGIO信号,应用层需注册该信号的回调函数,当这些关键事件发生时,信号回调函数运行,做后