动图:
验证杂项驱动,仅保留最基本的读写-10
mytext.c-内核文件
#include<linux/module.h>
#include<asm/io.h> //是因为 ioremap iounmap
#include<linux/fs.h>//register_chrdev unregister_chrdev
#include<linux/device.h>// class_create
#include<linux/uaccess.h>// copy_to_user
#include<linux/kthread.h>//内核线程
#include<linux/delay.h>
#include<linux/miscdevice.h>//杂项设备头文件
char mybuff[100]="helloworld!!";//定义在内核空间数据
int myopen(struct inode * pinode, struct file *pfile)
{
printk(KERN_WARNING "ino=%d\n",pinode->i_ino);
return 0;
}
int myclose(struct inode *pinode, struct file *pfile)
{
return 0;
}
// 第一参数 打开设备文件在内核里对应 file 结构体
ssize_t myread(struct file *pfile, char __user * puserbuf, size_t nbyte, loff_t * ploff)
{//肯定从驱动 内核层拿到数据,送给应用层
//如果从内核空间 拷贝数据给用户空间
copy_to_user(puserbuf,mybuff,nbyte);
return nbyte;
}
ssize_t mywrite(struct file *pfile, const char __user *puserbuf, size_t nbyte, loff_t *ploff)
{//把应用层数据,写入到内核层
copy_from_user(mybuff,puserbuf,nbyte);//应用层把数据写入到底层
return nbyte;
}
//杂项驱动,主设备号固定10,次设备号被动申请
//验证杂项驱动,仅保留最基本的读写
const struct file_operations fops={
.owner=THIS_MODULE,//该结构体 为当前的模块结构体 地址所有拥有
.open=myopen, //fops.open=myopen;
.release=myclose,
.read=myread,
.write=mywrite,
};
//定义一个杂项设备的结构体
struct miscdevice mymisc={
.name="testmisc",
.fops=&fops,
.minor=MISC_DYNAMIC_MINOR
};
int __init myinit()
{
//模块加载时候
misc_register(&mymisc);
return 0;
}
void __exit myexit()
{
misc_deregister(&mymisc);
}
module_init(myinit);
module_exit(myexit);
// 遵循GPL规则
MODULE_LICENSE("GPL");// 公共通用许可证 GNU
myapp.c–应用层文件
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
struct myKey
{
int KeyNum;
int KeyVal;
}appKey;
struct myLed
{
int LedNum;
int LedVal;
}appLed;
char userbuf[50]={0};
int ret=0;
int main()
{
int fd=open("/dev/testmisc",O_RDWR);
if(fd < 0)
{
printf("open fail!!\n");
return -1;
}
while(1)
{
ret=read(fd,userbuf,7);
printf("%d,userbuf=%s\n",ret,userbuf);
sleep(3);
}
close(fd);
return 0;
}