Linux字元驅動

來源:互聯網
上載者:User

標籤:字元驅動

學習完了字元驅動,是按照宋寶華的Linux裝置驅動開發講解學習的,代碼練習敲了一遍,自己也理解了。
字元驅動主要的就是一些open,close,read,write等操作
通過上層調用到自己寫的底層函數

這裡寫代碼片#include <linux/fs.h>#include <linux/module.h>#include <linux/slab.h>#include <linux/types.h>#include <linux/errno.h>#include <linux/cdev.h>#include <linux/mm.h>#include <linux/sched.h>#include <linux/init.h>#include <asm/io.h>#include <asm/system.h>#include <asm/uaccess.h>#define GLOBALMEM_SIZE  0x1000  /*全域記憶體4kb*/#define MEM_CLEAR       0x1     /*清除全域記憶體*/#define GLOBALMEM_MAJOR 250     /*主裝置號*/static int globalmem_major = GLOBALMEM_MAJOR;struct globalmem_dev{    struct cdev cdev;    unsigned char mem[GLOBALMEM_SIZE];};struct globalmem_dev *globalmem_devp; /*全域結構體*/int globalmem_open(struct inode* inode, struct file* filp){    filp->private_data = globalmem_devp;//將裝置結構體指標值賦值給檔案私人資料指標    return 0;}int globalmem_release(struct inode* inode, struct file* filp){    struct globalmem_dev* dev = filp->private_data;    return 0;}static int globalmem_ioctl(struct inode* inodep, struct file* filp,        unsigned int cmd,unsigned long arg){    struct globalmem_dev* dev = filp->private_data;    return 0;}static ssize_t globalmem_read(struct file* filp, char __user *buf,        size_t count, loff_t *ppos){    struct globalmem_dev* dev = filp->private_data;    unsigned long p = *ppos;    int ret = 0;    if (p >= GLOBALMEM_SIZE ) //位移量超過數組範圍        return 0;    if (count > GLOBALMEM_SIZE - p) //讀的個數太大        count = GLOBALMEM_SIZE - p;    //從核心讀到使用者    if(copy_to_user(buf,dev->mem + p,count))        ret = - EFAULT; //EFAULT 參數buf指向無效記憶體位址    else {            *ppos += count;            ret = count;            printk(KERN_INFO "read %d bytes from %x\n",count,p);    }    return ret;}static ssize_t globalmem_write(struct file* filp, char __user *buf,        size_t count, loff_t *ppos){    struct globalmem_dev* dev = filp->private_data;    unsigned long p = *ppos;    int ret = 0;    if(p >= GLOBALMEM_SIZE) //位移量超過核心空間大小        return 0;    if(count > GLOBALMEM_SIZE - p) //寫的個數超過現有的        count = GLOBALMEM_SIZE - p;    //從使用者寫到核心    if(copy_from_user(dev->mem + p,(void*)buf,count))        ret = - EFAULT;    else    {        *ppos += count;        ret = count;        printk(KERN_INFO "write %d bytes from %x\n", count,dev->mem + p);    }    return ret;}//filp是核心檔案結構體static loff_t globalmem_llseek(struct file* filp, loff_t offset, int orig){    struct globalmem_dev* dev = filp->private_data;    int ret;    //SEEK_SET 0 檔案開頭    //SEEK_CUR 1 當前位置    //SEEK_END 2 檔案尾    switch(orig){        case 0:            if(offset < 0){                ret = - EINVAL;                break;            }            if(offset > GLOBALMEM_SIZE){                ret = - EINVAL;                break;            }            filp->f_pos = (unsigned int)offset;            ret = filp->f_pos;            break;        case 1:            if(offset > GLOBALMEM_SIZE){                ret = - EINVAL;                break;            }            if(filp->f_pos + offset > GLOBALMEM_SIZE){                ret = - EINVAL;                break;            }            filp->f_pos += offset;            ret = filp->f_pos;            break;        case 2:            if(offset > 0){                 ret = - EINVAL; //在檔案末尾,只能位移賦值                break;            }            if(offset + GLOBALMEM_SIZE < 0){                ret = - EINVAL;                break;            }            filp->f_pos += offset;            ret = filp->f_pos;            break;        default:            ;    }    return 0;}static const struct file_operations globalmem_fops = {    .owner = THIS_MODULE,    .open = globalmem_open,    .read = globalmem_read,    .write = globalmem_write,    .release = globalmem_release,    .llseek = globalmem_llseek,    .compat_ioctl = globalmem_ioctl};static void globalmem_setup_dev(struct globalmem_dev* globalmem_dev,int index){    int err,devno;    devno = MKDEV(globalmem_major,0);    cdev_init(&globalmem_dev->cdev,&globalmem_fops);    err = cdev_add(&globalmem_dev->cdev,devno,1);    if(err)    {        printk(KERN_NOTICE "ERROR %d adding globalmem %d",err,index);    }}static int __init globalmem_init(void){    printk(KERN_INFO "globalmem_init");    int result;    dev_t devno = MKDEV(globalmem_major,0);//根據主裝置號,或得裝置號,一般次裝置號為0    if(globalmem_major != 0)        register_chrdev_region(devno,1,"globalmem_dev");    else    {        result = alloc_chrdev_region(&devno,0,1,"globalmem_dev");//自動分配一個裝置號        globalmem_major = MAJOR(devno);    }    if(result < 0)        return result;    //動態申請結構體記憶體    globalmem_devp = kmalloc(sizeof(struct globalmem_dev),GFP_KERNEL);    if(!globalmem_devp)        goto fail_malloc;    memset(globalmem_devp,0,sizeof(struct globalmem_dev));    globalmem_setup_dev(globalmem_devp,0);    return 0;fail_malloc:    unregister_chrdev_region(devno,1);    return result;}static int __exit  globalmem_exit(void){    printk(KERN_INFO "globalmem_exit...");    dev_t devno;    devno = MKDEV(globalmem_major,0);    cdev_del(&globalmem_devp->cdev); // 刪除cdev結構體    unregister_chrdev_region(devno,1);//登出裝置    kfree(globalmem_devp);    return 0;}module_init(globalmem_init);module_exit(globalmem_exit);

Makefile

KVERS = $(shell uname -r)obj-m += globalmem_private.obuild:kernel_moduleskernel_modules:    make -C /lib/modules/$(KVERS)/build M=$(CURDIR) modulesinsmod:    insmod globalmem.koclean:    make -C /lib/modules/$(KVERS)/build M=$(CURDIR) modules clean

測試程式

#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#define path "/dev/globalmem_dev"int main(){    char buf[] = "Hello word!\n";    int fd = open(path,O_RDWR);    if(fd == -1){        perror("open");        exit(1);    }    write(fd,buf,sizeof(buf));    close(fd);}

執行結果

Linux字元驅動

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.