linux驅動支援多個裝置
1.註冊裝置
insmod driverName.ko
//主要是呼叫xxx_init()函式向chrdev中註冊裝置號(代表一類裝置),和將要使用的裝置數量
// xxx_init()中利用函式結構體,file_operations初始化cdev,然後把cdev和註冊的裝置號關聯。
// 利用 cat /proc/devices 可以看到主裝置號,和裝置號。
2.建立裝置檔案
mknod /dev/xxxdevice c 260 1
mknod /dev/xxxdevice c 260 2
//主要是建立多個裝置檔案,制定檔名稱,裝置型別,主裝置好,次裝置號
3.TODO:
// 區分裝置
4. code 例項(一)
static mem_major = MEMDEV_MAJOR; module_param(mem_major, int, S_IRUGO); struct mem_dev *mem_devp; /*裝置結構體指標*/ struct cdev cdev; /*檔案開啟函式*/ int mem_open(struct inode *inode, struct file *filp) { struct mem_dev *dev; /*獲取次裝置號*/ int num = MINOR(inode->i_rdev); if (num >= MEMDEV_NR_DEVS) return -ENODEV; dev = &mem_devp[num]; /*將裝置描述結構指標賦值給檔案私有資料指標*/ filp->private_data = dev; return 0; } /*檔案釋放函式*/ int mem_release(struct inode *inode, struct file *filp) { return 0; } /*讀函式*/ static ssize_t mem_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos) { unsigned long p = *ppos; /*記錄檔案指標偏移位置*/ unsigned int count = size; /*記錄需要讀取的位元組數*/ int ret = 0; /*返回值*/ struct mem_dev *dev = filp->private_data; /*獲得裝置結構體指標*/ /*判斷讀位置是否有效*/ if (p >= MEMDEV_SIZE) /*要讀取的偏移大於裝置的記憶體空間*/ return 0; if (count > MEMDEV_SIZE - p) /*要讀取的位元組大於裝置的記憶體空間*/ count = MEMDEV_SIZE - p; /*讀資料到使用者空間:核心空間->使用者空間交換資料*/ if (copy_to_user(buf, (void*)(dev->data + p), count)) { ret = - EFAULT; } else { *ppos += count; ret = count; printk(KERN_INFO "read %d bytes(s) from %d\n", count, p); } return ret; } /*寫函式*/ static ssize_t mem_write(struct file *filp, const char __user *buf, size_t size, loff_t *ppos) { unsigned long p = *ppos; unsigned int count = size; int ret = 0; struct mem_dev *dev = filp->private_data; /*獲得裝置結構體指標*/ /*分析和獲取有效的寫長度*/ if (p >= MEMDEV_SIZE) return 0; if (count > MEMDEV_SIZE - p) /*要寫入的位元組大於裝置的記憶體空間*/ count = MEMDEV_SIZE - p; /*從使用者空間寫入資料*/ if (copy_from_user(dev->data + p, buf, count)) ret = - EFAULT; else { *ppos += count; /*增加偏移位置*/ ret = count; /*返回實際的寫入位元組數*/ printk(KERN_INFO "written %d bytes(s) from %d\n", count, p); } return ret; } /* seek檔案定位函式 */ static loff_t mem_llseek(struct file *filp, loff_t offset, int whence) { loff_t newpos; switch(whence) { case 0: /* SEEK_SET */ /*相對檔案開始位置偏移*/ newpos = offset; /*更新檔案指標位置*/ break; case 1: /* SEEK_CUR */ newpos = filp->f_pos + offset; break; case 2: /* SEEK_END */ newpos = MEMDEV_SIZE -1 + offset; break; default: /* can't happen */ return -EINVAL; } if ((newpos<0) || (newpos>MEMDEV_SIZE)) return -EINVAL; filp->f_pos = newpos; return newpos; } /*檔案操作結構體*/ static const struct file_operations mem_fops = { .owner = THIS_MODULE, .llseek = mem_llseek, .read = mem_read, .write = mem_write, .open = mem_open, .release = mem_release, }; /*裝置驅動模組載入函式*/ static int memdev_init(void) { int result; int i; dev_t devno = MKDEV(mem_major, 0); /* 申請裝置號,當xxx_major不為0時,表示靜態指定;當為0時,表示動態申請*/ /* 靜態申請裝置號*/ if (mem_major) result = register_chrdev_region(devno, 2, "memdev"); else /* 動態分配裝置號 */ { result = alloc_chrdev_region(&devno, 0, 2, "memdev"); mem_major = MAJOR(devno); /*獲得申請的主裝置號*/ } if (result < 0) return result; /*初始化cdev結構,並傳遞file_operations結構指標*/ cdev_init(&cdev, &mem_fops); cdev.owner = THIS_MODULE; /*指定所屬模組*/ cdev.ops = &mem_fops; /* 註冊字元裝置 */ cdev_add(&cdev, MKDEV(mem_major, 0), MEMDEV_NR_DEVS); /* 為裝置描述結構分配記憶體,此處是重點(1)*/ mem_devp = kmalloc(MEMDEV_NR_DEVS * sizeof(struct mem_dev), GFP_KERNEL); if (!mem_devp) /*申請失敗*/ { result = - ENOMEM; goto fail_malloc; } memset(mem_devp, 0, sizeof(struct mem_dev)); /*為裝置分配記憶體*/ for (i=0; i < MEMDEV_NR_DEVS; i++) { mem_devp[i].size = MEMDEV_SIZE; mem_devp[i].data = kmalloc(MEMDEV_SIZE, GFP_KERNEL); memset(mem_devp[i].data, 0, MEMDEV_SIZE); } return 0; fail_malloc: unregister_chrdev_region(devno, 1); return result; } /*模組解除安裝函式*/ static void memdev_exit(void) { cdev_del(&cdev); /*登出裝置*/ kfree(mem_devp); /*釋放裝置結構體記憶體*/ unregister_chrdev_region(MKDEV(mem_major, 0), 2); /*釋放裝置號*/ } MODULE_AUTHOR("David Xie"); MODULE_LICENSE("GPL"); module_init(memdev_init); module_exit(memdev_exit);
#include <stdio.h> int main() { FILE *fp0 = NULL; char Buf[4096]; /*初始化Buf*/ strcpy(Buf,"Mem is char dev!"); printf("BUF: %s\n",Buf); /*開啟裝置檔案*/ fp0 = fopen("/dev/memdev0","r+"); if (fp0 == NULL) { printf("Open Memdev0 Error!\n"); return -1; } /*寫入裝置*/ fwrite(Buf, sizeof(Buf), 1, fp0); /*重新定位檔案位置(思考沒有該指令,會有何後果)*/ fseek(fp0,0,SEEK_SET); /*清除Buf*/ strcpy(Buf,"Buf is NULL!"); printf("BUF: %s\n",Buf); /*讀出裝置*/ fread(Buf, sizeof(Buf), 1, fp0); /*檢測結果*/ printf("BUF: %s\n",Buf); return 0; }
相關推薦
linux驅動支援多個裝置
1.註冊裝置 insmod driverName.ko //主要是呼叫xxx_init()函式向chrdev中註冊裝置號(代表一類裝置),和將要使用的裝置數量 // xxx_init()中利用函式結構體,file_operations初始化cdev,然後把cdev和註冊的
linux 驅動建立多個裝置
linux 驅動中建立一個裝置的例子很多,以下例子是建立多個字元裝置的例子,包括驅動部分和測試部分 驅動部分包括 globalmem.c Makefile兩個檔案: globalmem.c file: #include <linux/module.h>
一個驅動支援多個裝置再usb子系統、input子系統、platform、iic子系統 中的實現
platform 你寫的驅動你應該知道它適用與哪些裝置吧,如果你想支援一個裝置,那麼你就構造一個 usb_device_id (USB)、i2c_device_id (IIC)、platform_device_id(Platform)放到對應驅動的id_
ZYNQ Linux驅動開發——第一個字元裝置驅動
硬體平臺:XCZ7020 CLG484-1 完全適配Zedboard 開發環境:Widows下Vivado 2016.2 、 SDK2016.2 、 Linux機器:debin 目的:操作板載的LED燈LD9,受PS部分的MIO7控制 linux裝置驅
一個驅動程式對應多個裝置
#include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/fs.h> #include <linux/cdev.h> #in
程式碼:編寫一個簡單的字元裝置驅動——建立多個同類型裝置
編寫同類型多個裝置字元驅動應注意一下幾個問題: 1、申請裝置號alloc_chrdev_region時須指定次裝置號範圍; 2、動態分配裝置空間時同時分配NUM個裝置的空間; 3、根據次裝置號和統一的主裝置號生成針對單個裝置的devno,然後完成cdev_add註冊; 4、
linux——alsa中多個音效卡裝置時開啟某一指定音效卡的PCM裝置
前言 最近除錯板子上的3個ADAU1761音訊介面,使用pocketsphinx語音庫呼叫alsa庫的API介面開啟指定的Mic進行錄入語音時出現異常,預設情況只能開啟第一個ADAU1761音訊介面,想開啟第二個或第三個ADAU1761音訊介面時卻出現錯誤
Windows驅動開發WDM (11)- 多個裝置物件(同一個驅動)
通常在WDM驅動的AddDevice裡面只會呼叫一次IoCreateDevice建立一個裝置物件。其實我們也可以呼叫多次IoCreateDevice來建立多個裝置物件。當驅動呼叫IoCreateDevice成功後,驅動物件DriverObject的DeviceObject指
linux驅動開發之一個真正的裝置驅動需要一些什麼元素(裝置號,操作方法)
1,需要一個裝置號(重點看下面的程式碼) 因為核心中有很多的裝置驅動,所以需要一個裝置號id來進行區分 裝置號分成兩個部分: 主裝置號:某一
Linux下nginx+多個Tomcat負載均衡的實現
java 負載 均衡 bootstra 火墻 瀏覽器 startup 顯示 tomcat的配置 由於項目需要,共創建了10個Tomcat端,由nginx負責轉發。9個Tomcat端口分別是8080,11000,12000,13000,14000,15000,16000,17
Linux下SVN+多個Tomcat自動部署
mod .html 部署 update語句 hooks 參考 eba bsp auth 項目中都是jsp開發,所以用到Tomcat。 在我文章中也寫過多個Tomcat 的部署,具體可以參考:http://www.cnblogs.com/magmell/p/7045193.h
如何將Linux系統的多個目錄及文件備份並壓縮到一個文件,以方面保持和傳遞?
如何將linux系統的多個目錄及文件備份並壓縮到一個文件 以方面保持和傳遞? 1.備份Linux系統 window系統在運行狀態下,我們是無法將文件拷貝出來的,那麽在Linux下呢?她的文件結構式一種樹型結構。而且在系統運行的時候我們可以進行打包所有系統文件。特別要說的在Linux的root賬戶具備
linux nginx配置多個網站
vhost host 編輯 dir OS nginx 文件夾 CA nginx配置 1.把網站配置在hom目錄下,需要建立wwwroot目錄 1.在nginx.conf 增加inlcude代碼,然後創建一個vhost,最後配置個xxx.com.conf //編輯n
Linux 下 svn 多個項目多用戶分配
usr osi 匿名 win 註意 () 禁止訪問 缺省值 管理 安裝步驟如下: 1、yum install subversion 2、輸入rpm -ql subversion查看安裝位置,如下圖: 輸入 svn –help可以查看svn的使用方法 需求 開發
Linux上配置多個tomcat的配置修改(修改tomcat配置)
1、修改環境變數 #vi /etc/profile ####### 工程1 tomcat1####### export CATALINA_BASE=/data/server/tomcat export CATALINA_HOME=$CA
Spring環境下MyBatis支援多個Datasource參考實現
需求背景 最近接到一個專案,需要改造一個老的系統。該老系統以Oracle為儲存,巨量的PL/SQL程式碼實現業務程式碼,C實現Socket Server,作為Client和PL/SQL的橋樑。不出所料,該老系統最大的問題是PL/SQL程式碼量巨大(上萬的Procedure好幾個),且毫無
Appium自動化測試-同時執行多個裝置
在之前的文章中,學習了Appium的基本使用,可以參考Appium自動化測試-入門,我們接著學習一下在一臺電腦中同時執行多裝置的方法,這樣在測試多種裝置的時候,可以直接在本地完成。 一、啟動Appium 一個Appium伺服器只能連線一個測試裝置進行測試,如果要在一臺電腦上同時測
Ubuntu16.04配置Apache支援多個站點
怎樣在一個Ubuntu的機器上(虛擬機器)配置Apache支援多個網站呢? 比如你有一臺獨立的Ubuntu虛擬機器,配有一個外網的IP(45.46.47.48),並且註冊了兩個域名AAA.com和BBB.com,將這兩個域名DNS解析到你虛機的IP地址。假設你已經安裝好了Apache,一
Linux下部署多個Tomcat端
由於專案需要,共建立了10個Tomcat端,由nginx負責轉發。10個Tomcat埠分別是8080,11000,12000,13000,14000,15000,16000,17000,18000,19000. nginx配置:upstream Tomcat { server xxx.
iReport列印(支援多個模版交叉列印)
//根據實際情況從資料庫中獲取資料 List<User> userList = new ArrayList<>(); User printBean = null; JasperPrint jasperPrint = n