国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁 > news >正文

網(wǎng)站正常打開速度慢semi

網(wǎng)站正常打開速度慢,semi,上海手機網(wǎng)站開發(fā),國際新聞最新消息戰(zhàn)爭視頻在上一節(jié)完成NFS開發(fā)環(huán)境的搭建后,本節(jié)將探討Linux字符設(shè)備驅(qū)動的開發(fā)。字符設(shè)備驅(qū)動作為Linux內(nèi)核的重要組成部分,主要負責(zé)管理與字符設(shè)備(如串口、鍵盤等)的交互,并為用戶空間程序提供統(tǒng)一的讀寫操作接口。 驅(qū)動代碼…

在上一節(jié)完成NFS開發(fā)環(huán)境的搭建后,本節(jié)將探討Linux字符設(shè)備驅(qū)動的開發(fā)。字符設(shè)備驅(qū)動作為Linux內(nèi)核的重要組成部分,主要負責(zé)管理與字符設(shè)備(如串口、鍵盤等)的交互,并為用戶空間程序提供統(tǒng)一的讀寫操作接口。

驅(qū)動代碼

#include <linux/module.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/uaccess.h>
#include <linux/cdev.h> #define DEVICE_NAME "hello_chrdev"
#define BUFFER_SIZE 100// 設(shè)備結(jié)構(gòu)體
typedef struct {char buffer[BUFFER_SIZE];struct class *class;struct device *device;dev_t dev_num;struct cdev cdev;
} HelloDevice;static HelloDevice hello_dev;// 打開設(shè)備
static int hello_open(struct inode *inode, struct file *filp) {printk(KERN_INFO "Hello device opened\n");return 0;
}// 讀取設(shè)備
static ssize_t hello_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) {size_t len = strlen(hello_dev.buffer);if (*f_pos >= len) {return 0;}if (count > len - *f_pos) {count = len - *f_pos;}if (copy_to_user(buf, hello_dev.buffer + *f_pos, count)) {return -EFAULT;}*f_pos += count;return count;
}// 寫入設(shè)備
static ssize_t hello_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) {if (count > BUFFER_SIZE - 1) {count = BUFFER_SIZE - 1;}if (copy_from_user(hello_dev.buffer, buf, count)) {return -EFAULT;}hello_dev.buffer[count] = '\0';*f_pos += count;return count;
}// 關(guān)閉設(shè)備
static int hello_release(struct inode *inode, struct file *filp) {printk(KERN_INFO "Hello device closed\n");return 0;
}// 文件操作結(jié)構(gòu)體
static struct file_operations hello_fops = {.owner = THIS_MODULE,.open = hello_open,.read = hello_read,.write = hello_write,.release = hello_release,
};// 模塊初始化函數(shù)
static int __init hello_init(void) {int ret;// 分配設(shè)備號ret = alloc_chrdev_region(&hello_dev.dev_num, 0, 1, DEVICE_NAME);if (ret < 0) {printk(KERN_ERR "Failed to allocate character device number\n");return ret;}// 創(chuàng)建類hello_dev.class = class_create(THIS_MODULE, DEVICE_NAME);if (IS_ERR(hello_dev.class)) {unregister_chrdev_region(hello_dev.dev_num, 1);printk(KERN_ERR "Failed to create class\n");return PTR_ERR(hello_dev.class);}// 創(chuàng)建設(shè)備hello_dev.device = device_create(hello_dev.class, NULL, hello_dev.dev_num, NULL, DEVICE_NAME);if (IS_ERR(hello_dev.device)) {class_destroy(hello_dev.class);unregister_chrdev_region(hello_dev.dev_num, 1);printk(KERN_ERR "Failed to create device\n");return PTR_ERR(hello_dev.device);}// 初始化 cdev 結(jié)構(gòu)體cdev_init(&hello_dev.cdev, &hello_fops);hello_dev.cdev.owner = THIS_MODULE;// 添加字符設(shè)備到系統(tǒng)ret = cdev_add(&hello_dev.cdev, hello_dev.dev_num, 1);if (ret < 0) {device_destroy(hello_dev.class, hello_dev.dev_num);class_destroy(hello_dev.class);unregister_chrdev_region(hello_dev.dev_num, 1);printk(KERN_ERR "Failed to add character device\n");return ret;}printk(KERN_INFO "Hello device initialized. Major: %d, Minor: %d\n", MAJOR(hello_dev.dev_num), MINOR(hello_dev.dev_num));return 0;
}// 模塊卸載函數(shù)
static void __exit hello_exit(void) {cdev_del(&hello_dev.cdev);device_destroy(hello_dev.class, hello_dev.dev_num);class_destroy(hello_dev.class);unregister_chrdev_region(hello_dev.dev_num, 1);printk(KERN_INFO "Hello device removed\n");
}module_init(hello_init);
module_exit(hello_exit);MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("A simple hello world character device driver");

函數(shù)接口詳解

1. 模塊初始化與退出相關(guān)函數(shù)
alloc_chrdev_region
int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name);
  • 功能:動態(tài)分配一組連續(xù)的字符設(shè)備號。
  • 參數(shù)
    • dev:用于存儲分配到的設(shè)備號。
    • baseminor:起始的次設(shè)備號。
    • count:要分配的設(shè)備號數(shù)量。
    • name:設(shè)備的名稱,用于在 /proc/devices 中顯示。
  • 返回值:成功返回 0,失敗返回負數(shù)錯誤碼。
class_create
struct class *class_create(struct module *owner, const char *name);
  • 功能:在 /sys/class 目錄下創(chuàng)建一個設(shè)備類。
  • 參數(shù)
    • owner:指向模塊的指針,通常為 THIS_MODULE。
    • name:類的名稱。
  • 返回值:成功返回指向 struct class 的指針,失敗返回錯誤指針。
device_create
struct device *device_create(struct class *class, struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...);
  • 功能:在 /sys/class/<class_name> 目錄下創(chuàng)建設(shè)備節(jié)點,并在 /dev 目錄下創(chuàng)建對應(yīng)的設(shè)備文件。
  • 參數(shù)
    • class:指向設(shè)備類的指針。
    • parent:父設(shè)備指針,通常為 NULL。
    • devt:設(shè)備號。
    • drvdata:設(shè)備驅(qū)動數(shù)據(jù),通常為 NULL。
    • fmt:設(shè)備名稱的格式化字符串。
  • 返回值:成功返回指向 struct device 的指針,失敗返回錯誤指針。
cdev_init
void cdev_init(struct cdev *cdev, const struct file_operations *fops);
  • 功能:初始化字符設(shè)備結(jié)構(gòu)體 struct cdev,并關(guān)聯(lián)文件操作結(jié)構(gòu)體 struct file_operations
  • 參數(shù)
    • cdev:指向 struct cdev 的指針。
    • fops:指向 struct file_operations 的指針。
cdev_add
int cdev_add(struct cdev *p, dev_t dev, unsigned count);
  • 功能:將字符設(shè)備添加到內(nèi)核中。
  • 參數(shù)
    • p:指向 struct cdev 的指針。
    • dev:設(shè)備號。
    • count:設(shè)備數(shù)量。
  • 返回值:成功返回 0,失敗返回負數(shù)錯誤碼。
module_initmodule_exit
module_init(hello_init);
module_exit(hello_exit);
  • 功能:分別指定模塊加載和卸載時調(diào)用的函數(shù)。
2. 文件操作相關(guān)函數(shù)
  • 在 Linux 內(nèi)核中,struct file_operations 結(jié)構(gòu)體是字符設(shè)備驅(qū)動與用戶空間進行交互的關(guān)鍵橋梁,其中 open、read、writerelease 是比較常用的操作函數(shù)。

    struct file_operations` 結(jié)構(gòu)體中相關(guān)成員介紹

    open 函數(shù)
    int (*open) (struct inode *inode, struct file *filp);
    
    • 功能:當(dāng)用戶空間使用 open() 系統(tǒng)調(diào)用打開設(shè)備文件時,內(nèi)核會調(diào)用驅(qū)動中注冊的 open 函數(shù)。該函數(shù)通常用于執(zhí)行設(shè)備的初始化操作,如分配資源、檢查設(shè)備狀態(tài)等。
    • 參數(shù)
      • struct inode *inode:指向文件對應(yīng)的索引節(jié)點,包含了文件的元信息,如文件類型、權(quán)限等。
      • struct file *filp:指向文件對象,代表了一個打開的文件實例,包含了文件的當(dāng)前狀態(tài)、偏移量等信息。
    • 返回值:成功時返回 0,失敗時返回負數(shù)錯誤碼。
    read 函數(shù)
    ssize_t (*read) (struct file *filp, char __user *buf, size_t count, loff_t *f_pos);
    
    • 功能:當(dāng)用戶空間使用 read() 系統(tǒng)調(diào)用從設(shè)備文件讀取數(shù)據(jù)時,內(nèi)核會調(diào)用驅(qū)動中的 read 函數(shù)。該函數(shù)負責(zé)將設(shè)備中的數(shù)據(jù)復(fù)制到用戶空間的緩沖區(qū)。
    • 參數(shù)
      • struct file *filp:指向文件對象。
      • char __user *buf:用戶空間的緩沖區(qū)指針,用于存儲從設(shè)備讀取的數(shù)據(jù)。
      • size_t count:用戶請求讀取的字節(jié)數(shù)。
      • loff_t *f_pos:文件的當(dāng)前偏移量指針,可通過修改該指針來更新文件的讀寫位置。
    • 返回值:成功時返回實際讀取的字節(jié)數(shù),返回 0 表示已到達文件末尾,失敗時返回負數(shù)錯誤碼。
    write 函數(shù)
    ssize_t (*write) (struct file *filp, const char __user *buf, size_t count, loff_t *f_pos);
    
    • 功能:當(dāng)用戶空間使用 write() 系統(tǒng)調(diào)用向設(shè)備文件寫入數(shù)據(jù)時,內(nèi)核會調(diào)用驅(qū)動中的 write 函數(shù)。該函數(shù)負責(zé)將用戶空間緩沖區(qū)中的數(shù)據(jù)復(fù)制到設(shè)備中。
    • 參數(shù)
      • struct file *filp:指向文件對象。
      • const char __user *buf:用戶空間的緩沖區(qū)指針,包含了要寫入設(shè)備的數(shù)據(jù)。
      • size_t count:用戶請求寫入的字節(jié)數(shù)。
      • loff_t *f_pos:文件的當(dāng)前偏移量指針。
    • 返回值:成功時返回實際寫入的字節(jié)數(shù),失敗時返回負數(shù)錯誤碼。
    release 函數(shù)
    int (*release) (struct inode *inode, struct file *filp);
    
    • 功能:當(dāng)用戶空間使用 close() 系統(tǒng)調(diào)用關(guān)閉設(shè)備文件時,內(nèi)核會調(diào)用驅(qū)動中的 release 函數(shù)。該函數(shù)通常用于執(zhí)行設(shè)備的清理操作,如釋放資源、關(guān)閉設(shè)備等。
    • 參數(shù)
      • struct inode *inode:指向文件對應(yīng)的索引節(jié)點。
      • struct file *filp:指向文件對象。
    • 返回值:成功時返回 0,失敗時返回負數(shù)錯誤碼。
3. 模塊卸載相關(guān)函數(shù)
cdev_del
void cdev_del(struct cdev *p);
  • 功能:從內(nèi)核中移除字符設(shè)備。
  • 參數(shù)
    • p:指向 struct cdev 的指針。
device_destroy
void device_destroy(struct class *class, dev_t devt);
  • 功能:銷毀 /sys/class/<class_name> 目錄下的設(shè)備節(jié)點和 /dev 目錄下的設(shè)備文件。
  • 參數(shù)
    • class:指向設(shè)備類的指針。
    • devt:設(shè)備號。
class_destroy
void class_destroy(struct class *cls);
  • 功能:銷毀 /sys/class 目錄下的設(shè)備類。
  • 參數(shù)
    • cls:指向 struct class 的指針。
unregister_chrdev_region
void unregister_chrdev_region(dev_t from, unsigned count);
  • 功能:釋放之前分配的字符設(shè)備號。
  • 參數(shù)
    • from:起始的設(shè)備號。
    • count:要釋放的設(shè)備號數(shù)量。

編譯和測試

編寫 Makefile
obj-m += helloworld.o
KDIR := linux-5.15.18/
PWD := $(shell pwd)
default:$(MAKE) -C $(KDIR) M=$(PWD) modules
clean:$(MAKE) -C $(KDIR) M=$(PWD) clean

將 linux-5.15.18/ 替換為實際的 Linux 5.15.18 內(nèi)核源碼路徑。

編譯驅(qū)動

在終端中執(zhí)行 make 命令編譯驅(qū)動模塊。

測試驅(qū)動

在 QEMU 終端中:

  1. 使用 insmod helloworld.ko 加載驅(qū)動模塊。
  2. 使用 echo “Hello World” > /dev/helloworld 向設(shè)備寫入數(shù)據(jù)。
  3. 使用 cat /dev/helloworld 從設(shè)備讀取數(shù)據(jù)。
  4. 使用 rmmod hello_chrdev.ko 卸載驅(qū)動模塊。
    在這里插入圖片描述
http://m.aloenet.com.cn/news/39575.html

相關(guān)文章:

  • 單頁網(wǎng)站對攻擊的好處如何做好互聯(lián)網(wǎng)營銷
  • 警惕成人網(wǎng)站免費看手機引流推廣接單
  • 做網(wǎng)站所用的技術(shù)推廣普通話的宣傳語
  • 國內(nèi)網(wǎng)站開發(fā)短視頻精準(zhǔn)獲客系統(tǒng)
  • 品牌專業(yè)建設(shè)網(wǎng)站常見的搜索引擎
  • 在哪能學(xué)到網(wǎng)站建設(shè)專業(yè)seo推廣是做什么
  • 做植物提取物好的推廣網(wǎng)站seo自動優(yōu)化軟件下載
  • 校園網(wǎng)站規(guī)劃與建設(shè)工具大全
  • 網(wǎng)站建設(shè)app開發(fā)合同范本百度普通下載
  • 新疆建設(shè)廳官方網(wǎng)站文件鏈接推廣
  • 無錫 網(wǎng)站建設(shè)黃頁88網(wǎng)官網(wǎng)
  • 同個主體新增網(wǎng)站備案外鏈吧怎么使用
  • 做網(wǎng)站看網(wǎng)頁效果手機網(wǎng)站排名優(yōu)化
  • 跨境電商千萬別做亞馬遜seo排名優(yōu)化工具推薦
  • 地產(chǎn)建站規(guī)劃可以投放廣告的網(wǎng)站
  • 網(wǎng)站建設(shè)服務(wù)價格表seo顧問公司
  • 網(wǎng)站icp備案新規(guī)推廣哪個平臺好
  • c 做網(wǎng)站教程百度seo教程視頻
  • 建設(shè)銀行滇龍行網(wǎng)站百度競價推廣點擊器
  • 網(wǎng)站建設(shè)深圳百度霸屏推廣
  • 做網(wǎng)站和app需要多久短網(wǎng)址在線生成
  • 找人做網(wǎng)站價格2345網(wǎng)址大全設(shè)主頁
  • 福州網(wǎng)站建設(shè)制作首選熒光信息建網(wǎng)站建設(shè)
  • 收錢碼合并的網(wǎng)站怎么做東莞seo黑帽培訓(xùn)
  • 網(wǎng)站400百度關(guān)鍵詞優(yōu)化手段
  • vps做網(wǎng)站用什么系統(tǒng)網(wǎng)站推廣途徑和推廣要點有哪些?
  • 站長工具收錄查詢女裝關(guān)鍵詞排名
  • 陜西住房與城鄉(xiāng)建設(shè)廳網(wǎng)站微信引流獲客軟件
  • 東莞南城網(wǎng)站建設(shè)公司網(wǎng)絡(luò)營銷優(yōu)化推廣
  • 網(wǎng)站建設(shè)實訓(xùn)報告建議北京網(wǎng)站制作建設(shè)公司