驱动专题:源码编写 0 简单字符设备驱动及测试程序

汇总地址:https://blog.csdn.net/chichi123137/article/details/80946381

简单字符设备驱动程序

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <linux/device.h>
#include <linux/gpio.h>

#define DEVICE_NAME	"mydriver"	
static int MYDRIVER_Major = 0;

static int mydriver_open(struct inode *inode, struct file *file)
{
	printk("My Driver Open Called!\n");
	return 0;
}

static int mydriver_release(struct inode *inode, struct file *file)
{
	printk("My Driver Release Called!\n");
	return 0;
}

static int mydriver_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
{
	printk("My Driver Read Called!\n");
	return 0;
}

static int mydriver_write(struct file *filp, char *buf, size_t count, loff_t *f_pos)
{
	printk("My Driver Write Called!\n");
	return 0;
}

static int mydriver_ioctl( struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{

}

static struct file_operations mydriver_fops =
{
	.owner  =   THIS_MODULE,
	.open   =   mydriver_open, 
	.release =  mydriver_release,
	.read   =   mydriver_read,
	.write  =   mydriver_write,
	.ioctl  =   mydriver_ioctl,
};

static struct class *mydriver_class;

static int __init mydriver_init(void)
{

	printk("MY DRIVER MODULE INIT\n");

	MYDRIVER_Major = register_chrdev(0, DEVICE_NAME, &mydriver_fops);
	if (MYDRIVER_Major < 0)
	{
		printk(DEVICE_NAME " can't register major number\n");
		return MYDRIVER_Major;
	}
	printk("register My Driver OK! Major = %d\n", MYDRIVER_Major);

	//注册一个类,使mdev可以在"/dev/"目录下面建立设备节点
	mydriver_class = class_create(THIS_MODULE, DEVICE_NAME);
	if(IS_ERR(mydriver_class))
	{
		printk("Err: failed in My Driver class. \n");
		return -1;
	}
	//创建一个设备节点,节点名为DEVICE_NAME
	device_create(mydriver_class, NULL, MKDEV(MYDRIVER_Major, 0), NULL, DEVICE_NAME);

	printk(DEVICE_NAME " initialized\n");
	return 0;
}

static void __exit mydriver_exit(void)
{
	printk("MY DRIVER MODULE EXIT\n");
	unregister_chrdev(MYDRIVER_Major, DEVICE_NAME);
	device_destroy(mydriver_class, MKDEV(MYDRIVER_Major, 0));
	class_destroy(mydriver_class);
}

module_init(mydriver_init);
module_exit(mydriver_exit);

MODULE_AUTHOR("www.txmcu.com");		
MODULE_DESCRIPTION("My Driver");	
MODULE_LICENSE("GPL");

测试程序

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>

int main(int argc, char **argv)
{
	int fd;
	fd = open("/dev/mydriver", 0);
	if (fd < 0)
	{
		perror("open device");
		exit(1);
	}

	/*your code*/

	close(fd);
	return 0;
}

Makefile:

KERN_DIR = /home/linux/tools/linux-2.6.31

all:
	make -C $(KERN_DIR) M=`pwd` modules 

clean:
	make -C $(KERN_DIR) M=`pwd` modules clean
	rm -rf modules.order

obj-m	+= driver_module.o

目录结构如下:

测试步骤:

1 在menuconfig中配置好内核源码的目标系统为s3c2440,在makefile中配置好交叉编译器为arm-linux-

2 在pc上将驱动程序编译生成.ko,命令:make

3 在pc上将测试程序编译生成elf可执行文件,命令:arm-linux-gcc -o driver_test driver_test.c

4 挂载nfs,这样就可以在开发板上看到pc端的.ko文件和测试文件

mount -t nfs -o nolock,vers=2 192.168.0.103:/home/linux/nfs_root  /mnt

执行结果如下:

insmod driver_module.ko

lsmod

dmesg

rmmod driver_module 卸载模块

猜你喜欢

转载自blog.csdn.net/chichi123137/article/details/82453295