linux 驅動建立多個裝置
linux 驅動中建立一個裝置的例子很多,以下例子是建立多個字元裝置的例子,包括驅動部分和測試部分
驅動部分包括 globalmem.c Makefile兩個檔案:
globalmem.c file:
#include <linux/module.h> #include <linux/types.h> #include <linux/fs.h> #include <linux/errno.h> #include <linux/mm.h> #include <linux/sched.h> #include <linux/init.h> #include <linux/cdev.h> #include <linux/device.h> #include <linux/slab.h> #include <asm/io.h> #include <asm/system.h> #include <asm/uaccess.h> #define GLOBALMEM_SIZE 0x1000 //global memory size 4KB #define MEM_CLEAR 0x1 //clear all the mem #define GLOBALMEM_MAJOR 350 //globalmem major number static struct class* globalmem_class0; static struct class* globalmem_class1; static int globalmem_major = GLOBALMEM_MAJOR; struct globalmem_dev{ struct cdev cdev; //cdev struct unsigned char mem[GLOBALMEM_SIZE]; //global mem }; struct globalmem_dev* globalmem_devp; void globalmem_setup_cdev(struct globalmem_dev * dev, int index); int globalmem_init(void){ int result; dev_t devno = MKDEV(globalmem_major, 0); if(globalmem_major){ result = register_chrdev_region(devno, 2, "globalmem"); }else{ result = alloc_chrdev_region(&devno, 0, 2, "globalmem"); globalmem_major = MAJOR(devno); } if(result < 0){ return result; } globalmem_devp = kmalloc(2 * sizeof(struct globalmem_dev), GFP_KERNEL); if(!globalmem_devp){ result = -ENOMEM; goto fail_malloc; } memset(globalmem_devp, 0, 2 * sizeof(struct globalmem_dev)); globalmem_setup_cdev(&globalmem_devp[0], 0); globalmem_setup_cdev(&globalmem_devp[1], 1); globalmem_class0 = class_create(THIS_MODULE, "globalmem0"); //create file under /sys/class device_create(globalmem_class0, NULL, MKDEV(globalmem_major, 0), NULL, "globalmem_0"); //globalmem_0 is the name under /dev/ globalmem_class1 = class_create(THIS_MODULE, "globalmem1"); //create file under /sys/class device_create(globalmem_class1, NULL, MKDEV(globalmem_major, 1), NULL, "globalmem_1"); //globalmem_1 is the name under /dev/ return 0; fail_malloc: unregister_chrdev_region(devno, 1); return result; } void globalmem_exit(void){ cdev_del(&(globalmem_devp[0].cdev)); cdev_del(&(globalmem_devp[1].cdev)); unregister_chrdev_region(MKDEV(globalmem_major, 0), 2); //unregister device kfree(globalmem_devp); device_destroy(globalmem_class0, MKDEV(globalmem_major, 0)); class_destroy(globalmem_class0); device_destroy(globalmem_class1, MKDEV(globalmem_major, 1)); class_destroy(globalmem_class1); } static int globalmem_open_0(struct inode* inode, struct file* filp){ int minor = iminor(inode); struct globalmem_dev* dev; dev = container_of(inode->i_cdev, struct globalmem_dev, cdev); filp->private_data = dev; printk(KERN_INFO "in kernel function: %s, minor = %d", __func__, minor); return 0; } static int globalmem_open_1(struct inode* inode, struct file* filp){ int minor = iminor(inode); struct globalmem_dev* dev; dev = container_of(inode->i_cdev, struct globalmem_dev, cdev); filp->private_data = dev; printk(KERN_INFO "in kernel function: %s, minor = %d", __func__, minor); return 0; } static ssize_t globalmem_read_0(struct file* filp, char __user * buf, size_t count, loff_t * ppos){ int ret = 0; struct globalmem_dev * dev = filp->private_data; printk(KERN_INFO "in kernel function: %s", __func__); ret = copy_to_user(buf, dev->mem, count); return 0; } static ssize_t globalmem_read_1(struct file* filp, char __user * buf, size_t count, loff_t * ppos){ int ret = 0; struct globalmem_dev * dev = filp->private_data; printk(KERN_INFO "in kernel function: %s", __func__); ret = copy_to_user(buf, dev->mem, count); return 0; } static ssize_t globalmem_write_0(struct file* filp, const char __user * buf, size_t count, loff_t * ppos){ int ret = 0; struct globalmem_dev * dev = filp->private_data; ret = copy_from_user(dev->mem, buf, count); dev->mem[count] = 0; printk(KERN_INFO "in kernel function: %s, content = %s", __func__, dev->mem); return 0; } static ssize_t globalmem_write_1(struct file* filp, const char __user * buf, size_t count, loff_t * ppos){ int ret = 0; struct globalmem_dev * dev = filp->private_data; ret = copy_from_user(dev->mem, buf, count); dev->mem[count] = 0; printk(KERN_INFO "in kernel function: %s, content = %s", __func__, dev->mem); return 0; } static loff_t globalmem_llseek_0(struct file* filp, loff_t offset, int orig){ printk(KERN_INFO "in kernel function: %s", __func__); return 0; } static loff_t globalmem_llseek_1(struct file* filp, loff_t offset, int orig){ printk(KERN_INFO "in kernel function: %s", __func__); return 0; } static long globalmem_ioctl_0(struct file * filp, unsigned int cmd, unsigned long arg){ struct globalmem_dev * dev = filp->private_data; memset(dev->mem, 0, sizeof(dev->mem)/sizeof(dev->mem[0])); printk(KERN_INFO "in kernel_function: %s", __func__); return 0; } static long globalmem_ioctl_1(struct file * filp, unsigned int cmd, unsigned long arg){ struct globalmem_dev * dev = filp->private_data; memset(dev->mem, 0, sizeof(dev->mem)/sizeof(dev->mem[0])); printk(KERN_INFO "in kernel_function: %s", __func__); return 0; } static const struct file_operations globalmem_fops[] = { [0] = { .owner = THIS_MODULE, .open = globalmem_open_0, .llseek = globalmem_llseek_0, .read = globalmem_read_0, .write = globalmem_write_0, .compat_ioctl = globalmem_ioctl_0, }, [1] = { .owner = THIS_MODULE, .open = globalmem_open_1, .llseek = globalmem_llseek_1, .read = globalmem_read_1, .write = globalmem_write_1, .compat_ioctl = globalmem_ioctl_1, } }; void globalmem_setup_cdev(struct globalmem_dev* dev, int index){ int err; int devno = MKDEV(globalmem_major, index); cdev_init(&dev->cdev, &globalmem_fops[index]); dev->cdev.owner = THIS_MODULE; err = cdev_add(&dev->cdev, devno, 1); if(err) printk(KERN_NOTICE "Error %d adding globalmem", err); } module_init(globalmem_init); module_exit(globalmem_exit); MODULE_LICENSE("Dual BSD/GPL"); MODULE_AUTHOR("XXX"); MODULE_DESCRIPTION("Global mem test"); 1,1 Top
Makefile file:
mymodule-objs := globalmem.o obj-m := globalmem.o PWD:=$(shell pwd) KERNEL_DIR=/sziauto/android_src/m6_lch_1280x800/svn_m6_jb42_0403/branches/branches-LCH/out/target/product/T37lchaudi/obj/KERNEL_OBJ/ CROSS_COMPILE=/sziauto/android_src/m6_lch_1280x800/svn_m6_jb42_0403/branches/branches-LCH/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin PWD:=$(shell pwd) all: make ARCH=arm $(CROSS_COMPILE) -C $(KERNEL_DIR) M=$(PWD) modules clean: rm -rf *.o modules.order *.ko Module.symvers *.mod.c
測試部分包括 Android.mk driver_test.c
driver_test.c :
#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #define BUFFER_LEN 100 int main(int argc, char* argv[]){ int fd = -1; char cmd = 0; char param[BUFFER_LEN] = {0}; char content[BUFFER_LEN] = {0}; const char* PATH0 = "/dev/globalmem_0"; const char* PATH1 = "/dev/globalmem_1"; while(1){ printf("\n"); printf("type o|O to open file\n"); printf("type r|R to exec read\n"); printf("type w|W to exec write\n"); printf("type i|I to exec ioctl\n"); printf("type q|Q to quit\n"); printf("input your cmd: "); memset(param, 0, sizeof(param)/sizeof(param[0])); fgets(param, BUFFER_LEN, stdin); if(param[0] == 'o' || param[0] == 'O'){ printf("input the path you want to open\n"); printf("type 0 to open /dev/globalmem_0, 1 to open /dev/globalmem_1:"); memset(param, 0, sizeof(param)/sizeof(param[0])); fgets(param, BUFFER_LEN, stdin); if(param[0] == '0'){ if(fd > 0){ close(fd); } fd = open(PATH0, O_RDWR); }else if(param[0] == '1'){ if(fd > 0){ close(fd); } fd = open(PATH1, O_RDWR); } }else if(param[0] == 'r' || param[0] == 'R'){ read(fd, content, BUFFER_LEN); printf("\ncontent read from kernel is: %s\n", content); }else if(param[0] == 'w' || param[0] == 'W'){ printf("exec write cmd\n"); memset(param, 0, sizeof(param)/sizeof(param[0])); printf("input your write content: "); fgets(param, BUFFER_LEN, stdin); write(fd, param, strlen(param)); }else if(param[0] == 'i' || param[0] == 'I'){ printf("exec ioctl cmd\n"); ioctl(fd, 1, NULL); }else if(param[0] == 'q' || param[0] == 'Q'){ printf("will quit...\n"); close(fd); fd = -1; break; } } return 0; }
Android.mk
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
driver_test.c
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := driver_test
include $(BUILD_EXECUTABLE)
相關推薦
linux 驅動建立多個裝置
linux 驅動中建立一個裝置的例子很多,以下例子是建立多個字元裝置的例子,包括驅動部分和測試部分 驅動部分包括 globalmem.c Makefile兩個檔案: globalmem.c file: #include <linux/module.h>
linux驅動支援多個裝置
1.註冊裝置 insmod driverName.ko //主要是呼叫xxx_init()函式向chrdev中註冊裝置號(代表一類裝置),和將要使用的裝置數量 // xxx_init()中利用函式結構體,file_operations初始化cdev,然後把cdev和註冊的
程式碼:編寫一個簡單的字元裝置驅動——建立多個同類型裝置
編寫同類型多個裝置字元驅動應注意一下幾個問題: 1、申請裝置號alloc_chrdev_region時須指定次裝置號範圍; 2、動態分配裝置空間時同時分配NUM個裝置的空間; 3、根據次裝置號和統一的主裝置號生成針對單個裝置的devno,然後完成cdev_add註冊; 4、
一個驅動支援多個裝置再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
Linux中通過fork()同時建立多個程序
1、使用系統呼叫fork()建立三個子程序;2、各個子程序顯示和輸出一些提示資訊和自己的程序識別符號;3、父程序顯示自己的程序ID和一些提示資訊,然後呼叫waitpid()等待多個子程序結束,並在子程序結束後顯示輸出提示資訊表示程式結束。#include <stdio.
Linux中apache建立多個虛擬主機(訪問多個站點目錄)
因為公司公用一臺開發機,apache服務是公用的,全域性的document是預設的,不便於改動,只能建立虛擬機器主機及埠來通過http訪問自己的站點目錄。 進入etc/httpd/httpd.conf配置檔案: 1.加入listen埠: Listen 81 2
linux——alsa中多個音效卡裝置時開啟某一指定音效卡的PCM裝置
前言 最近除錯板子上的3個ADAU1761音訊介面,使用pocketsphinx語音庫呼叫alsa庫的API介面開啟指定的Mic進行錄入語音時出現異常,預設情況只能開啟第一個ADAU1761音訊介面,想開啟第二個或第三個ADAU1761音訊介面時卻出現錯誤
Windows驅動開發WDM (11)- 多個裝置物件(同一個驅動)
通常在WDM驅動的AddDevice裡面只會呼叫一次IoCreateDevice建立一個裝置物件。其實我們也可以呼叫多次IoCreateDevice來建立多個裝置物件。當驅動呼叫IoCreateDevice成功後,驅動物件DriverObject的DeviceObject指
linux驅動開發之一個真正的裝置驅動需要一些什麼元素(裝置號,操作方法)
1,需要一個裝置號(重點看下面的程式碼) 因為核心中有很多的裝置驅動,所以需要一個裝置號id來進行區分 裝置號分成兩個部分: 主裝置號:某一
TCP server 為什麽一個端口可以建立多個連接?
tab 建立 傳輸 grep not ide 技術分享 什麽 circle https://segmentfault.com/q/1010000003101541 如果是tcp client用同一個本地端口去連不同的兩個服務器ip,連第二個時就會提示端口已被占用。但服務
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賬戶具備
Exchange Server 2016管理系列課件45.DAG部署之建立多個DAG組
Exchange Server 郵件服務器 DAG管理 多DAG管理 方式方法是一樣的,比如我建了三個DAG組,對應的有三個DAG的計算機名稱。每個DAG群集都對應有自己的IP到故障轉移群集管理器中,可以看到DAG相關的群集資源。註意:群集管理器裏面的東西看看可以,但是不建議在群集管理器中隨意
Tomcat建立多個應用(Web Server),多個主機,多個站點的方法
-h 制作 ctp 變量 details real def fonts lin https://blog.csdn.net/chungle2011/article/details/52317433 http://piperzero.iteye.com/blog/147577
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