尝试在树莓派安装的raspbian系统上进行linux字符设备驱动
sudo apt-get update
sudo apt-get install raspberrypi-kernel-headers
可以使用uname -r
查看当前版本
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define BUFFER_MAX (10)
#define OK (0)
#define ERROR (-1)
struct cdev *gDev;
struct file_operations *gFile;
dev_t devNum;
unsigned int subDevNum=1;
int reg_major=232;
int reg_minor=0;
char *buffer;
int flag=0;
int testOpen(struct inode *p,struct file *f)
{
printk(KERN_EMERG"testOpen OK\r\n");
return 0;
}
int testWrite(struct file *f,const char __user *u,size_t s,loff_t *l)
{
printk(KERN_EMERG"testWrite OK\r\n");
return 0;
}
int testRead(struct file *f,char __user *u,size_t s,loff_t *l)
{
printk(KERN_EMERG"testRead OK\r\n");
return 0;
}
int charDrvInit(void)
{
devNum=MKDEV(reg_major,reg_minor);
if(OK == register_chrdev_region(devNum,subDevNum,"testchar1"))
{
printk(KERN_EMERG"register_chrdev_region OK\r\n");
}
else
{
printk(KERN_EMERG"register_chrdev_region error\r\n");
return ERROR;
}
printk(KERN_EMERG"devNum is %d\r\n",devNum);
gDev = kzalloc(sizeof(struct cdev),GFP_KERNEL);
gFile = kzalloc(sizeof(struct file_operations),GFP_KERNEL);
gFile->open=testOpen; //当测试程序调用open函数时会进入testOpen
gFile->read=testRead; //当测试程序调用read函数时会进入testRead
gFile->write=testWrite; //当测试程序调用write函数时会进入testWrite
gFile->owner=THIS_MODULE;
cdev_init(gDev,gFile);
cdev_add(gDev,devNum,3);
return 0;
}
void __exit charDrvExit(void)
{
cdev_del(gDev);
unregister_chrdev_region(devNum,subDevNum);
return;
}
module_init(charDrvInit);//insmod **.ko
module_exit(charDrvExit);//rmmod **.ko
MODULE_LICENSE("GPL");
创建编写Makefile文件
sudo vim Makefile
obj-m :=mydev1.o
HEAD :=$(shell uname -r)
KERNEL := /usr/src/linux-headers-$(HEAD)/
all:
make -C $(KERNEL) M=$(shell pwd) modules
clean:
make -C $(KERNEL) M=$(shell pwd) clean
install:
ismod mydev1.ko
unistall:
rmmod mydev1
esc :wq
保存后退出vim
编译内核模块
make
成功后可看到如下文件
清空一下dmesg消息
sudo dmesg -C
加载模块
sudo insmod mydev1.ko
dmesg
#include
#include
#include
#include
#define DATA_NUM (10)
int main(int argc,char *argv[])
{
int fd,i;
int WD,RD;
fd_set fdset;
char buf[DATA_NUM]="111";
memset(buf,0,DATA_NUM); //清空数组buf
fd=open("/dev/testchar1",O_RDWR);
printf("%d\r\n",fd);
if(-1==fd)
{
perror("open file error\r\n");
}
else
{
printf("open successe\r\n");
}
WD=write(fd,buf,DATA_NUM);
RD=read(fd,buf,DATA_NUM);
printf("%d %d\r\n",WD,RD);
printf("%s\r\n",buf);
return 0;
}
编译代码
sudo gcc -o testchar1 testchar1.c
程序中fd=open("/dev/testchar1",O_RDWR); 所以还需建立/dev/testchar1 目录项及索引节点
# c表示为字符设备(b表示块设备) 232为主设备号 0为次设备号
sudo mknod /dev/testchar1 c 232 0
执行测试程序
sudo ./testchar1