在文章
https://blog.csdn.net/weixin_40933496/article/details/140830422?spm=1001.2014.3001.5502
的基础上,通过class_create 及device_create实现自动创建节点
#include "asm/uaccess.h"
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/mman.h>
#include <linux/random.h>
#include <linux/init.h>
#include <linux/raw.h>
#include <linux/tty.h>
#include <linux/capability.h>
#include <linux/ptrace.h>
#include <linux/device.h>
#include <linux/highmem.h>
#include <linux/backing-dev.h>
#include <linux/shmem_fs.h>
#include <linux/splice.h>
#include <linux/pfn.h>
#include <linux/export.h>
#include <linux/io.h>
#include <linux/uio.h>
#include <linux/uaccess.h>
#include <asm/uaccess.h>
static int major;
static unsigned char hello_buf[100];
static struct class *hello_class;
static int hello_open (struct inode *node, struct file *filp)
{
printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
return 0;
}
static ssize_t hello_read (struct file *filp, char __user *buf, size_t size, loff_t *offset)
{
int alen;
unsigned long len = size > 100 ? 100 : size;
printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
alen = copy_to_user(buf, hello_buf, len);
printk("%s read %s\n",__FUNCTION__,hello_buf);
return len;
}
static ssize_t hello_write(struct file *filp, const char __user *buf, size_t size, loff_t *offset)
{
int alen;
unsigned long len = size > 100 ? 100 : size;
printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
alen = copy_from_user(hello_buf, buf, len);
printk("%s write %s\n",__FUNCTION__,hello_buf);
return len;
}
static int hello_release (struct inode *node, struct file *filp)
{
printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
return 0;
}
/* 1. create file_operations */
static const struct file_operations hello_drv = {
.owner = THIS_MODULE,
.read = hello_read,
.write = hello_write,
.open = hello_open,
.release = hello_release,
};
/* 2. register_chrdev */
/* 3. entry function */
static int hello_init(void)
{
major = register_chrdev(0, "100ask_hello", &hello_drv);
hello_class = class_create(THIS_MODULE,"hello_class");
if(IS_ERR(hello_class)) {
pr_err("failed to allocate class\n");
return PTR_ERR(hello_class);
}
//create device /dev/hello
device_create(hello_class, NULL, MKDEV(major, 0), NULL, "hello");
return 0;
}
/* 4. exit function */
static void hello_exit(void)
{
device_destroy(hello_class, MKDEV(major, 0));
class_destroy(hello_class);
unregister_chrdev(major, "100ask_hello");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
/* 写: ./hello_test /dev/xxx 100ask
* 读: ./hello_test /dev/xxx
*/
int main(int argc, char **argv)
{
int fd;
int len;
char buf[100];
if (argc < 2)
{
printf("Usage: \n");
printf("%s <dev> [string]\n", argv[0]);
return -1;
}
// open
fd = open(argv[1], O_RDWR);
if (fd < 0)
{
printf("can not open file %s\n", argv[1]);
return -1;
}
if (argc == 3)
{
// write
len = write(fd, argv[2], strlen(argv[2])+1);
printf("APP write ret = %d\n", len);
}
else
{
// read
len = read(fd, buf, 100);
buf[99] = '\0';
printf("APP read str : %s\n", buf);
}
// close
close(fd);
return 0;
}
KERN_DIR = /home/book/100ask_imx6ull-sdk/Linux-4.9.88
all:
make -C $(KERN_DIR) M=`pwd` modules
$(CROSS_COMPILE)gcc -o hello_test hello_test.c
clean:
make -C $(KERN_DIR) M=`pwd` modules clean
rm -rf modules.order
rm -f hello_test
obj-m += hello_drv.o