在虛擬開發板上加載驅動-Linux驅動學習(4)

【學習筆記】node

驅動代碼linux

file_operations.cshell

#include <linux/init.h>
#include <linux/module.h>
//雜項設備驅動須要增長兩個頭文件
#include <linux/miscdevice.h>
#include <linux/fs.h>
//傳輸函數頭文件
#include <linux/uaccess.h>

int misc_open(struct inode *inode, struct file *file){//(*open)函數實現
	printk("hello misc_open\n");
	return 0;
}

int misc_release(struct inode *inode, struct file *file){//(*release)函數實現
	printk("bye bye\n");
	return 0;
}

ssize_t misc_read(struct file *file, char __user *ubuf, size_t size, loff_t *loff_t){

	char kbuf[64] = "mydate";//定義字符串,可以在應用層讀取到

	if(copy_to_user(ubuf, kbuf, strlen(kbuf)) != 0){//判斷是否成功嚮應用層傳輸數據

		printk("copy_to_user error\n");
		return -1;
	
	}
	
	return 0;
}

ssize_t misc_write(struct file *file, const char __user *ubuf, size_t size, loff_t *loff_t){

	char kbuf[64] = {0};
	
	if(copy_from_user(kbuf, ubuf, size) != 0){//判斷是否成功嚮應用層傳輸數據

		printk("copy_from_user error\n");

		return -1;
	
	}

	printk("kbuf is %s\n",kbuf);
	return 0;

}


//第2步:填充文件操做集
struct file_operations misc_fops = {
	.owner = THIS_MODULE,	//這裏簡單的填充一個owner
	.open = misc_open,	//根據咱們自定義的函數名來填充
	.release = misc_release,
	.read = misc_read,
	.write = misc_write
};

//第1步:填充雜項設備結構體
struct miscdevice misc_dev = {
	.minor = MISC_DYNAMIC_MINOR,	//次設備號,動態分配
	.name = "hello_misc",			//設備節點的名字
	.fops = &misc_fops				//填充文件操做集
};
//第3步;註冊到內核
static int misc_init(void){
	int ret;
	ret = misc_register(&misc_dev);//存儲註冊的地址
	//判斷是否註冊成功
	if(ret < 0){
		printk("misc registe is error\n");
		return -1;
	}
	printk("misc registe is successful\n");  //內核裏不能使用c語言庫,因此不能用printf
	return 0;
}
//卸載驅動
static void misc_exit(void){
	misc_deregister(&misc_dev);
	printk("misc bye bye\n");
}

//入口和出口
module_init(misc_init);
module_exit(misc_exit);

//聲明許可證
MODULE_LICENSE("GPL");

app.capp

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc, char *argv[]){//若是打開設備節點成功,這會調用驅動裏邊的misc_open()函數

	int fd;
	
	char read_buf[64] = {0};
	char write_buf[64] = "write date";
	
	fd = open("/dev/hello_misc",O_RDWR);//open the device node

	if(fd < 0){		//determine whether the opening is successful
	
		perror("open error\n");//和printf用法類似
		
		return fd;
	}

	read(fd,read_buf,sizeof(read_buf));//讀設備節點

	printf("read_buf is %s\n",read_buf);//打印從內核層讀取的內容
	
	write(fd,write_buf,sizeof(write_buf));//將數據寫入設備節點,將應用層數據傳入的內核層
	

	close(fd);//關閉節點
	
	return 0;
}

Makefileide

obj-m +=file_operations.o

KDIR:=/home/pymeia/qemu/ARM/linux-4.9.268

PWD?=$(shell pwd)

ARCH=arm
CROSS_COMPILE=arm-linux-gnueabi-

all:
	make -C $(KDIR) M=$(PWD) modules
clean:
	make -C $(KDIR) M=$(PWD) clean

開發板初始信息函數

image

編譯驅動和app學習

若是編譯出錯,則須要輸入以下命令code

export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabi-

image

拷貝file_operations.ko驅動和app到根目錄,更新磁盤鏡像blog

image

再次啓動開發板 sh runnolcd.sh開發

image

加載驅動,並顯示驅動信息

insmod file_operations.ko
lsmod

image

卸載驅動

rmmod file_operations
rmmod file_operations.ko

image

運行app

./app

我這裏虛擬開發板配置不完善,運行顯示錯誤

整理自嵌入式學習之Linux驅動篇

相關文章
相關標籤/搜索