新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > 驅(qū)動學習1

        驅(qū)動學習1

        作者: 時間:2016-12-01 來源:網(wǎng)絡 收藏
        /*清除空間*/
        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;
        }
        /*模塊清除函數(shù)*/
        static void memdev_exit(void)
        {
        cdev_del(&cdev);/*注銷字符設備*/
        /*釋放兩個物理內(nèi)存*/
        kfree(mem_devp[0].data);
        kfree(mem_devp[1].data);
        kfree(mem_devp);/*釋放設備結(jié)構(gòu)體內(nèi)存*/
        unregister_chrdev_region(MKDEV(mem_major,0),2);
        }
        /*定義相關(guān)的操作函數(shù)*/
        /*mem_open*/
        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];
        /*將數(shù)據(jù)指向兩個內(nèi)存空間*/
        filp->private_data = dev;
        return 0;
        }
        /*release函數(shù)的實現(xiàn)*/
        int mem_release(struct inode *inode, struct file *flip)
        {
        return 0;
        }
        /*read函數(shù)的實現(xiàn)*/
        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;
        /*獲得file結(jié)構(gòu)體上的指針*/
        struct mem_dev *dev = filp->private_data;
        /*參數(shù)的檢查*/
        if(p >= MEMDEV_SIZE)
        return 0;
        if(count > MEMDEV_SIZE - p)
        count = MEMDEV_SIZE - p;
        /*從內(nèi)核讀數(shù)據(jù)到用戶空間*/
        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",count,p);
        }
        return ret;
        }
        /*write函數(shù)的實現(xiàn)*/
        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;
        /*獲得設備結(jié)構(gòu)體的指針*/
        struct mem_dev *dev = filp->private_data;
        /*檢查參數(shù)的長度*/
        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 "writted %d bytes(s) from %d",count,p);
        }
        return ret;
        }
        /*lseek的實現(xiàn)*/
        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:
        return -EINVAL;
        }
        filp->f_pos = newpos;
        return newpos;
        }
        /*作者以及權(quán)限的聲明*/
        MODULE_AUTHOR("GongPing");
        MODULE_LICENSE("GPL");
        /*通過宏module_init和module_exit實現(xiàn)模塊添加*/
        module_init(memdev_init);
        module_exit(memdev_exit);
        第三個是Makefile:
        ifneq ($(KERNELRELEASE),)
        obj-m := memdev.o
        else
        #KDIR :=/usr/src/kernels/2.6.35.14-96.fc14.i686
        #KDIR :=/lib/modules/2.6.35.14-96.fc14.i686/build
        #KDIR ?=/opt/LinuxKernel/linux-2.6.38.1
        KDIR :=/opt/LinuxKernel/linux-2.6.38.1
        PWD :=$(shell pwd)
        default:
        make -C $(KDIR) M=$(PWD) modules
        clean:
        rm -f *.ko *.o *.mod.o *.mod.c *.symvers
        endif
        第4個是應用程序:
        #include
        #include
        #include
        int main()
        {
        FILE *fp0 = NULL;
        char Buf[4096];
        /*復制數(shù)據(jù)到buf中*/
        strcpy(Buf,"Mem is char devices!");
        printf("Buf: %s",Buf);
        /*打開設備文件*/
        fp0 = fopen("/dev/memdev0","rw");
        /*錯誤處理*/
        if(fp0 == NULL)
        {
        printf("Open Memdev0 Error!");
        return -1;
        }
        /*寫數(shù)據(jù)到設備中*/
        //fread(Buf,sizeof(Buf),1,fp0);
        fwrite(Buf,sizeof(Buf),1,fp0);
        /*定位*/
        fseek(fp0,0,SEEK_SET);
        /*復制數(shù)據(jù)到Buf*/
        strcpy(Buf,"Buf is NULL!");
        /*打印*/
        printf("Buf: %s",Buf);
        /*讀數(shù)據(jù)*/
        fread(Buf,sizeof(Buf),1,fp0);
        printf("BUF: %s",Buf);
        fclose(fp0);
        return 0;
        }
        源碼是別人的,我只是做了一下注釋,然后做了適當?shù)男薷?,?qū)動程序與應用程序以及硬件代碼存在較大的差別,以后要多寫,多理解,多總結(jié)。
        上一頁 1 2 下一頁

        關(guān)鍵詞: 驅(qū)動學

        評論


        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 冕宁县| 韩城市| 罗城| 颍上县| 密山市| 奈曼旗| 衡东县| 遵义县| 军事| 寿宁县| 马尔康县| 桓台县| 宁远县| 江口县| 勐海县| 大渡口区| 瓦房店市| 恩施市| 五河县| 迁西县| 伊吾县| 临桂县| 济源市| 股票| 荔浦县| 邵阳县| 屏东县| 遵义市| 沈阳市| 房产| 晴隆县| 前郭尔| 万年县| 永胜县| 西丰县| 大埔县| 桑日县| 馆陶县| 图片| 焉耆| 本溪市|