汇总地址:https://blog.csdn.net/chichi123137/article/details/80946381
简单字符设备驱动程序
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#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
#include
#include
#include
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 卸载模块