第一个驱动
学习
register_chrdev
copy_to_user
copy_from_user
chrdevbase.c
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <linux/module.h>
#define CHRDEVBASE_MAJOR 200
#define CHRDEVBASE_NAME "chrdevbase"
static char readbuf[100];
static char writebuf[100];
static char kerneldata[] = "kernel data!";
static int chrdevbase_open(struct inode *inode)
{
printk("chrdevbase open!");
return 0;
}
static ssize_t chrdevbase_read(struct file *filp, char __user *buf, size_t cnt,loff_t *lofft)
{
int retvalue = 0;
retvalue = copy_to_user(buf, readbuf, cnt);
if (retvalue == 0){
printk("kernel senddata ok !\r\n");
}else{
printk("kernel senddata failed !\r\n");
}
return 0;
}
static ssize_t chrdevbase_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offt)
{
int retvalue = 0;
retvalue = copy_from_user(writebuf, buf, cnt);
if (retvalue == 0){
printk("kernel recevdata:%s\r\n", writebuf);
}else{
printk("kernel recvdata failed\r\n");
}
return 0;
}
static int chrdevbase_release(struct inode *inode, struct file *filp)
{
return 0;
}
static struct file_operations chrdevbase_fops = {
.owner = THIS_MODULE,
.open = chrdevbase_open,
.write = chrdevbase_write,
.read = chrdevbase_read,
.release = chrdevbase_release,
};
static int __init chrdevbase_init(void)
{
int retvalue = 0;
retvalue = register_chrdev(CHRDEVBASE_MAJOR, CHRDEVBASE_NAME, &chrdevbase_fops);
if(retvalue < 0)
{
printk("failed");
}
printk("init");
return 0;
}
static void __exit chrdevbase_exit(void)
{
unregister_chrdev(CHRDEVBASE_MAJOR, CHRDEVBASE_NAME);
printk("chrdevbase exit\r\n");
}
module_init(chrdevbase_init);
module_exit(chrdevbase_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("zzk");
chrdevbaseApp.c
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include "sys/stat.h"
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
static char usrdata[] = {"user data!"};
int main(int argc, char *argv[])
{
int fd, retvalue;
char *filename;
char readbuf[100],writebuf[100];
if(argc !=3){
printf("Error Usage!\r\n");
return -1;
}
filename = argv[1];
fd = open(filename, O_RDWR);
if (fd < 0){
printf("Cant open file %s\r\n", filename);
return -1;
}
if (atoi(argv[2]) == 1){
retvalue = read(fd, readbuf, 50);
if(retvalue<0){
printf("read file %s failed\r\n", filename);
}
else{
printf("read data:%s\r\n", readbuf);
}
}
if (atoi(argv[2]) == 2){
memcpy(writebuf, usrdata, sizeof(usrdata));
retvalue = write(fd, writebuf,50);
if (retvalue < 0){
printf("write file %s fail\r\n", filename);
}
}
retvalue = close(fd);
if (retvalue < 0){
printf("Cannot close file %s\n", filename);
return -1;
}
return 0;
}
Makefile
KERNELDIR := /home/zzk/linux/IMX6ULL/linux/temp/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek
CURRENT_PATH := $(shell pwd)
NFS_PATH := /home/zzk/linux/nfs/rootfs/lib/modules/4.1.15
obj-m := chrdevbase.o
obj-ko := chrdevbase.ko
build: kernel_modules
kernel_modules:
$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modules
arm-linux-gnueabihf-gcc chrdevbaseApp.c -o chrdevbaseApp
clean:
$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean
install:
cp $(obj-ko) chrdevbaseApp $(NFS_PATH)
验证:
- insmod chrdevbase.ko
- mknod /dev/chrdevbase c 200 0
- 如下图:用APP验证读写
![在这里插入图片描述](https://img-blog.csdnimg.cn/7dc5777193bd43609a5018cc8c87f355.png)