一個雜項設備,應用層通過write函數傳入一個結構體,把結構體寫入內核

#1雜項設備
##1.1linux下的三大設備
字符設備,塊設備,網絡設備。
字符設備特點:是一個順序的數據流設備,對這種設備的讀寫是按字符進行的,這些字符是連續地形成一個數據流。他不具備緩衝區,對這種設備的讀寫是實時的。
塊設備特點:具有一定結構的隨記存取設備,對這種設備的讀寫是按塊進行的,使用緩衝區來存放暫時的數據,待時機成熟後,從緩存一次性寫入設備或者從設備一次性讀到緩衝區。
網絡設備特點:網絡設備是面向數據包的接收和發送而設計,由系統分配一個唯一的名字(如eth0)。
除網絡設備外,字符設備和塊設備都是通過文件系統的系統調用接口open()、close()、write()、read()等函數可以訪問,應用程序可以通過打開設備文件來訪問該設備。
#雜項設備註冊/註銷函數
| 頭文件 | #include <linux/miscdevice.h>
|函數原型| int misc_register(struct miscdevice * misc);//註冊 int misc_deregister(struct miscdevice *misc); //卸載
| 參數| misc: 雜項設備的指針
|返回值|失敗:小於0

#2雜項設備驅動代碼例子:fops.c

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/uaccess.h>

typedef struct STUDENT
{
char sex;
char name[20];
int num;
}stu;
stu student;
int tiny4412_open(struct inode *node, struct file *fp)
{
printk(“tiny4412 open is called by user space\n”);
return 0;
}
//ubuf是user buf的縮寫
ssize_t tiny4412_read(struct file *fp, char __user *ubuf, size_t size, loff_t *foff)
{
int ret;
ret = copy_to_user(ubuf, &student, sizeof(student));
if(ret != 0){
printk(“copy to user error\n”);
return ret;
}
printk(“tiny4412_read\n”);
return 0;
}

ssize_t tiny4412_write(struct file *fp, const char __user *ubuf, size_t size, loff_t *foff)
{
int ret;
ret = copy_from_user(&student, ubuf, size);
if(ret != 0){
printk(“copy from user error\n”);
return ret;
}
printk(“student.name = %s\n”,student.name);
printk(“student.num = %d\n”,student.num);
printk(“student.sex = %c\n”,student.sex);
return 0;
}

struct file_operations misc_fops={
.owner=THIS_MODULE,
.read = tiny4412_read,
.write = tiny4412_write,
.open = tiny4412_open
};

struct miscdevice my_misc ={
.minor=MISC_DYNAMIC_MINOR,
.fops=&misc_fops,
.name=“biu”
};

static int __init tiny4412_misc_init(void)
{
int ret;
ret=misc_register(&my_misc);
if(ret<0)
{
printk(“misc_register error\n”);
return ret;
}
printk(“misc_register ok\n”);
return 0;
}

static void __exit tiny4412_misc_exit(void)
{

misc_deregister(&my_misc);
printk("tiny4412 misc devices is moved complete\n");

}

module_init(tiny4412_misc_init);
module_exit(tiny4412_misc_exit);
MODULE_LICENSE(“GPL”);


應用程序測試驅動:app.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

typedef struct STUDENT
{
char sex;
char name[20];
int num;
}stu;
stu student2;
int main(int argc, char **argv)
{
int fd;
stu student ={
.sex = ‘m’,
.name = “xiaohong”,
.num = 18117
};

fd = open("/dev/biu", O_RDWR);
if(fd < 0){
	perror("open error:");
	return fd;
}
write(fd, &student, sizeof(stu));
read(fd, &student2, sizeof(stu));
printf("student2.name = %s\n",student2.name);
printf("student2.num = %d\n",student2.num);
printf("student2.sex = %c\n",student2.sex);
close(fd);

return 0;

}


obj-m += fops.o

KERN_DIR=/root/work/tiny4412/linux/linux-3.5
PWD := $(shell pwd)

modules:
$(MAKE) ARCH=arm -C (KERNDIR)M=(KERN_DIR) M=(PWD) modules

clean:
$(MAKE) ARCH=arm -C (KERNDIR)M=(KERN_DIR) M=(PWD) modules clean

開發板測試:
make編譯內核,arm-linux-gcc 編譯app,把生成的.ko和app傳到開發板上。然後insmod fops.ko,執行app

![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20190602211345862.png)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章