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,輸入一串字符串,輸入什麼就輸出什麼,這樣就完成了整個驅動程序的編寫、編譯、安裝及測試工作。







 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章