字符设备驱动的编写主要就是驱动对应的open close read,是对file_operations结构体成员变量的实现。
linux驱动程序可以编译到内核里面,也就是zImage中,或者编译为.ko的模块,测试的时候只需要加载.ko模块
1.创建工程文件
2.设置.vsocd
3.设置Makefile
4.进行编译生成.ko文件
1.设置为SD卡启动
2.设置bootcmd和bootargs为tftp下载zImage和设备树,以及nfsroot挂载(和之前一样)
3.一些命令
modprobe 模块加载
lsmod 显示模块
rmmod 卸载模块
depmod 第一次使用时需要使用该命令生成modules.dep文件
对于加载和卸载模块进行验证,使用printk函数输出打印,代码如下:
1.字符设备注册
使用:register_chrdev()
2.字符设备注销
使用:unregister_chrdev()
3.设备号设置
3.1linux内核用dev_t(unsigned int)表示。其中高12位为主设备号,低20位位次设备号。
3.2从dev_t获取主设备号和次设备号:MAJOR(dev_t),MINOR(dev_t)
3.3从主设备号和次设备号构成dev_t,通过MKDEV(major,minor)
基础框架来自于file_operations结构体,需要自己写需要的内容。如下:
并且每个成员函数都有自己的方法,如下:
然后编写一个应用程序,对驱动进行调用。
- #include
- #include
- #include
- #include
- #include
-
-
-
- //应用程序参数个数,传入的具体参数内容,格式为字符串
- int main(int argc,char *argv[])
- {
- int ret=0;
- int fd=0;
- char *filename;
- char readbuf[100],writebuf[100];
- filename=argv[1];
- //RDWR具有读写
- fd=open(filename,O_RDWR);
- if(fd<0){
- printf("can't open file %s\r\n",filename);
- return -1;
- }
- /*read*/
- ret= read(fd,readbuf,50);
- if(ret<0){
- printf("read file %s failed \r\n",filename);
- }
- else {
-
- }
-
- /*write*/
- ret=write(fd,writebuf,50);
- if(ret<0){
- printf("write file %s failed\r\n",filename);
- }
- else{
-
- }
- /*close*/
- ret=close(fd);
- if(ret<0){
- printf("close file %s failed \r\n",filename);
- }
-
-
- return 0;
- }
然后进行测试
1.加载驱动
2.进入/dev查看设备文件,创建设备节点: mknod /dev/chrdevbase c 200 0
3.运行
驱动程序完善:应用程序可以对驱动进行读写。例如从驱动中读取数据,向驱动中写入数据
设置:if(atoi(argv[2])==1)//读 if(atoi(argv[2])==2)//写 判断传入的参数