日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

globalmem设备代码分析

發(fā)布時間:2025/3/21 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 globalmem设备代码分析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

驅(qū)動程序代碼:

#include<linux/module.h> ?

#include<linux/types.h> ?
#include<linux/fs.h> ?
#include<linux/errno.h> ?
#include<linux/mm.h> ?
#include<linux/sched.h> ?
#include<linux/init.h> ?
#include<linux/cdev.h> ?
#include<linux/slab.h> ? ? ? ? ?
#include<linux/kdev_t.h> ?
#include<linux/device.h> ?
#include <asm/io.h> ?
#include<asm/system.h> ?
#include<asm/uaccess.h> ?
? ?
#define DEVICE_NAME ? "globalmem" ?
#define GLOBALMEM_SIZE ? ? ? ? 0x1000 /*全局內(nèi)存最大4K字節(jié)*/ ?
#define MEM_CLEAR 0x1 /*清0全局內(nèi)存*/ ?
#define GLOBALMEM_MAJOR 241 /*預(yù)設(shè)的globalmem的主設(shè)備號*/ ?
? ?
static int globalmem_major = GLOBALMEM_MAJOR; ?




/*globalmem設(shè)備結(jié)構(gòu)體*/ ?
struct globalmem_dev ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
{ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
struct cdev cdev; /*cdev結(jié)構(gòu)體*/ ? ? ? ? ? ? ? ? ? ? ? ?
unsigned char mem[GLOBALMEM_SIZE];/*全局內(nèi)存*/ ? ? ? ??
}; ?
??
? ?


struct globalmem_dev *globalmem_devp; /*設(shè)備結(jié)構(gòu)體指針*/ ?
? ?
static struct class *globalmem0_class; ?
static struct class *globalmem1_class; ?


? ?


/*文件打開函數(shù)*/ ?
int globalmem_open(struct inode *inode, struct file *filp) ?
{ ?
/*將設(shè)備結(jié)構(gòu)體指針賦值給文件私有數(shù)據(jù)指針*/ ?
struct globalmem_dev *dev; ?


dev = container_of(inode->i_cdev,struct globalmem_dev,cdev); ??
filp->private_data = dev; ??
return 0; ?
} ?










/*文件釋放函數(shù)*/ ?
int globalmem_release(struct inode *inode, struct file *filp) ?
{ ?
return 0; ?
} ?








? ?
/* ioctl設(shè)備控制函數(shù) */ ?
static int globalmem_ioctl(struct inode *inodep, struct file *filp, unsigned ?
? int cmd, unsigned long arg) ?
{ ?
struct globalmem_dev *dev = filp->private_data;/*獲得設(shè)備結(jié)構(gòu)體指針*/ ?
? ?
switch (cmd) ?
{ ?
case MEM_CLEAR: ?
memset(dev->mem, 0, GLOBALMEM_SIZE); ? ? ??
printk(KERN_INFO "globalmem is setto zero\n"); ?
break; ?
? ?
default: ?
return - EINVAL; ?
} ?
return 0; ?
}?






? ?
/*讀函數(shù)*/ ?
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; /*獲得設(shè)備結(jié)構(gòu)體指針*/ ?

/*分析和獲取有效的寫長度*/ ?
if (p >= GLOBALMEM_SIZE) ?
return count ? ?- ENXIO: 0; ?
if (count > GLOBALMEM_SIZE - p) ?
count = GLOBALMEM_SIZE - p; ?

/*內(nèi)核空間->用戶空間*/ ?
if (copy_to_user(buf, (void*)(dev->mem +p), count)) ?
{ ?
ret = - EFAULT; ?
} ?
else ?
{ ?
*ppos += count; ?
ret = count; ?

printk(KERN_INFO "read %d bytes(s)from %d\n", count, p); ?
} ?
return ret; ?
} ?






? ?
/*寫函數(shù)*/ ?
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; /*獲得設(shè)備結(jié)構(gòu)體指針*/ ?

/*分析和獲取有效的寫長度*/ ?
if (p >= GLOBALMEM_SIZE) ?
return count ? ?- ENXIO: 0; ?
if (count > GLOBALMEM_SIZE - p) ?
count = GLOBALMEM_SIZE - p; ?

/*用戶空間->內(nèi)核空間*/ ?
if (copy_from_user(dev->mem + p, buf,count)) ?
ret = - EFAULT; ?
else ?
{ ?
*ppos += count; ?
ret = count; ?
printk(KERN_INFO "written %d bytes(s)from %d\n", count, p); ?
} ?

return ret; ?
} ?
? ?
? ?
? ?
? ?
/* seek文件定位函數(shù) */ ?
static loff_t globalmem_llseek(struct file *filp, loff_t offset, int orig) ?
{ ?
loff_t ret = 0; ?
switch (orig) ?
{ ?
case 0: ?/*相對文件開始位置偏移*/ ?
if (offset < 0) ?
{ ?
ret = - EINVAL; ?
break; ?
} ?
if ((unsigned int)offset >GLOBALMEM_SIZE) ?
{ ?
ret = - EINVAL; ?
break; ?
} ?
filp->f_pos = (unsigned int)offset; ?
ret = filp->f_pos; ?
break; ?


case 1: ?/*相對文件當(dāng)前位置偏移*/ ?
if ((filp->f_pos + offset) >GLOBALMEM_SIZE) ?
{ ?
ret = - EINVAL; ?
break; ?
} ?
if ((filp->f_pos + offset) < 0) ?
{ ?
ret = - EINVAL; ?
break; ?
} ?
filp->f_pos += offset; ?
ret = filp->f_pos; ?
break; ?


default: ?
ret = - EINVAL; ?
break; ?
} ?
return ret; ?
} ?








? ?
/*文件操作結(jié)構(gòu)體*/ ?
static const struct file_operations globalmem_fops = ?
{ ?
.owner = THIS_MODULE, ?
.llseek = globalmem_llseek, ?
.read = globalmem_read, ?
.write = globalmem_write, ?
//.ioctl = globalmem_ioctl,?
.unlocked_ioctl = globalmem_ioctl,
.compat_ioctl = globalmem_ioctl,
.open = globalmem_open, ?
.release = globalmem_release, ?
}; ?
? ?
? ?
? ?
? ?
/*初始化并注冊cdev*/ ?
static void globalmem_setup_cdev(struct globalmem_dev *dev, int index) ?
{ ?
int err, devno = MKDEV(globalmem_major,index); ?

/*
cdev_init(&dev->cdev, &globalmem_fops); ?
dev->cdev.owner = THIS_MODULE; ?
dev->cdev.ops = &globalmem_fops;?
*/


cdev_init(&dev->cdev, &globalmem_fops); ?
dev->cdev.owner = THIS_MODULE; ?


err = cdev_add(&dev->cdev, devno, 1); ?
if (err) ?
printk(KERN_NOTICE "Error %d addingLED%d", err, index); ?
} ?






? ?
/*設(shè)備驅(qū)動模塊加載函數(shù)*/ ?
int globalmem_init(void) ?
{ ?
int result; ?
dev_t devno = MKDEV(globalmem_major, 0); ?

/* 申請設(shè)備號*/ ?
if (globalmem_major) ?
result = register_chrdev_region(devno, 2,DEVICE_NAME); ?
else /* 動態(tài)申請設(shè)備號 */ ?
{ ?
result = alloc_chrdev_region(&devno, 0,2, DEVICE_NAME); ?
globalmem_major = MAJOR(devno); ?
} ??
if (result < 0) ?
return result; ?
? ? ?
/* 動態(tài)申請2個設(shè)備結(jié)構(gòu)體的內(nèi)存*/ ?
globalmem_devp = kmalloc(2*sizeof(struct globalmem_dev), GFP_KERNEL); ?
if (!globalmem_devp) ? ?/*申請失敗*/ ?
{ ?
result = - ENOMEM; ?
goto fail_malloc; ?
} ?
memset(globalmem_devp, 0, 2*sizeof(struct globalmem_dev)); ?


globalmem_setup_cdev(&globalmem_devp[0],0); ?
globalmem_setup_cdev(&globalmem_devp[1],1); ?
? ?
? ? //注冊一個類,使mdev可以在/dev/下面建立設(shè)備節(jié)點 ??
? ? globalmem0_class =class_create(THIS_MODULE, "globalmem0"); ??
? ? if( IS_ERR(globalmem0_class) ) ??
? ? { ??
? ? ? ? printk(KERN_NOTICE, "creatglobalmem0_class failed!"); ??
? ? ? ? return -1; ??
? ? } ??
? ?
? ? //創(chuàng)建一個設(shè)備節(jié)點,節(jié)點名字為globalmem0 ??
? ? device_create(globalmem0_class, NULL,MKDEV(globalmem_major, 0), NULL, "globalmem0"); ??
? ? printk(KERN_NOTICE, "globalmem0initialized!"); ??
? ?
? ? globalmem1_class =class_create(THIS_MODULE, "globalmem1"); ??
? ? if( IS_ERR(globalmem1_class) ) ??
? ? { ??
? ? ? ? printk(KERN_NOTICE, "creatglobalmem1_class failed!"); ??
? ? ? ? return -1; ??
? ? } ??
? ?
? ? //創(chuàng)建一個設(shè)備節(jié)點,節(jié)點名字為globalmem1 ??
? ? device_create(globalmem1_class, NULL,MKDEV(globalmem_major, 1), NULL, "globalmem1"); ??
? ? printk(KERN_NOTICE, "globalmem1initialized!"); ??
? ?
return 0; ?

fail_malloc:?
unregister_chrdev_region(devno,2); ?
return result; ?
} ?






? ?
/*模塊卸載函數(shù)*/ ?
void globalmem_exit(void) ?
{ ?
cdev_del(&(globalmem_devp[0].cdev)); ? ?
cdev_del(&(globalmem_devp[1].cdev)); ? /*注銷cdev*/ ?
kfree(globalmem_devp); ? ? /*釋放設(shè)備結(jié)構(gòu)體內(nèi)存*/ ?
unregister_chrdev_region(MKDEV(globalmem_major, 0), 2); /*釋放設(shè)備號*/ ?
class_destroy(globalmem0_class); ??
class_destroy(globalmem1_class); ??
} ?






? ?
MODULE_AUTHOR("SongBaohua"); ?
MODULE_LICENSE("GPL"); ?
//MODULE_LICENSE("DualBSD/GPL"); ?
? ?
module_param(globalmem_major,int, S_IRUGO); ?
? ?
module_init(globalmem_init); ?

module_exit(globalmem_exit);?







用戶空間測試程序代碼:

#include <stdio.h> ?
#include <stdlib.h> ?
#include <time.h> ?
#include <unistd.h> ?
#include<linux/fcntl.h> ?
? ?
int main() ?
{ ?
int fd; ?
char buf1[]="testglobalmen data!";//寫入memdev設(shè)備的內(nèi)容 ?
char buf_read[4096]; //memdev設(shè)備的內(nèi)容讀入到該buf中 ?

if((fd=open("/dev/globalmem0",O_RDWR))==-1)//打開memdev設(shè)備 ?
{ ?
printf("open globalmem0 WRONG!\n"); ?
return 0; ?
} ?
? ?
int count = 0; ?
while(count<=100) ?
{ ?
printf("openglobalmem0 SUCCESS!\n"); ?
printf("buf is %s\n",buf1); ?
write(fd,buf1,sizeof(buf1));//把buf中的內(nèi)容寫入memdev設(shè)備 ?
lseek(fd,0,SEEK_SET); //把文件指針重新定位到文件開始的位置 ?
read(fd,buf_read,sizeof(buf1));//把memdev設(shè)備中的內(nèi)容讀入到buf_read中 ?
printf("buf_read is %s\n",buf_read); ?
count++; ?
} ?

close(fd); ?
return 0; ?
}?












總結(jié)

以上是生活随笔為你收集整理的globalmem设备代码分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 日韩精品人妻一区二区中文字幕 | 久色网 | 成人性生生活性生交全黄 | 69久久精品无码一区二区 | 雨宫琴音一区二区三区 | 丰满圆润老女人hd | 亚洲性视频在线 | 奇米在线观看 | 久久免费视频3 | 日韩精品一区三区 | 国产精品熟妇人妻g奶一区 a少妇 | 亚洲国产视频网站 | 武侠古典av| 人妖和人妖互交性xxxx视频 | 窝窝午夜影院 | 国产精品无码天天爽视频 | 色呦呦一区二区 | 狠狠干综合网 | 欧美性受xxxx黑人猛交88 | 国产色视频一区二区三区qq号 | 国产男男gay体育生网站 | 四虎永久在线精品 | 最近中文字幕在线观看视频 | 极品少妇网站 | 高清国产午夜精品久久久久久 | 久久精品无码人妻 | 黄色成人小视频 | 久久亚洲精精品中文字幕早川悠里 | 青青草视频观看 | 波多野结衣一二区 | 久久国语对白 | 黄色视屏免费 | 成人国产精品免费观看动漫 | 久久伊人在| 可以看的av网址 | 国产最新视频 | 亚洲国产精品成人无码区 | 嘿咻视频在线观看 | 欧美精品aa| 天天综合一区 | 91天天综合 | 久久久久久久九九九九 | 台湾a级艳片潘金莲 | 成人在线激情 | 亚洲丁香花色 | 欧美 亚洲 另类 激情 另类 | 亚洲の无码国产の无码步美 | 大地资源二中文在线影视免费观看 | 国产高清一二三区 | 在线免费看mv的网站入口 | 欧美嫩交 | 国产福利在线播放 | 五月深爱婷婷 | 欧美丝袜视频 | 国产又粗又黄的视频 | 国产污在线观看 | aaa色| 亚洲视频日韩 | 免费观看一级视频 | 久久久久久久久久一区二区 | 国产精品一区在线观看你懂的 | 天天摸天天舔 | 国产91视频在线 | 成年人在线免费观看视频网站 | 午夜婷婷丁香 | jizz在线看 | 亚洲欧美天堂 | av高潮| 中文乱码人妻一区二区三区视频 | 国产免费播放 | 国产在线综合网 | 无码国产精品一区二区高潮 | 国产女主播视频 | 免费看大片a | 国产又粗又猛又爽又黄的视频一 | 少妇大叫太粗太大爽一区二区 | 99热99在线 | 久久精品视频99 | 五月天婷婷丁香 | 精品国产一区二区三区在线 | 欧美乱码精品一区二区 | 看免费一级片 | 国产片在线播放 | 精品欧美一区二区精品少妇 | 一卡二卡三卡四卡五卡 | 日本爽爽爽爽爽爽在线观看免 | 日韩欧美国产高清 | 日韩在线色 | 日本免费黄网站 | 91原创视频在线观看 | 欧美7777 | 国产91高清 | 久久久精品综合 | www.sesehu.com | 中文字幕有码无码人妻av蜜桃 | 91av视频网站| fc2ppv色の美マンに中出し | 精品国产黄色 | 2018天天弄 |