【學習筆記】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
開發板初始信息函數
編譯驅動和app學習
若是編譯出錯,則須要輸入以下命令code
export ARCH=arm export CROSS_COMPILE=arm-linux-gnueabi-
拷貝file_operations.ko驅動和app到根目錄,更新磁盤鏡像blog
再次啓動開發板 sh runnolcd.sh開發
加載驅動,並顯示驅動信息
insmod file_operations.ko lsmod
卸載驅動
rmmod file_operations rmmod file_operations.ko
運行app
./app
我這裏虛擬開發板配置不完善,運行顯示錯誤