嵌入式linu简单程序_第1页
嵌入式linu简单程序_第2页
嵌入式linu简单程序_第3页
嵌入式linu简单程序_第4页
嵌入式linu简单程序_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、demodemo.c#ifndef_KERNEL_#define_KERNEL_#endif#ifndefMODULE#defineMODULE#endif#includeclinux/config.h>#include<linux/module.h>//模块相关#include<linux/kernel.h>//内核相关#ineludeclinux/fs.h>//file_operations#include<linux/types.h>//ssize_t定义文件#include<linux/init.h>//_init和_exit相关#inelude<linux/errno.h>#inelude<linux/cdev.h>#include<asm/uaccess.h>//copy_to_user()^Dcopy_from_user()在此定义#include<asm/system.h>/*相关宏定义-7#defineDEVICE_NAME"demo11//设备名称#definedemo_MAJOR88〃主设备号#definedemo_MINOR0〃次设备号#defineERROR-1staticintMAX_BUF_LEN=1024;〃数值的最人值staticintWRI_LENGTH=O;厂结构体的定义*/staticintdemo_major=demo_MAJOR;structdemo_dev{structcdevcdev;chardrv_buf[1024];};structdemo_dev*demo_devp;/*demo设备文件打开*/intdemo_open(structinode*inodezstructfile*filp)filp->private_data=demo_devp;sprintf(demo_devp->drv_buf/,deviceopensucess!\n”);printk("deviceopensucess!\nM);return0;}*//*demo设备文件关闭舟/intdemo_release(structinode*inode,structfile*filp)return0;*/厂逆序排列缓冲区数据staticvoiddo_write(char*drv_buf)inti;intlen二WRI_LENGT比chartmp;for(i=0;i<len;i++」en—){tmp=drv_buf[len・l];drv_buf[len-l]=drv_buf[i);drv_buf[i]=tmp;}*/staticssize_tdemo_write(structfile*filp,constchar*buffer,size_tcountjoff_t*ppos){structdemo_dev*dev=filp->private_data;if(count>MAX_BUF_LEN)count=MAX_BUF_LEN;copy_from_user(dev->drv_bufrbuffer,count);WRI_LENGTH=count;printk(Huserwritedatatodriver\nJ;do_write(dev->drv_buf);returncount;}*/staticssize_tdemo_read(structfile*filp,char沐buffer,size_tcount,loff_t*ppos)

structdemo_dev*dev=fiIp->private_data;if(count>MAX_BUF_LEN)count=MAX_BUF_LEN;copy_to_user(bufferzdev->drv_buf,count);printk(Huserreaddatafromdriver\nH);returncount;}4c)tm*/staticintdemojoctl(structinode专node,structfile*file,unsignedintcmd,unsignedlongarg)printk(Mioctlruning'n");switch(cmd){casel:printkf'runingcommand1\n”);break;case2:printkf'runingcommand2\n”);break;default:printk(Herrorcmdnumber\n");break;}return0;}4c)tm*/4c)tm*//*demo的模块加载函数staticconststructfile_operationsdemo_fops={•owner•二THISJVIODULE,read=demo_read,write=demo_write,.ioctl=demo」octl,open二demo_open,release=demo_release,};4c)tm*//*demo的模块加载函数int_initdemo」nit(void)intresult;interr;dev_tdevno=MKDEV(demo_MAJOR,demo_MINOR);if(demo_MAJOR){result=register_chrdev_region(devno"demo”);}else{result二alloc_chrdev_region(&devnoQl「demo");demo_major=MAJOR(devno);}if(result<0){returnresult;}demo_devp=kmalloc(sizeof(structdemo_dev),GFP_KERNEL);if(!demo_devp){printk("空间申请失败\n”);returnERROR;}printk(Hstartdemoinit!\n");cdevjnit(&demo_devp・>cdey&demo_fops);demo_devp->cdev.owner二THIS_MODULE;err=cdev_add(&demo_devp・>cdev,devgl);if(err){printk(“注册设备失败”);unregister_chrdev_region(MKDEV(demo_MAJOR,demo_MINOR)/l);returnerr;}printk(Hdemoinitseccess!\nH);return0;/*demo的模块卸载函数*/void_exitdemo_exit(void)cdev_del(&demo_devp->cdev);kfree(demo_devp);unregister_chrdev_region(MKDEV(demo_MAJOR,demo_MINOR),l);}MODULE_AUTHOR(HLiangBaoqiangM);MODULE_LICENSE「DualBSD/GPLM);module」nit(demo」nit);module_exit(demo_exit);Makefileobj-m+=demo.o#modl-y:=mod_a.oKVERSION=$(shelluname-r)all:make-C/lib/modules/$(KVERSION)/buildM=$(PWD)modulesclean:make-C/lib/modules/$(KVERSION)/buildM=$(PWD)cleanrm-f*.o*.ko*.cmdtest_demo.c#include<stdio.h>#include<stdlib.h>#inelude<fcntl.h>#inelude<unistd.h>#inelude<sys/ioctl.h>voidshowbuf(char*buf);intMAX_LEN=32;intmain(){intfd;inti;charbuf[255];for(i=0;i<MAX_LEN;i++){buf[i]=i;}fd=open(,,/dev/demo,,,O_RDWR);if(fd<0)printf("####DEMOdeviceopenfail####\n");return(-1);

printf(”write%dbytesdatato/dev/demo\nH,MAX_LEN);showbuf(buf);write(fd,buf,MAX_LEN);printfC'Read%dbytesdatafrom/dev/demo\n",MAX_LEN);read(fdzbuf,MAX_LEN);showbuf(buf);ioctl(fdlNULL);ioctl(fdANULL);close(fd);return0;}voidshowbuf(char*buf){inti,j=0;for(i=0;i<MAX_LEN;i++){if(i%4==0)printf("\n%4d:"J++);printf(,,%4d舄buf[i]);printf(Hprintf(H\n2、hello.c#include<linux/init.h>#include<linux/module.h>MODULE_LICENSE「DualBSD/GPLM);staticinthello」nit(void){printk(KERN_ALERT,,Hello,initthemodule!11);return0;}staticvoidhello_exit(void){printk(KERN_ALERT"Goodbye,exitthemodule!11);}module」nit(hello」nit);module_exit(hello_exit);LINUX驱动版本的helloworld终于下决心好好学习LINUX内核和驱动开发了,不怕千万人耻笑,勇敢将自己的学习过程写出来:1、关于目录/lib/modules/2.6.9-42.ELsmp/build/ 这个是内核源码所在的目录一般使用这样的命令进入这个目录:cd/lib/modules/$(uname-r)/build/这个目录实际上指向了:/usr/src/kernels/2.6.9-42.EL-smp-i6862、 编译驱动所使用的makefile实际上编译驱动的时候是使用预先提供的一个makefile的,位置在:/lib/modules/$(uname-r)/build/Makefile注意:M是大写的3、 网上抄录的Linux驱动Helloworld的源码://hello.c#inelude<linux/init.h>#inelude<linux/module.h>MODULE_LICENSE「DualBSD/GPLM);staticinthelloit(void){printk(KERN_ALERT"helloworld!\nH);return0;}staticvoidhello_exit(void){printk(KERN_ALERT”goodbye!\n“);}module」nit(hello」nit);module_exit(hello_exit);4、 写个makefile来编译这个驱动:(版本一,最简单的)#下面这行是文件Makefile的内容,注意M是人写的obj-m:=hello.o把hello.c和Makefile保存在同一目录,然后执行:make-C/lib/modules/'uname-r'/buildSUBDIRS=$PWDmodules这样驱动就编译好了,成果是hello.ko文件。注意:makefile—定要写成Makefile,如果写成makefile就编译不过。(折腾啊,就这一步耗了N多时间)5、 再写另一种Makefile:(版本二:最省事的)#以下是Makefile文件的内容obj-m:=hello.oKERNEL_DIR:=/lib/modules/$(shelluname-r)/buildPWD:=$(shellpwd)all:make-C$(KERNEL_DIR)SUBDIRS=$(PWD)modulesclean:rm*.o*.ko然后执行:make就编译成功了,命令行不再加参数,很省爭。注意:all:和clean:F面的行,前面是一个TAB键6、 加载驱动:执行insmod./hello.ko屏幕上没反应。(因为我是在WINDOWS上用远程终端连上去的嘛)0K,先让时光倒流,回到加载驱动以前,先另开一个窗II,执行:tail・f/var/log/message然后在原来的窗11里执行:insmod./hello.ko哈哈,/var/log/message文件里面看见了盼望已久的helloworld!7、查看驱动:Ismod看见hello这个驱动在其中&卸载驱动:rmmodhello看见/var/log/message里显示了goodbye经过两周的摸索,终于对Linux设备驱动开发有了个初步的认识,下面对Linux设备驱动开发环境的搭建做个小结,以方便自己以后查询,同时也能给同道的初学者一点帮助。刚接触Linux设备驱动时,初学者往往连如何编译驱动程序都不懂,更别说编译进内核或加载测试了。一般都是在网上找个最简单的helloworld驱动程序,然后严格按照网上所说的步骤编译,结呆却得到一大堆见都没见过的错误,更不要说根据错误信息来解决问题了,很多人到这里就不知道如何往下进行了。十几天前我也卡在这里很长时间,现在知道所以然了就记下来,些许对一些同道者有帮助。一个基本的Linux设备驱动开发环境由宿主机和目标机组成,宿主机就是用来做驱动开发工作的主机,目标机就是用来运行和测试设备驱动的主机,在宿主机上需要有开发工具(gcc,gdb,make等)和linux源码(版本要对应目标机上的linux内核),而目标机上只要运行linux即可。由于步骤有所不同,下面分为普通Linux设备驱动开发和嵌入式Linux设别驱动开发两种情况来讲述坏境的搭建和驱动程序的编译:(一)普通Linux设备驱动开发普通Linux主要是区分于嵌入式Linux(一般指uClinux),在这种开发中宿主机和目标机可以是一台主机,即在本机上开发编译然后在本机上加载运行(Linux设备驱动也可以直接编译进内核,但为了开发工作方便,一般采用动态加载的方式),当然也可以是两台主机,如果是两台主机的话,要保证宿主机上的linux源码的版本号与目标机中的linux内核版本一致。普通Linux设备驱动开发的步骤如下:在宿主机上安装开发工具和卞载linux源码(要求版本号和目标机上的linux内核版本一致)。开发工具主要有gcc、gdb、make等,这些工具在redhat或fc中默认就安装了,在debian或Ubuntu中可以通过下面这个命令安装:apt-getinstallbuild-essentiallinux源码可以通过以下几种途径获得:直接去卜•载通过包管理工具下载源码,在debian和Ubuntu中可以通过下面这个命令卞载,apt-getinstalllinux-source-(版本号),F载后的文件在/usr/src目录中,解压到该目录即可将源码解压到/usr/src/目录后,进入linux-source-(版本号)目录中执行下面几个命令:makeoldconfigmakepreparemakescripts编写Linux驱动程序,以一个最简单的hello.c为例,hello.c的内容如卞:#include"linux/init.h"#include"linux/module.h"staticinthello_init(void)printk(KERN_ALERT"HelloWorldlinux_driver_module\n");return0;}staticvoidhello_exit(void){printk(KERN_ALERT"Goodbeylinux_driver_module\nH);}module」nit(hello」nit);module_exit(hello_exit);MODULE_UCENSE(,IGPLM);MODULE_AUTHOR(,Ilpjn);写Makefile文件,一个示例如卞,里面各项参数根据实际情况更改:#sampledrivermoduleobj-m:=hello.oKDIR=/usr/src/linux-source-2.6.24/all:$(MAKE)-C$(KDIR)M=$(PWD).PHONY:cleanclean:rm-f*.mod.c*.mod.o*.ko*.o*.tmp_versions编译,在hello.c和Makefile所在目录下执行make即可,编译后在当前目录生成hello.ko文件加载并测试:加载使用insmod或modprobe命令来实现,如在当前路径执行如下代码:insmodhello.ko或modprobehello注意,如呆在虚拟终端加载内核的话,将看不到内核打印信息,因为内核打印信息不会输出到虚拟终端,而是输出到/proc/kmsg文件中,所以可以通过以下方式查看内核信息:cat/proc/kmsg会一直打印,需要Ctrl—C手动终止dmesg或dmesg|tail-N,N为一数字,表示显示最后N行卸载:使用rmmod命令卸载驱动模块,如rmmodhello(二)嵌入式Linux设备驱动开发这种开发中一般目标机为带有嵌入式处理器的开发板,而宿主机为PC,开发环境需要在宿主机上搭建,嵌入式Linux设备驱动开发的步骤如下:在宿主机上卞载嵌入式Linux的源码,并安装嵌入式Linux开发工具(针对于不同的嵌入式处理器,工具也有所不同,如对应于Arm的arm-gcc系列,针对nios2处理器的nios2-cc系列)编写Linux设备驱动驱动程序,还以上面给出的hello.c为例,将该文件复制到(linux源码目录)/drivers/(目标文件夹)/中在(目标文件夹)中创建Makefile和Kconfig(菜单配置文件),内容分别如下:#makefileobj・$(CONFIG_HELLODRV)+=hello.o#KconfigmenuUSER_DEVICE_DRIVERSconfigHELLODRVtristate"Hello"—help—Thisisasampledriverprogramme.endmenu注意,如果Kconfig文件中的"tristate"写成,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论