模块代码chr_test.c
/**
* To test the chr_dev for AP operation
* by wozon
*
* */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/fs.h>
MODULE_LICENSE ("GPL");
dev_t dev;
struct cdev cdev;
int chr_open(struct inode *i, struct file *f)
{
printk("AP opened!\n");
return 0;
}
int chr_close(struct inode *i, struct file *filp)
{
printk("AP closed!\n");
return 0;
}
struct file_operations chr_fops={
.owner = THIS_MODULE,
.open = chr_open,
.release = chr_close,
};
//模块加载函数
int __init init_module (void)
{
int rst = 0;
dev = MKDEV(249,1); //创建设备节点
rst = register_chrdev_region(dev,1,"shuibian"); //向内核注册设备号
if(rst != 0)
{
rst = -1;
goto exit0;
}
cdev_init(&cdev,&chr_fops);//字符设备驱动控制块初始化
rst = cdev_add(&cdev,dev,1);//向内核添加字符设备驱动控制块
if(rst != 0)
{
rst = -2;
goto exit1;
}
printk("Chr,This module was added by the kernel!\n");
goto exit0;
exit1:
unregister_chrdev_region(dev,1);//注销设备号
exit0:
return rst;
}
//模块卸载函数
void __exit cleanup_module (void)
{
cdev_del(&cdev);//从内核中删除字符设备控制块。
unregister_chrdev_region(dev,1);
printk("This module was removed by the kernel!\n");
}
应用程序代码test.c
/*
* test.c
*/
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ioctl.h>
int main (void)
{
int fd;
fd = open ("/dev/sb13",O_RDWR);
if (fd < 0) {
perror("open");
exit(0);
}
printf ("/dev/chrdev opened, fd=%d\n",fd);
close (fd);
printf ("/dev/chrdev closed!\n");
return 0;
}
Makefile
#To display info during Ccompiling
$(warning KERNELRELEASE=$(KERNELRELEASE))
#To check the KERNELRELEASE enviroment value
ifeq ($(KERNELRELEASE),)
#It's NULL, so to set the enviroment value
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD :=$(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions Module* modules*
.PHONY: modules modules_install clean
#To create obj file
else
obj-m := chr_test.o
endif
先编译模块文件,在终端里面输入make,按下回车
生成chr_test.ko文件。
进入root用户,手动创建设备节点:mknod /dev/ c 249 1
可以看出在/dev/目录下面生成了sb13设备
将chr_test.ko文件加载进内核里面 insmod chr_test.ko
编译test.c文件,生成应用程序
执行应用程序 sudo ./a.out
可以看出,正常访问到了我们刚刚创建的设备节点。
ps:我们这样通过手动方式创建设备节点,然后编辑模块代码,用应用程序来访问,很复杂,尤其是作为别人项目一部分时,就更加不便维护,下一节我们将讲解自动创建设备节点的方法。