Linux学习笔记——linux内核字符设备驱动

尝试在树莓派安装的raspbian系统上进行linux字符设备驱动

1.更新安装kernel header源码

sudo apt-get update
sudo apt-get install raspberrypi-kernel-headers

可以使用uname -r查看当前版本

2.编写模块源码mydev1.c

#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

可以看到
在这里插入图片描述

3.编写测试程序源码testchar1.c

#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

Linux学习笔记——linux内核字符设备驱动_第1张图片

你可能感兴趣的:(linux内核,树莓派)