14。字符设备框架介绍与实现openwrt入门经典教程
14。字符设备框架介绍与实现
实验目的
掌握编写一个字符设备驱动程序的框架、必须的步骤
1字符设备驱动程序框架简介
我们在学习C语言的时候,知道每个应用程序的入口函数,即第一个被执行的函数是main函数,那么,我们自己的驱动程序,哪个函数是入口函数呢?
在写驱动程序时,驱动函数的名字可以任意取,常常为xxxxinit(),当实现好这个xxxxinit()函数以后,内核其实并不知道这个就是我们驱动的入口函数,因此我们要想办法告诉内核,我们的入口函数是哪个?我们通过moduleinit()函数来告诉内核,具体如下。
moduleinit(drvinit);
通过上面的修饰以后,drvinit()这个函数就变成了我们的驱动程序的入口函数了。当然,有入口函数,自然还需要一个出口函数,我们通过moduleexit()函数来告诉内核,具体如下。
moduleexit(drvexit);
从上一章中,我们知道,应用程序是通过open、read、write。。。函数来和我们的驱动程序进行交互的,那么我们的驱动程序是怎么给应用程序提供这些接口的呢?我们在写驱动程序的时候,我们首先需要定义出一个fileoperations结构体,该结构体是驱动和应用程序交互的接口。具体定义如下。
structfileoperations{
structmoduleowner;
lofft(llseek)(structfile,lofft,int);ssizet(read)(structfile,charuser,sizet,lofft);ssizet(write)(structfile,constcharuser,sizet,lofft);ssizet(aioread)(structkiocb,conststructiovec,unsignedlong,lofft);
ssizet(aiowrite)(structkiocb,conststructiovec,unsignedlong,lofft);int(readdir)(structfile,void,filldirt);unsignedint(poll)(structfile,structpolltablestruct);
long(unlockedioctl)(structfile,unsignedint,unsignedlong);
long(compatioctl)(structfile,unsignedint,unsignedlong);
int(mmap)(structfile,structvmareastruct);
int(open)(structinode,structfile);
int(flush)(structfile,flownertid);int(release)(structinode,structfile);
int(fsync)(structfile,lofft,lofft,intdatasync);int(aiofsync)(structkiocb,intdatasync);
int(fasync)(int,structfile,int);
int(lock)(structfile,int,structfilelock);ssizet(sendpage)(structfile,structpage,int,sizet,lofft,int);unsignedlong(getunmappedarea)(structfile,unsignedlong,unsignedlong,
unsignedlong,unsignedlong);
int(checkflags)(int);
int(flock)(structfile,int,structfilelock);
ssizet(splicewrite)(structpipeinodeinfo,structfile,lofft,
sizet,unsignedint);
ssizet(spliceread)(structfile,lofft,structpipeinodeinfo,sizet,unsigned
int);
int(setlease)(structfile,long,structfilelock);
long(fallocate)(structfilefile,intmode,lofftoffset,lofftlen);
};
我们的驱动程序要给应用程序提供哪些接口,就只需要填充相应的成员即可。比如我们想提供open、close、read、write、ioctl这三个接口,就应该如下定义。
当fileoperations结构体定义、设置好以后,我们只需要通过registerchrdev()函数将该结构体注册进内核即可。
2字符设备驱动程序框架实现
经过前面部分的讲解,相信大家一定对如何写一个自己的驱动程序,有所感悟了。接下来,给大家一个简单的驱动程序的例子,可以用于作为框架模板,以后的驱动都可以基于该驱动进行修改。
在本实验的附件:字符设备框架程序模板文件夹中就有我们提供的模板,大家可以打开进行阅读,这里也把源码复制出来:
随着后面驱动程序的编写,大家就会熟悉这个模板了,同时熟悉字符设备驱动框架。
驱动程序模板
版本:V1
使用方法(末行模式下):
:sxxx你的驱动名称g
include
include
include
include
include
include
include
include
includeincludeinclude
includeinclude
include
include
includeinclude
includeincludeincludeincludeincludeincludeincludeinclude
基本定义
内核空间缓冲区定义
if0
defineKBMAXSIZE20definekbuf〔KBMAXSIZE〕;
endif
加密函数参数内容:IOW(IOWCHAR,IOWNUMn,IOWTYPE)
加密函数用于xxxioctl函数中
使用举例:ioctl(fd,IOW(L,0x80,long),0x1);
defineNUMnxxx,ifyouneed!
defineIOWCHARL
defineIOWTYPElong
defineIOWNUM10x80
初始化函数必要资源定义
用于初始化函数当中
devicenumber;
devtdevnum;
structdev
structcdevxxxcdev;
automknodedevxxxcdevnumminornum
structclassxxxclassNULL;
structdevicexxxdeviceNULL;
结构体fileoperations成员函数
open
staticintxxxopen(structinodeinode,structfilefile)
{
printk(xxxdriveopen。。。);
return0;
}
close
staticintxxxclose(structinodeinode,structfilefile)
{
printk(xxxdriveclose。。。);
return0;
}
read
staticssizetxxxread(structfilefile,charuserbuffer,
sizetlen,lofftpos)
{
intretv0;
printk(xxxdriveread。。。);
returnretv;
}
write
staticssizetxxxwrite(structfilefile,constcharuserbuffer,
sizetlen,lofftoffset)
{
intretv0;
printk(xxxdrivewrite。。。);
returnretv;
}
unlockedioctl
staticintxxxioctl(structfilefilp,unsignedintcmd,unsignedlongarg)
{
intretv0;
printk(xxxdriveioctl。。。);
switch(cmd)
{
常规:
cmd值自行进行修改
case0x1:
{
if(arg0x1)第二条件;
{
}
}
break;
带密码保护:
请在基本定义进行必要的定义
caseIOW(IOWCHAR,IOWNUM1,IOWTYPE):
{
if(arg0x1)第二条件
{
}
}
break;
default:break;
}
returnretv;
}
结构体:fileoperations
struct
staticconststructfileoperationsxxxfops{
。ownerTHISMODULE,
。openxxxopen,
。releasexxxclose,
。readxxxread,
。writexxxwrite,。unlockedioctlxxxioctl,
};
functions:init,exit
条件值变量,用于指示资源是否正常使用
unsignedcharinitflag0;
unsignedcharaddcodeflag0;
init
staticinitintxxxinit(void)
{
intretv0;
printk(xxxdriveinit。。。);
函数allocchrdevregion主要参数说明:
参数2:次设备号
参数3:创建多少个设备
if((retvallocchrdevregion(devnum,0,1,xxx))0)
{
gotodevregerror;
}
initflag1;标示设备创建成功;
printk(Thedriveinfoofxxx:major:dminor:d,MAJOR(devnum),MINOR(devnum));
cdevinit(xxxcdev,xxxfops);
if((retvcdevadd(xxxcdev,devnum,1))!0)
{
gotocdevadderror;
}
xxxclassclasscreate(THISMODULE,xxx);
if(ISERR(xxxclass))
{
gotoclasscerror;
}
xxxdevicedevicecreate(xxxclass,NULL,devnum,NULL,xxx);
if(ISERR(xxxdevice))
{
gotodevicecerror;
}
printk(automknodsuccess!);
请在此添加您的初始化程序
如果需要做错误处理,请:gotoxxxerror;
addcodeflag1;
END
gotoinitsuccess;
devregerror:
printk(allocchrdevregionfailed);
returnretv;
cdevadderror:
printk(cdevaddfailed);
unregisterchrdevregion(devnum,1);
initflag0;returnretv;
classcerror:
printk(classcreatefailed);
cdevdel(xxxcdev);
unregisterchrdevregion(devnum,1);
initflag0;
returnPTRERR(xxxclass);
devicecerror:
printk(devicecreatefailed);
cdevdel(xxxcdev);
unregisterchrdevregion(devnum,1);
classdestroy(xxxclass);
initflag0;
returnPTRERR(xxxdevice);
请在此添加您的错误处理内容
xxxerror:
addcodeflag0;
return1;
END
initsuccess:
printk(xxxinitsuccess!);
return0;
}
exit
staticexitvoidxxxexit(void)
{
printk(xxxdriveexit。。。);
if(addcodeflag1)
{
请在这里释放您的程序占有的资源
printk(freeyourresources。。。);
printk(freefinish);
END
}
if(initflag1)
{
释放初始化使用到的资源;
cdevdel(xxxcdev);
unregisterchrdevregion(devnum,1);
deviceunregister(xxxdevice);
classdestroy(xxxclass);
}
}
moduleoperations
moduleloadingmoduleinit(xxxinit);moduleexit(xxxexit);
someinfomation
MODULELICENSE(GPLv2);
MODULEAUTHOR(fromJafy);MODULEDESCRIPTION(xxxdrive);
TheEnd
唐山打人事件最新,法医鉴定最终结果出炉,恐引众怒,能判几年?唐山打人事件最新,法医鉴定最终结果出炉,恐引众怒,能判几年?千呼万唤之下,就算是胡锡进,也只是委婉地提醒了一句。唐山烤肉店殴打妇女事件发生11天后,河北省公安厅首次发布了事故通报。
上将军赋国之荩臣,民之大幸,盖世豪杰,谓上将军细柳旌旗,怯薛骅骝黑甲锋锐,虎贲骠骑。治御万众,如臂指使奋起当先,所向无敌。顺不妄喜,逆不惶馁安不奢逸,危不惊惧。坚毅如钢,百战淬火。纵横天下,无坚不摧。胸有惊雷,面如平湖运筹帷幄
教育黑板报丨一周教育信创热点关注(06。06本周最热以推进信息技术应用为抓手!教育部党组人民日报撰文筑牢教育强国建设之基6月9日,教育部党组在人民日报刊发文章筑牢教育强国建设之基。文章指出,以推进信息技术应用为抓手,进一步推
高陵区首批西安菜园子农产品区域公用品牌包装箱免费发放视频加载中近日,首批由西安市高陵区农业农村和林业局印制的西安菜园子农产品区域公用品牌系列农产品包装箱免费向已授权的10家优质名特优果蔬生产销售的农业经营主体发放,本次发放的特色农产
女子发现大家都不坐长椅,好奇地她坐了上去,顿时被烫到跳起来在夏天,有时接触到刚刚经历过暴晒的沙子石材等等,往往会感觉到发烫,相信大家或多或少都有类似的经历。这也成为很多人夏天难以忘怀的记忆。不过,很多时候,这些物体表面的温度是很难用肉眼看
张哲张翼张熙张敏张哲(13351420年),字子玄,秦州西关(今甘肃天水秦州区西关)人。明洪武五年(1372年)中举入仕,授户部主事,擢升员外郎。张哲为官清正,处事无忤,同朝融融。父卒丁忧,产业丰
墨菲如果埃里克森和B费搭档中场,曼联在下赛季的表现会更糟糕直播吧6月21日讯近日,前英格兰国脚丹尼墨菲接受了TalkSport的采访,在采访中他表示并不认为埃里克森是适合曼联的选择。墨菲表示,如果曼联签下埃里克森,并让他和B费搭档中场,那
皮肤瘙痒可能存在的原因?皮肤瘙痒患者要明确病因,可能是天气干燥等生理因素引起,也可能是湿疹体癣接触性皮炎荨麻疹等疾病引起,可以通过一般治疗药物治疗等方式止痒。1。生理因素由于天气干燥,人体水分流失较多,可
日常搞笑段子1。小时候,我妈不止一次跟我说,亲嘴会怀孕,亲嘴会怀孕,结果我家猫跳起来抢肉吃的时候好死不死亲到了我的嘴,过了几个月它还生下了三只小猫出于责任感,有我一口肉吃,我就不会让那三只小猫
搞笑日常辅导员这个语气是不是生气了搞笑一刻本文有16条内容,预计阅读时长3分钟,望能博君一笑,笑口常开好彩自然来老师这个语气,是不是生气了是不是应该这个语气,老师好的呢猪猪,路上注意安全,吃饱饱穿暖暖哒,一定要照顾
120万一针抗癌药,上海首位患者治疗成功!一个月肿瘤消失,值吗120万元打一针,就能让癌细胞消失?说起癌症,几乎人人都怕,作为一种致死率高治疗难度大的疾病,癌症在更多时候意味着绝症。伴随着科技的进步,人类对癌症的探索也进入了新的阶段,如今的癌
真正厉害的人,都拥有共赢思维,狠狠提升自己的格局人民日报上写过这样一句话拥抱世界,才能拥抱明天,携手共进,才能行稳致远。单丝不成线,独木不成林。拥有共赢思维的人,往往能走得更远。共赢是一种智慧看过这样一个案例。蜜獾和导蜜鸟都喜欢
穷莫交友,忍者无敌穷莫交友,忍者无敌。说的是一个人在年轻的时候,尤其是穷的时候,就不要交朋友了。这句话好像跟我们日常的认知不太一样。我们日常的认知是说大家出来混,多交点朋友,尤其是你父母,尤其是小县
朝鲜姑娘有多美?看看游客镜头里的朝鲜女性为什么到朝鲜旅行的中年男士都喜欢朝鲜姑娘,下面跟随小编的步伐,看看朝鲜姑娘到底有什么魅力?(此处已添加小程序,请到今日头条客户端查看)图片这位朝鲜女导游,身穿正装制服详细地跟游客讲
环湖徒步鄂州洋澜湖我已用双脚丈量你的波澜壮阔了(下)头号有新人从今天起记录我的2023今天继续踏上我环湖徒步的旅程啦,起点和终点都安排在鄂州凤凰广场的凤凰台,绕着洋澜湖西边的区域一周。今日徒步路线图凤凰台是两层中式古建筑的高台,台中
在旅行攻略上你永远找不到的重庆美食!这下知道了头号有新人重庆,一座带有魔幻色彩的二线城市。真正的美食隐藏在重庆城的咔咔角角,没有记录,没有地图,全凭重庆老餮们的口口相传。这就是重庆城,高冷的CBD被一大群低矮的民房包围着。民房
武当悟道之旅武当山,道教四大名山。位于湖北省十堰市丹江口境内,河南湖北交界。古称太岳,因非玄武不足以当之得名,在道教属武当派。因周五上班,傍晚18点从单位出发,全程465公里,导航预计5小时1
(社会)哈尔滨冰雪大世界魅力冰雕引客来哈尔滨冰雪大世界举办的玉兔迎春冰雕艺术创作比赛1月7日正式闭幕。本次冰雕艺术比赛共有12组专业冰雕团队参赛,冰雕师们展示出高超的冰雕技艺,吸引来自全国各地的游客观赏。1月5日,游客
大唐荔乡浮山胜景吴子任清晨,我们从高州市区驱车,往东南方向行驶,往大唐荔乡根子镇浮山岭进发。一路上翻山过村,每一处都是一座深厚的历史宝藏。浮山岭顶峰海拔966米。因顶上五个小山峰极似人的手掌,故又
磐安出发自驾3日游好去处攻略推荐小编全家自驾游去浙江省磐安县旅游,那里山清水秀,风景如画,让小编流连忘返。旅行是一种追寻,尽可能地去更多的地方,寻找不一样的新鲜与感动旅行是一种分享。下面跟随小编一起去看看吧!春风
旅行博主房琪为了事业放弃50万年薪,4年游遍300个城市,值得吗?在社交平台上,有一位旅行博主,她叫房琪,今年30岁。房琪4年时间去了近300个城市,她到过的地方,有天上更有人间的普者黑险奇美秀的玉龙雪山美丽乡村江西婺源江南水乡扬州。她也到过繁华
满满烟火气多地消费复苏年味渐浓还有不到十天,就到小年了。在祖国各地,在渐浓的年味里,蕴含着日渐复苏的活力。浙江春节临近各地特色美食登场在浙江余杭区百丈镇半山村,一到过年,村民们就会制作黄金鱼圆,寓意富裕团圆。趁