97色伦色在线综合视频,无玛专区,18videosex性欧美黑色,日韩黄色电影免费在线观看,国产精品伦理一区二区三区,在线视频欧美日韩,亚洲欧美在线中文字幕不卡

網(wǎng)站建設(shè) 引導(dǎo)免費(fèi)建商城網(wǎng)站哪個(gè)好

鶴壁市浩天電氣有限公司 2026/01/22 11:05:24
網(wǎng)站建設(shè) 引導(dǎo),免費(fèi)建商城網(wǎng)站哪個(gè)好,做設(shè)備開(kāi)通哪個(gè)網(wǎng)站好,怎么搭建自己的博客網(wǎng)站聲明#xff1a;內(nèi)容源于B站UP主——北京迅為電子一、簡(jiǎn)介字符設(shè)備#xff1a;IO的傳遞傳遞過(guò)程是以字符設(shè)備為單位的#xff0c;沒(méi)有緩沖#xff0c;比如I2C,SPI都是字符設(shè)備 塊設(shè)備#xff1a;IO傳遞過(guò)程是一塊為單位的#xff0c;跟存儲(chǔ)相關(guān)的#xff0c;都屬于塊設(shè)備…聲明內(nèi)容源于B站UP主——北京迅為電子一、簡(jiǎn)介字符設(shè)備IO的傳遞傳遞過(guò)程是以字符設(shè)備為單位的沒(méi)有緩沖比如I2C,SPI都是字符設(shè)備塊設(shè)備IO傳遞過(guò)程是一塊為單位的跟存儲(chǔ)相關(guān)的都屬于塊設(shè)備網(wǎng)絡(luò)設(shè)備與前面兩個(gè)不一樣是以sockett套接字來(lái)訪問(wèn)的1.1 雜項(xiàng)設(shè)備特點(diǎn)雜項(xiàng)設(shè)備使字符設(shè)備的一種可以自動(dòng)生成設(shè)備節(jié)點(diǎn)系統(tǒng)中有很多雜項(xiàng)設(shè)備可以通過(guò)cat /proc/misc命令來(lái)查看問(wèn)題一雜項(xiàng)設(shè)備除了比字符設(shè)備代碼簡(jiǎn)單還有別的區(qū)別嗎雜項(xiàng)設(shè)備的主設(shè)備號(hào)都是相同的均為10次設(shè)備是不同的主設(shè)備號(hào)相同就可以節(jié)省內(nèi)核資源問(wèn)題二主設(shè)備號(hào)與次設(shè)備號(hào)是什么設(shè)備號(hào)包含主設(shè)備號(hào)和此設(shè)備號(hào)主設(shè)備號(hào)在Linux系統(tǒng)里面是唯一的次設(shè)備號(hào)不一定唯一主設(shè)備號(hào)可以通過(guò)命令cat /proc/devices二、雜項(xiàng)設(shè)備2.1 雜項(xiàng)設(shè)備描述定義在內(nèi)核源碼路徑下include/linux/miscdevicestruct miscdevice { int minor; //次設(shè)備號(hào)。可設(shè)為 MISC_DYNAMIC_MINOR通常為255讓內(nèi)核自動(dòng)分配一個(gè)空閑的。 const char *name; //設(shè)備名稱(chēng)。注冊(cè)成功后會(huì)在 /dev/ 下生成以此命名的設(shè)備節(jié)點(diǎn) const struct file_operations *fops;//文件操作集。指向?qū)崿F(xiàn)設(shè)備操作函數(shù)集如 open、read、write、ioctl 等 struct list_head list; struct device *parent; struct device *this_device; const struct attribute_group **groups; const char *nodename; umode_t mode; }; extern int misc_register(struct miscdevice *misc); //注冊(cè)雜項(xiàng)設(shè)備 extern void misc_deregister(struct miscdevice *misc); //注銷(xiāo)雜項(xiàng)設(shè)備file_operations文件操作集定義在incldue/linux/fs.h下面struct file_operations { struct module *owner; loff_t (*llseek) (struct file *, loff_t, int); ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); ssize_t (*read_iter) (struct kiocb *, struct iov_iter *); ssize_t (*write_iter) (struct kiocb *, struct iov_iter *); int (*iterate) (struct file *, struct dir_context *); int (*iterate_shared) (struct file *, struct dir_context *); __poll_t (*poll) (struct file *, struct poll_table_struct *); long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); long (*compat_ioctl) (struct file *, unsigned int, unsigned long); int (*mmap) (struct file *, struct vm_area_struct *); unsigned long mmap_supported_flags; int (*open) (struct inode *, struct file *); int (*flush) (struct file *, fl_owner_t id); int (*release) (struct inode *, struct file *); int (*fsync) (struct file *, loff_t, loff_t, int datasync); int (*fasync) (int, struct file *, int); int (*lock) (struct file *, int, struct file_lock *); ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); int (*check_flags)(int); int (*flock) (struct file *, int, struct file_lock *); ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); int (*setlease)(struct file *, long, struct file_lock **, void **); long (*fallocate)(struct file *file, int mode, loff_t offset, loff_t len); void (*show_fdinfo)(struct seq_file *m, struct file *f); #ifndef CONFIG_MMU unsigned (*mmap_capabilities)(struct file *); #endif ssize_t (*copy_file_range)(struct file *, loff_t, struct file *, loff_t, size_t, unsigned int); int (*clone_file_range)(struct file *, loff_t, struct file *, loff_t, u64); int (*dedupe_file_range)(struct file *, loff_t, struct file *, loff_t, u64); int (*fadvise)(struct file *, loff_t, loff_t, int); ANDROID_KABI_RESERVE(1); ANDROID_KABI_RESERVE(2); ANDROID_KABI_RESERVE(3); ANDROID_KABI_RESERVE(4); } __randomize_layout;里面的一個(gè)結(jié)構(gòu)體成員都對(duì)應(yīng)一個(gè)調(diào)用2.2 注冊(cè)雜項(xiàng)設(shè)備的流程①填充miscdevice這個(gè)結(jié)構(gòu)體②填充file_operations這個(gè)結(jié)構(gòu)體③注冊(cè)雜項(xiàng)設(shè)備并生成設(shè)備節(jié)點(diǎn)/*模板*/ struct const file_operation xx_fops { .owner THIS_MODULE, //固定寫(xiě)法 ...... }; struct miscdevice xx_dev { .minor MISC_DYNAMIC_MINOR, //自動(dòng)分配次設(shè)備號(hào) .name xxx, //定義自己的雜項(xiàng)設(shè)備名稱(chēng) .fopsxx_fops //設(shè)備操作函數(shù)集合 }; static int xxx_init() { int ret; retmisc_misc_register(xx_dev); //注冊(cè)設(shè)備 if(ret0) { printk(misc register error ); return -1; } return 0; } void xxx_exit() { misc_deregister(xx_dev); //注銷(xiāo)設(shè)備 }三、編寫(xiě)一個(gè)雜項(xiàng)設(shè)備驅(qū)動(dòng)編寫(xiě)misc_hello.c文件#include linux/module.h #include linux/init.h #include linux/miscdevice.h #include linux/fs.h //2.填充file_operations結(jié)構(gòu)體 struct file_operations misc_fops { .owner THIS_MODULE //固定寫(xiě)法 }; //1.填充miscdevice結(jié)構(gòu)體 struct miscdevice misc_dev { .minor MISC_DYNAMIC_MINOR, //自動(dòng)分配次設(shè)備號(hào) .name hello_misc, //定義自己的雜項(xiàng)設(shè)備名稱(chēng) .fopsmisc_fops //設(shè)備操作函數(shù)集合 }; static int misc_init(void) //驅(qū)動(dòng)入口函數(shù) { int ret; ret misc_register(misc_dev); //注冊(cè)雜項(xiàng)設(shè)備 if(ret0) { printk(misc device is register error ); return -1; } printk(misc device is register succeed );//注意 內(nèi)核打印用 printk 而不是 printf return 0; } static void misc_exit(void) //驅(qū)動(dòng)出口函數(shù) { misc_deregister(misc_dev); //注銷(xiāo)雜項(xiàng)設(shè)備 printk(misc device is deregister ); } module_init(misc_init); //告訴linux模塊入口函數(shù)加載模塊代碼到操作系統(tǒng) module_exit(misc_exit); //卸載 MODULE_LICENSE(GPL v2); //同意 GPL 開(kāi)源協(xié)議編寫(xiě)Makefile文件export ARCHarm64 #設(shè)置平臺(tái)架構(gòu) export CROSS_COMPILEaarch64-linux-gnu- #交叉編譯器前綴 obj-m helloworld.o #m表示將helloworld.o編譯為模塊 KDIR : ~/LubanCat_SDK/kernel #內(nèi)核源碼路徑 PWD ? $(shell pwd) #獲取當(dāng)前目錄 all: make -C $(KDIR) M$(PWD) ARCH$(ARCH) CROSS_COMPILE$(CROSS_COMPILE) modules #make -C $(KDIR)切換到內(nèi)核目錄;M$(PWD) modules將當(dāng)前路徑下的代碼編譯為模塊 clean: make -C $(KDIR) M$(PWD) ARCH$(ARCH) CROSS_COMPILE$(CROSS_COMPILE) clean #清理生成的文件注意make -C $(KDIR) 會(huì)切換到內(nèi)核源碼目錄并啟動(dòng)一個(gè)新的 make 進(jìn)程。這個(gè)新進(jìn)程的環(huán)境變量可能不會(huì)完全繼承父進(jìn)程即Makefile的導(dǎo)出變量尤其是當(dāng)內(nèi)核源碼目錄的 Makefile 有自己的默認(rèn)設(shè)置時(shí)。顯式傳遞參數(shù)如 ARCHarm64可以確保內(nèi)核的 make 系統(tǒng)使用正確的架構(gòu)和編譯器而不受環(huán)境變量繼承問(wèn)題的影響。四、文件操作函數(shù)集問(wèn)題如果我們?cè)趹?yīng)用層使用系統(tǒng)IO對(duì)設(shè)備節(jié)點(diǎn)進(jìn)行打開(kāi)關(guān)閉讀寫(xiě)等操作時(shí)會(huì)發(fā)生什么呢當(dāng)在應(yīng)用層read設(shè)備節(jié)點(diǎn)的時(shí)候就會(huì)觸發(fā)驅(qū)動(dòng)里面read這個(gè)函數(shù)ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);當(dāng)在應(yīng)用層write設(shè)備節(jié)點(diǎn)的時(shí)候就會(huì)觸發(fā)驅(qū)動(dòng)里面write這個(gè)函數(shù)ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);當(dāng)在應(yīng)用層poll/select設(shè)備節(jié)點(diǎn)的時(shí)候就會(huì)觸發(fā)驅(qū)動(dòng)里面poll/select這個(gè)函數(shù)__poll_t (*poll) (struct file *, struct poll_table_struct *);當(dāng)在應(yīng)用層ioctl設(shè)備節(jié)點(diǎn)的時(shí)候就會(huì)觸發(fā)驅(qū)動(dòng)里面ioctl這個(gè)函數(shù)long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long)當(dāng)在應(yīng)用層open設(shè)備節(jié)點(diǎn)的時(shí)候就會(huì)觸發(fā)驅(qū)動(dòng)里面open這個(gè)函數(shù)int (*open) (struct inode *, struct file *);當(dāng)在應(yīng)用層close設(shè)備節(jié)點(diǎn)的時(shí)候就會(huì)觸發(fā)驅(qū)動(dòng)里面close這個(gè)函數(shù)int (*release) (struct inode *, struct file *);/*驅(qū)動(dòng)層代碼*/ #include linux/module.h #include linux/init.h #include linux/miscdevice.h #include linux/fs.h //3.實(shí)現(xiàn)open函數(shù) static int misc_open(struct inode *inode, struct file *file) { printk(misc device is opened:hello misc open ); return 0; } static int misc_release(struct inode *inode, struct file *file) { printk(misc device is released:hello misc release ); return 0; } static ssize_t misc_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { printk(misc device is read:hello misc read ); return 0; } static ssize_t misc_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { printk(misc device is write:hello misc write ); return 0; } //2.填充file_operations結(jié)構(gòu)體 struct file_operations misc_fops { .owner THIS_MODULE, //固定寫(xiě)法 .open misc_open, .release misc_release, .read misc_read, .write misc_write }; //1.填充miscdevice結(jié)構(gòu)體 struct miscdevice misc_dev { .minor MISC_DYNAMIC_MINOR, //自動(dòng)分配次設(shè)備號(hào) .name hello_misc, //定義自己的雜項(xiàng)設(shè)備名稱(chēng) .fops misc_fops //設(shè)備操作函數(shù)集合 }; static int misc_init(void) //驅(qū)動(dòng)入口函數(shù) { int ret; ret misc_register(misc_dev); //注冊(cè)雜項(xiàng)設(shè)備 if(ret0) { printk(misc device is register error ); return -1; } printk(misc device is register succeed );//注意 內(nèi)核打印用 printk 而不是 printf return 0; } static void misc_exit(void) //驅(qū)動(dòng)出口函數(shù) { misc_deregister(misc_dev); //注銷(xiāo)雜項(xiàng)設(shè)備 printk(misc device is deregister ); } module_init(misc_init); //告訴linux模塊入口函數(shù)加載模塊代碼到操作系統(tǒng) module_exit(misc_exit); //卸載 MODULE_LICENSE(GPL v2); //同意 GPL 開(kāi)源協(xié)議/*上層應(yīng)用用于測(cè)試應(yīng)用層調(diào)用open函數(shù)驅(qū)動(dòng)層是否有相應(yīng)的反應(yīng)*/ #include stdio.h #include fcntl.h #include unistd.h #include sys/stat.h #include sys/types.h int main(int argc, char *argv[]) { int fd; char buf[64]{0}; fd open(/dev/hello_misc, O_RDWR); //打開(kāi)驅(qū)動(dòng)對(duì)應(yīng)的設(shè)備文件 if(fd 0) { printf(misc device open failed ); return -1; } printf(app layer device open success ); read(fd,buf,sizeof(buf)); close(fd); return 0; }設(shè)備節(jié)點(diǎn)就是連接上層應(yīng)用和底層驅(qū)動(dòng)的橋梁?jiǎn)栴}假如在驅(qū)動(dòng)層代碼中file_operitions 里面沒(méi)有read,但是在應(yīng)用層有read設(shè)備節(jié)點(diǎn)代碼的時(shí)候會(huì)發(fā)生什么答什么也不會(huì)發(fā)生也不會(huì)報(bào)錯(cuò)問(wèn)題應(yīng)用層和內(nèi)核層是不能直接進(jìn)行數(shù)據(jù)傳輸?shù)?/用戶(hù)層向內(nèi)核層傳遞數(shù)據(jù) static __always_inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n) //內(nèi)核層向用于層傳遞數(shù)據(jù) static __always_inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n)注意這兩個(gè)函數(shù)只能在驅(qū)動(dòng)代碼中使用函數(shù)copy_from_user(void *to, const void __user *from, unsigned long n)函數(shù)作用從用戶(hù)層讀取數(shù)據(jù)到內(nèi)核層函數(shù)參數(shù)param1 to 目的地址。數(shù)據(jù)拷貝的目的地位于內(nèi)核空間的緩沖區(qū)。param2 from 源地址。數(shù)據(jù)來(lái)源位于用戶(hù)空間的緩沖區(qū)由應(yīng)用層傳入param3 n 要拷貝的字節(jié)數(shù)返回值0n個(gè)字節(jié)完全拷貝0:未能成功拷貝的剩余字節(jié)數(shù)函數(shù)copy_to_user(void __user *to, const void *from, unsigned long n)函數(shù)作用將內(nèi)核層數(shù)據(jù)寫(xiě)入用戶(hù)空間函數(shù)參數(shù)param1 to 目的地址。數(shù)據(jù)拷貝的目的地位于用戶(hù)空間的緩沖區(qū)由應(yīng)用層提供param2 from 源地址。數(shù)據(jù)來(lái)源位于內(nèi)核空間的緩沖區(qū)param2 n 要拷貝的字節(jié)數(shù)返回值0n個(gè)字節(jié)完全拷貝0:未能成功拷貝的剩余字節(jié)數(shù)當(dāng)應(yīng)用層運(yùn)行read(fd,buf,sizeof(buf)); printf(app layer read data : %s ,buf);驅(qū)動(dòng)層會(huì)運(yùn)行static ssize_t misc_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { char kbuf[64]嵌入式linux驅(qū)動(dòng); printk(misc device is read:hello misc read ); if(copy_to_user(buf,kbuf,sizeof(kbuf))!0) { printk(misc device copy to user error ); return -1; } return 0; }read函數(shù)中的buf是應(yīng)用層的緩存地址傳遞給驅(qū)動(dòng)層的misc_read中buf通過(guò)copy_to_user將kbuf中的內(nèi)容拷貝到buf中在傳遞到應(yīng)用層最終在應(yīng)用層printf輸出
版權(quán)聲明: 本文來(lái)自互聯(lián)網(wǎng)用戶(hù)投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)聯(lián)系我們進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

杭州網(wǎng)站公司網(wǎng)站 免費(fèi) 托管運(yùn)營(yíng)

杭州網(wǎng)站公司,網(wǎng)站 免費(fèi) 托管運(yùn)營(yíng),哪些國(guó)家網(wǎng)站無(wú)須備案,wordpress首頁(yè)導(dǎo)航從零搞定 CP2102#xff1a;Windows 下 USB 轉(zhuǎn)串口通信的完整實(shí)戰(zhàn)指南 你有沒(méi)有遇到過(guò)這樣的場(chǎng)景

2026/01/21 17:13:01

廣西做網(wǎng)站建設(shè)的公司廣安seo優(yōu)化

廣西做網(wǎng)站建設(shè)的公司,廣安seo優(yōu)化,網(wǎng)站備案 時(shí)間,域名注冊(cè)推薦第一章#xff1a;從崩潰到自愈只需200ms#xff1a;Open-AutoGLM高可用設(shè)計(jì)背后的黑科技解析在分布式AI推理系統(tǒng)中#

2026/01/21 18:48:01

佛山行業(yè)網(wǎng)站設(shè)計(jì)建站什么程序好

佛山行業(yè)網(wǎng)站設(shè)計(jì),建站什么程序好,什么是建設(shè)網(wǎng)站的主題,網(wǎng)架公司名字推薦大全ComfyUI BrushNet圖像編輯完全指南#xff1a;5大核心功能深度解析 【免費(fèi)下載鏈接】ComfyUI-Brus

2026/01/21 16:14:01