1. 程式人生 > >Linux 字元裝置驅動開發--記憶體讀寫操作

Linux 字元裝置驅動開發--記憶體讀寫操作

學習Linux的累計時間已經有兩年多了,工作關係,學習的過程總是斷斷續續的,現在整理一下,下面要分享的是一個簡單的linux驅動程式,將記憶體當作一個虛擬的裝置去讀寫,沒有什麼實際的用處,像hello wold!程式一樣,我們簡單體會一下linux驅動程式的特點,Linux裝置驅動程式開發第三版是一本不錯的參考書,講的比較詳細,值得入手,話不多說了,簡單講一下步驟:

1、我電腦上的Linux系統是Ubuntu14.04。

2、 新建一個duxie.c檔案作為驅動程式原始檔,一個ce.c作為應用層的測試程式,一個Makefile檔案用來編譯驅動程式產生*.ko檔案。

3、下面貼出程式碼:

duxie.c 原始碼如下:

/**************************************************************
    duxie.c  
    It can be compiled for x86 PC #include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h> /* printk() */
    author:
    date:  
***************************************************************/
 
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>   /* printk() */
 
#include <linux/errno.h>    /* error codes */
#include <linux/poll.h>    /* COPY_TO_USER */
 
 
#define DEVICE_NAME    "rwd"
 
static int rwdMajor = 0;
static int MAX_BUF_LEN=1024;
static char drv_buf[1024];
static int WRI_LENGTH=0;
 
 
 
/*************************************************************************************/
static ssize_t  dx_write(struct file *file, const char __user *buffer, size_t count, loff_t * ppos)
{  
    if(count > MAX_BUF_LEN)count = MAX_BUF_LEN;
    copy_from_user(drv_buf , buffer, count);
    WRI_LENGTH = count;
    printk("user write data to driver\n");
    return count;
}
/*************************************************************************************/
static ssize_t  dx_read(struct file *filp, char __user *buffer, size_t count, loff_t *ppos)
{
    if(count > MAX_BUF_LEN)
        count=MAX_BUF_LEN;
    copy_to_user(buffer, drv_buf,count);
    printk("user read data from driver\n");
    return count;
}
 
static int dx_open(struct inode *inode, struct file *filp)
{
    printk("device open sucess!\n");
    return 0;
}
/*************************************************************************************/
static int  dx_release(struct inode *inode, struct file *filp)
{
    printk("device release\n");
    return 0;
}
 
/*************************************************************************************/
static struct file_operations pxa270_fops = {
    owner:    THIS_MODULE,
    write:    dx_write,    
    read:    dx_read,    
    open:    dx_open,
    release:dx_release,
};
/*************************************************************************************/
 
static int __init dx_init(void)
{
 int ret;
        ret = register_chrdev(0, DEVICE_NAME, &pxa270_fops);
    if (ret < 0) {
        printk(DEVICE_NAME " can't get major number\n");
        return ret;
    }
    rwdMajor=ret;
 
    printk("dx module major number is %d\n", ret);
    return 0;
}
 
/*************************************************************************************/
 
void __exit  dx_exit(void)
{
  unregister_chrdev(rwdMajor, DEVICE_NAME);
}
module_exit(dx_exit);
module_init(dx_init);
MODULE_LICENSE("GPL");

Makefile的原始碼如下:

ifneq ($(KERNELRELEASE),)
obj-m := duxie.o
else
KDIR := /usr/src/linux-headers-3.19.0-31-generic
all:
    make -C $(KDIR) M=$(PWD) modules   
clean:
    rm -f *.ko *.o *.mod.o *.mod.c *.symvers  modul*
endif

應用層的測試程式ce.c原始碼如下:


#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include<string.h>


void showbuf(char *buf);
int MAX_LEN=32;

int main()
{
    int fd;
    int i;
    char buf1[255];
    char buf2[255];
    
    printf("please input a string:\n");
    scanf("%s",buf1);
        MAX_LEN=strlen(buf1);

    fd=open("/dev/rwd",O_RDWR);
    if(fd < 0){
        printf("####rwd  device open fail####\n");
        return (-1);
    }
    printf("write %d bytes data to /dev/rwd \n",MAX_LEN);
    printf("%s\n",buf1);

    write(fd,buf1,MAX_LEN);

    printf("Read %d bytes data from /dev/rwd \n",MAX_LEN);
    read(fd,buf2,MAX_LEN);
    printf("%s\n",buf2);
    
    close(fd);
    return 0;

}

具體實現的功能可以自己看一下。

4、 編譯生成duxie.ko檔案,用insmod duxie.ko載入驅動程式。

5、檢視主裝置號,可以用cat /proc/devices | grep rwd 檢視主裝置號。

6、該驅動程式需要手動註冊,可以用mknod /dev/rwd 裝置型別 主裝置號 次裝置號 (例如 mknod /dev/rwd c 248 0)來實現。

7,編譯執行ce.c,輸入一串字串,輸入什麼就輸出什麼,這樣就完成了整個驅動程式的編寫、編譯、安裝及測試工作。


相關推薦

Linux 字元裝置驅動開發--記憶體操作

學習Linux的累計時間已經有兩年多了,工作關係,學習的過程總是斷斷續續的,現在整理一下,下面要分享的是一個簡單的linux驅動程式,將記憶體當作一個虛擬的裝置去讀寫,沒有什麼實際的用處,像hello wold!程式一樣,我們簡單體會一下linux驅動程式的特點,Linux

linux字元裝置驅動開發模板及Makefile

#include <linux/init.h> #include <linux/module.h> #include <linux/fs.h> #include <linux/cdev.h> #include <linux/device.h> //

從零開始linux字元裝置驅動程式(一)(基於友善之臂tiny4412開發板)

從這篇博文開始,我將開始手把手教會大家寫linux裝置驅動程式這是開篇,如何來寫第一個字元裝置驅動程式。首先,寫一個最簡單的字元裝置驅動程式需要什麼?或者說我們需要了解什麼?1、每一個字元裝置至少需要有一個裝置號2、裝置號 = 主裝置號 + 次裝置號3、同一類裝置的主裝置號一

Linux字元裝置驅動模型--字元裝置的註冊

當我們編寫字元裝置驅動程式的時候,在進行字元裝置物件cdev的分配、初始化,裝置號的註冊這些初始化階段之後,就可以將它加入到系統中,這樣才能使用這個字元裝置。將一個字元裝置加入到系統中呼叫的函式時cdev_add,核心原始碼如下: int cdev_add(struct cdev *

Linux 字元裝置驅動結構(二)—— 自動建立裝置節點

      上一篇我們介紹到建立裝置檔案的方法,利用cat /proc/devices檢視申請到的裝置名,裝置號。 第一種是使用mknod手工建立:mknod filename type major minor 第二種是自動建立裝置節點:利用u

Linux 字元裝置驅動結構(一)—— cdev 結構體、裝置號相關知識解析

一、字元裝置基礎知識 1、裝置驅動分類       linux系統將裝置分為3類:字元裝置、塊裝置、網路裝置。使用驅動程式: 字元裝置:是指只能一個位元組一個位元組讀寫的裝置,不能隨機讀取裝置記憶體中的某一資料,讀取資料需要按照先後資料。

Linux字元裝置驅動註冊三種方法以及核心分析

       Linux驅動是使用者訪問底層硬體的橋樑,驅動有可以簡單分成三類:字元裝置、塊裝置、網路裝置。其中最多的是字元裝置,其中字元裝置的註冊方法主要有三種:雜項設備註冊、早期字元設備註冊、標準字元設備註冊。以及詳細介紹各類方法註冊。 開發環境: PC:WMwork

linux字元裝置驅動模型

一.雜項裝置驅動模型 雜項的主裝置號固定為10,只有255個次裝置號。可以直接生成驅動核心。 1.需要確定每個模型都會用到的檔案操作方法集合指標 2.確定核心的結構體 static struct miscdevice abc 確定三個引數,第一個為次裝置號,第二個是次裝

Linux字元裝置驅動

一、字元裝置基礎 字元裝置:是指只能一個位元組一個位元組進行讀寫操作的裝置,不能隨機讀取裝置中的某一資料、讀取資料要按照先後資料。字元裝置是面向流的裝置,常見的字元裝置有滑鼠、鍵盤、串列埠、控制檯和LED等。 一般每個字元裝置或者塊裝置都會在/dev目錄(可以是任意目錄,這樣是為了統一)下對應一個裝置檔案

1--linux字元裝置驅動

1. 編寫一個簡單的字元裝置框架 *****hello.c***** #include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #include <

Linux 網路裝置驅動開發(三) —— 網路裝置驅動基本原理和框架

一、協議棧層次對比 二、Linux網路子系統     Linux網路子系統的頂部是系統呼叫介面層。它為使用者空間提供的應用程式提供了一種訪問核心網路子系統的方法(socket)。位於其下面是一個協議無關層,它提供一種通用的方法來使用傳輸層協議。然後是具體協議的實現,在Lin

Linux 字元裝置驅動結構(三)—— file、inode結構體及chardevs陣列等相關知識解析

       先看下面這張圖,這是Linux 中虛擬檔案系統、一般的裝置檔案與裝置驅動程式值間的函式呼叫關係;         上面這張圖展現了一個應用程式呼叫字元裝置驅動的過程, 在裝置驅動程式的設計中,一般而言,會關心 file 和 inode 這兩個結構體  

linux字元裝置驅動程式scull例項

這個例子還是比較完整的講述了字元驅動開發的過程,尤其字元驅動程式的設計流程,包括測試在內。 【1.系統環境】 該驅動程式在UBUNTU10.04LTS編譯通過,系統核心為linux-2.6.32-24(可使用uname -r 命令來檢視當前核心的版本號) 由於安裝UBUNTU10.04LTS時,沒有安裝LI

深入理解Linux字元裝置驅動

文章從上層應用訪問字元裝置驅動開始,一步步地深入分析Linux字元裝置的軟體層次、組成框架和互動、如何編寫驅動、裝置檔案的建立和mdev原理,對Linux字元裝置驅動有全面的講解。本文整合之前發表的《L

linux字元裝置驅動模板(新標準)

//////////////gpio驅動模板//////////////////////////////static int major = 0;static void gpio_setup_cdev(struct cdev *dev, int minor, struct f

Linux字元裝置驅動程式的一個簡單示例

一.原始碼: // memdev.c #define MEMDEV_MAJOR 254 /*預設的mem的主裝置號*/ #define MEMDEV_NR_DEVS 2 /*裝置數*/ #define MEMDEV_SIZE 4096 /*mem裝置描述結構體

Linux 字元裝置驅動結構(三)—— file、inode結構體及chardevs陣列等相關知識解析[轉載]

       先看下面這張圖,這是Linux 中虛擬檔案系統、一般的裝置檔案與裝置驅動程式值間的函式呼叫關係;        上面這張圖展現了一個應用程式呼叫字元裝置驅動的過程, 在裝置驅動程式的設計中,一般而言,會關心 file 和 inode 這兩個結構體       

Linux字元裝置驅動剖析

一、先看看裝置應用程式 1.很簡單,open裝置檔案,read、write、ioctl,最後close退出。如下: intmain(int argc ,char *argv[]){ unsigned char val[1] = 1; int fd =open("/

OpenWRT(七)字元裝置驅動開發

一、字元裝置驅動 我們之前學習過驅動程式的開發,接下來我們接著深入學習字元裝置驅動程式的開發。字元裝置驅動是比較簡單的一種驅動。主要在於實現init、exit、open、read、write等函式。 二、字元裝置驅動例項 1、在package/kern

Linux 網路裝置驅動開發(二) —— Linux 網路棧剖析

一、協議簡介     雖然對於網路的正式介紹一般都參考了 OSI(Open Systems Interconnection)模型,但是本文對 Linux 中基本網路棧的介紹分為四層的 Intern