3.用戶程序與驅動交互

驅動程序請使用第二章https://blog.csdn.net/chenhequanlalala/article/details/140034424

用戶app與驅動交互最常見的做法是insmod驅動后,生成一個設備節點,app通過open,read等系統調用去操作這個設備節點,這里先用mknode命令調試。

mknod 設備名 設備類型(b塊設備/c字符設備/p管道)?主設備號 次設備號

mknod /dev/hello c 240 0

?使用mknode后生成了/dev/hello節點,寫入數據到hello節點中,查看dmesg的輸出發現調用了驅動的open write release

echo 1 > /dev/hello

[ ?802.771723] /home/book/nfs_rootfs/drivers_projects/01_hello_drv/hello_drv.c hello_open 48
[ ?802.773196] /home/book/nfs_rootfs/drivers_projects/01_hello_drv/hello_drv.c hello_write 40
[ ?802.773285] /home/book/nfs_rootfs/drivers_projects/01_hello_drv/hello_drv.c hello_release 56
?

?這里寫一個C程序來讀寫這個設備節點

#include "linux/string.h"
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>/*
讀數據 ./hello_test xxx(設備節點名字)
寫數據 ./hello_test xxx(設備節點名字) string
*/int main(int argc, char **argv)
{int fd;int len;char buf[1024];if(argc < 2){printf("Usage :\n");printf("%s <dev> [str]\n", argv[0]);return -1;}//openfd = open(argv[1], O_RDWR);if(fd < 0){printf("open %s failed\n", argv[1]);return -1;}//readif(argc == 2){len = read(fd, buf, sizeof(buf));printf("%s\n", buf);}//writeelse if(argc == 3){len = write(fd, argv[2], strlen(argv[2]));}else{printf("Too many parameters\n");}close(fd);
}

分別調用?./hello_test /dev/hello 123 和?./hello_test /dev/hello 后,查看dmesg輸出顯示

[ 2770.434595] /home/book/nfs_rootfs/drivers_projects/01_hello_drv/hello_drv.c hello_open 48
[ 2770.434664] /home/book/nfs_rootfs/drivers_projects/01_hello_drv/hello_drv.c hello_write 40
[ 2770.434705] /home/book/nfs_rootfs/drivers_projects/01_hello_drv/hello_drv.c hello_release 56
[ 2772.388372] /home/book/nfs_rootfs/drivers_projects/01_hello_drv/hello_drv.c hello_open 48
[ 2772.388439] /home/book/nfs_rootfs/drivers_projects/01_hello_drv/hello_drv.c hello_read 32
[ 2772.389257] /home/book/nfs_rootfs/drivers_projects/01_hello_drv/hello_drv.c hello_release 56

?app的open write read release都一一對應上了。

這里的./hello_test /dev/hello其實沒有讀到數據,因為驅動程序中并沒有和app交互數據。

[root@100ask:/mnt/drivers_projects/01_hello_drv]# ./hello_test /dev/hello
read size = 1024 data =?
?

?app與驅動交換數據通過copy_from_user和copy_to_user來實現

copy_to_user(void __user *to, const void *from, unsigned long n);
copy_from_user(void *to, const void __user *from, unsigned long n);

在驅動程序中添加一個buf用來保存用戶的數據,用copy_from_user保存數據,用copy_to_user讀取數據。

#include "asm/uaccess.h"
#include "linux/scatterlist.h"
#include "linux/types.h"
#include <linux/mm.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/module.h>#include <linux/uaccess.h>#define DEVICE_NAME "hello_device"
static int major;
#define hello_buf_size 100
static unsigned char hello_buf[hello_buf_size];//ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
//參數含義依次為 要讀取的文件指針 用戶保存數據的buf 讀取數據大小 文件內容的偏移量
static ssize_t hello_read (struct file * filp, char __user *buf, size_t size, loff_t *offset)
{unsigned long len = size > hello_buf_size ? hello_buf_size : size;copy_to_user(buf, hello_buf, len);printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);return len;
}//ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
//參數含義依次為 要寫入的文件指針 用戶要寫入的數據buf 寫入數據大小 文件內容的偏移量
static ssize_t hello_write (struct file *filp, const char __user *buf, size_t size, loff_t *offset)
{unsigned long len = size > hello_buf_size ? hello_buf_size : size;copy_from_user(hello_buf, buf, len);printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);return len;
}//int (*open) (struct inode *, struct file *);
//參數含義依次為 文件索引節點 文件指針
static int hello_open (struct inode *node, struct file *filp)
{printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);return 0;
}//int (*release) (struct inode *, struct file *);
//參數含義依次為 文件索引節點 文件指針
static int hello_release (struct inode *node, struct file *filp)
{printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);return 0; 
}/*構建file_operations結構體*/
static const struct file_operations hello_fops = {.owner      = THIS_MODULE,.read		= hello_read,.write		= hello_write,.open		= hello_open,.release    = hello_release,
};/*init函數,實現register_chrdev*/
static int __init hello_init(void)
{//數含義依次為 主設備號,如果為0,內核會自動分配一個可用的。設備名,會在/proc/devices中顯示。 file_operations結構體//注冊成功就返回主設備號major = register_chrdev(0, DEVICE_NAME, &hello_fops);printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);return 0;
}/*exit函數unregister_chrdev*/
static void __exit hello_exit(void)
{//數含義依次為 主設備號 設備名unregister_chrdev(major, DEVICE_NAME);printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
}module_init(hello_init);
module_exit(hello_exit);
//遵循GPL協議
MODULE_LICENSE("GPL");

重新insmod驅動后,執行測試程序

[root@100ask:/mnt/drivers_projects/01_hello_drv]# ./hello_test /dev/hello 123456
[root@100ask:/mnt/drivers_projects/01_hello_drv]# ./hello_test /dev/hello ? ? ??
read size = 100 data = 123456
[root@100ask:/mnt/drivers_projects/01_hello_drv]# ./hello_test /dev/hello hello
[root@100ask:/mnt/drivers_projects/01_hello_drv]# ./hello_test /dev/hello?
read size = 100 data = hello6
?

?這里第二次輸出hello6,是因為copy_from_user只是寫入指定長度的數據,第一次寫入的123456只覆蓋了前5字節。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/37701.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/37701.shtml
英文地址,請注明出處:http://en.pswp.cn/web/37701.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

64.WEB滲透測試-信息收集- WAF、框架組件識別(4)

免責聲明&#xff1a;內容僅供學習參考&#xff0c;請合法利用知識&#xff0c;禁止進行違法犯罪活動&#xff01; 內容參考于&#xff1a; 易錦網校會員專享課 上一個內容&#xff1a;63.WEB滲透測試-信息收集- WAF、框架組件識別&#xff08;3&#xff09;-CSDN博客 我們在…

【FedMut】Generalized Federated Learning via Stochastic Mutation

基于隨機變異的泛化聯邦學習 來源&#xff1a;AAAI2024 Abstract 問題&#xff1a; FedAvg 將相同的全局模型派發給客戶端進行本地訓練&#xff0c;容易陷入尖銳解&#xff0c;導致訓練出性能低下的全局模型 提出 FedMut&#xff1a; 本文提出了一種名為 FedMut 的新型FL方法…

2024免費的股票數據接口API

滄海數據 # Restful API https://tsanghi.com/api/fin/stock/{exchange_code}/realtime?token5dbb47113a4a43a6be1755673ce854db&ticker{ticker} 數據來源&#xff1a;滄海數據 請求方式&#xff1a;Get 數據格式&#xff1a;標準Json格式[{},...{}]

如何借用物聯網快速實現高標準農田信息化

如何借用物聯網快速實現高標準農田信息化 高標準農田信息化&#xff0c;作為現代農業發展的重要基石&#xff0c;是指在建設高產、穩產、節水、環保的農田基礎上&#xff0c;深度融合現代信息技術&#xff0c;實現農田管理的精準化、智能化和高效化。物聯網&#xff08;Intern…

vue3+ts實現計算兩個字符串的相似度

在TypeScript中&#xff0c;可以使用Levenshtein萊文斯坦距離算法來精確匹配兩個字符串的相似度百分比。Levenshtein距離是指兩個字符串之間&#xff0c;由一個轉換成另一個所需的最少編輯操作次數&#xff0c;這里的編輯操作包括插入、刪除、替換。 /*** Levenshtein距離算法…

Linux Static calls機制

文章目錄 前言一、簡介二、Background: indirect calls, Spectre, and retpolines2.1 Indirect calls2.2 Spectre (v2)2.3 RetpolinesConsequences 2.4 Static callsHow it works 三、其他參考資料 前言 Linux內核5.10內核版本引入新特性&#xff1a;Static calls。 Static c…

JAVA各版本-安裝教程

目錄 Java安裝包下載 Java安裝步驟 Java環境配置 Java安裝包下載 到Oracle官網下載自己需要的版本 Oracle Java下載&#xff1a;Java Archive | Oracle Hong Kong SAR, PRC 下拉選擇自己需要的版本&#xff08;本教程以Windows環境下&#xff0c;JAVA11為例&#xff09; 注…

C++初學者指南-3.自定義類型(第一部分)-指針

C初學者指南-3.自定義類型(第一部分)-指針 文章目錄 C初學者指南-3.自定義類型(第一部分)-指針1.為什么我們需要它們&#xff1f;2.T 類型的對象指針原始指針&#xff1a;T * 智能指針(C11) 3.操作符地址操作符 &解引用運算符 *成員訪問操作符 ->語法重定向 4.nullptr (…

【Linux】用戶管理

創建與刪除 adduser adduser 是一個交互式命令&#xff0c;用于創建新用戶并設置初始環境。 sudo adduser 用戶名示例&#xff1a; sudo adduser newuseruseradd useradd 是一個非交互式命令&#xff0c;允許你通過選項指定用戶的屬性。 sudo useradd [選項] 用戶名常見選…

SCADA系統對于工業生產的意義!

關鍵字:LP-SCADA系統, 傳感器可視化, 設備可視化, 獨立SPC系統, 智能儀表系統,SPC可視化,獨立SPC系統 SCADA系統在智能制造中扮演著至關重要的角色&#xff0c;它通過集成和自動化工廠車間的各種過程&#xff0c;提高了生產效率和產品質量&#xff0c;降低了成本&#xff0c;并…

【AI繪畫 ComfyUI】全新整合包來襲!一鍵安裝 即開即用,超好用的工作流形式的AI繪畫工具!

大家好&#xff0c;我是畫畫的小強 請在看這篇文章的人注意&#xff0c;本文章介紹的Comfy UI整合包是一個節點式的工作&#xff0c;流式的AI繪畫界面&#xff0c;并不適合新手使用。 如果你在找的是Web UI, 請前往我之前發布一篇的文章AI繪畫『Stable Diffusion』面向小白的…

【高中數學/基本不等式】設a,b>0.a+b=5,則 根號下(a+1)+根號下(b+3) 的最大值為?(2015重慶卷)

【問題】 設a,b>0.ab5,則根號下(a1)根號下(b3)的最大值為&#xff1f; 【解答】 解法一&#xff1a; 因雙根號計算不便&#xff0c;故采用平方后簡化之。 原式的平方a12倍根號下((a1)(b3))b3 ab42倍根號下((a1)(b3)) 因為ab5 a1b31359 9(a1)(b3)>2倍根號下((a1)…

【小貪】項目實戰——Zero-shot根據文字提示分割出圖片目標掩碼

目標描述 給定RGB視頻或圖片&#xff0c;目標是分割出圖像中的指定目標掩碼。我們需要復現兩個Zero-shot的開源項目&#xff0c;分別為IDEA研究院的GroundingDINO和Facebook的SAM。首先使用目標檢測方法GroundingDINO&#xff0c;輸入想檢測目標的文字提示&#xff0c;可以獲得…

uniapp中如何進行微信小程序的分包

思路&#xff1a;在uniapp中對微信小程序進行分包&#xff0c;和原生微信小程序進行分包的操作基本上沒區別&#xff0c;主要就是在pages.json中進行配置。 如圖&#xff0c;我新增了一個包diver-page 此時需要在pages.json中的subPackages數組中新增一項 root代表這個包的根…

用好華為小助手,生活總能快人一步

嘿&#xff01;朋友們&#xff01;你們有沒有想過&#xff0c;如果身邊有一個小助手&#xff0c;他不僅聰明伶俐&#xff0c;還能在生活的方方面面給予你最貼心的關懷和幫助&#xff0c;讓我們的日常生活變得更加方便和快捷&#xff0c;那該有多好&#xff01;沒錯&#xff0c;…

【云原生】Kubernetes資源配額+HPA+節點選擇器+親和性+污點

Kubernetes高級功能 文章目錄 Kubernetes高級功能一、資源配額1.1、什么是資源配額1.2、資源配額應用1.2.1、針對Namespace設置資源配額1.2.2、針對Pod設置資源配額 二、HorizontalPodAutoscaler&#xff08;HPA&#xff09;2.1、什么是HorizontalPodAutoscaler2.2、Horizontal…

談談創意設計中的AI、AGI、AIGC

在當今的數字化時代&#xff0c;創意設計領域正經歷著前所未有的變革。隨著人工智能&#xff08;AI&#xff09;、通用人工智能&#xff08;AGI&#xff09;以及人工智能生成內容&#xff08;AIGC&#xff09;的迅猛發展&#xff0c;設計師們的工作方式和創作手段都發生了深刻的…

Spring Boot中的緩存配置與優化

Spring Boot中的緩存配置與優化 大家好&#xff0c;我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01;今天我們將探討在Spring Boot應用中如何配置和優化緩存&#xff0c;以提升系統的…

UML形式化建模期末復習筆記

本文檔為xmind導出&#xff0c;可能存在缺少圖片等問題&#xff0c;建議下載思維導圖查看完整內容 鏈接: https://pan.baidu.com/s/17s-utC2C6Qg0tFp61Kw0ZQ?pwduq64 提取碼: uq64 概述 UML: Unified Modeling Language 統一建模語言 建模 定義 把不太理解的東西和一些已經較…

隔離級別是如何實現的?

在數據庫管理系統中&#xff0c;隔離級別&#xff08;Isolation Level&#xff09;是用來定義事務在執行過程中可以看到其他事務執行中的操作的一個設置。這主要用于控制事務之間的并發性和數據一致性。SQL標準定義了四種隔離級別&#xff0c;每種級別都以不同的方式平衡了性能…