新聞中心

        EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 字符設(shè)備驅(qū)動(dòng)-LED實(shí)驗(yàn)

        字符設(shè)備驅(qū)動(dòng)-LED實(shí)驗(yàn)

        作者: 時(shí)間:2016-11-21 來(lái)源:網(wǎng)絡(luò) 收藏
        驅(qū)動(dòng)源碼:
        #include
        #include
        #include
        #include
        #include
        #include
        #include
        #include
        #include
        #include
        int major;
        static struct class *leddrv_class;
        static struct class_device *leddrv_class_dev;
        volatile unsigned long *gpfcon = NULL;
        volatile unsigned long *gpfdat = NULL;
        static int led_drv_open(struct inode *inode, struct file *file)
        {
        //printk("first_drv_openn");
        *gpfcon &= ~((0x3<<(4*2)) | (0x3<<(5*2)) | (0x3<<(6*2)));
        *gpfcon |= ((0x1<<(4*2)) | (0x1<<(5*2)) | (0x1<<(6*2)));
        return 0;
        }
        static ssize_t led_drv_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
        {
        char val = 0;
        copy_from_user(&val,buf,count);
        if(val == 1)
        *gpfdat &= ~((1<<4) | (1<<5) | (1<<6));
        else if(val == 0)
        *gpfdat |= ((1<<4) | (1<<5) | (1<<6));
        //printk("first_drv_writen");
        return 0;
        }
        static struct file_operations led_drv_fops = {
        .owner = THIS_MODULE,
        .open = led_drv_open,
        .write = led_drv_write,
        };
        static int led_drv_init(void)
        {
        major = register_chrdev(0, "led_drv", &led_drv_fops); // 注冊(cè), 告訴內(nèi)核
        leddrv_class = class_create(THIS_MODULE, "leddrv");
        leddrv_class_dev = class_device_create(leddrv_class, NULL, MKDEV(major, 0), NULL, "xxx");
        gpfcon = (volatile unsigned long *)ioremap(0x56000050, 16);
        gpfdat = gpfcon + 1;
        return 0;
        }
        static void led_drv_exit(void)
        {
        unregister_chrdev(major, "led_drv"); // 卸載
        class_device_unregister(leddrv_class_dev);
        class_destroy(leddrv_class);
        iounmap(gpfcon);
        }
        module_init(led_drv_init);
        module_exit(led_drv_exit);
        MODULE_LICENSE("GPL");
        ==================================================================================================
        測(cè)試程序:
        #include
        #include
        #include
        #include
        int main(int argc, char **argv)
        {
        int fd;
        int val = 1;
        fd = open("/dev/xxx",O_RDWR);
        if(fd < 0)
        {
        printf("cant open!n");
        }
        if(argc != 2)
        {
        printf("Usage:n");
        printf("%s ",argv[0]);
        return 0;
        }
        if(strcmp(argv[1],"on") == 0)
        val = 1;
        else
        val = 0;
        write(fd,&val,4);
        return 0;
        }
        ==================================================================================================
        注:在調(diào)用write(fd,&val,4);時(shí)根據(jù)不同的val值在調(diào)用驅(qū)動(dòng)程序時(shí)做出判斷:關(guān)閉、打開(kāi)led燈
        copy_from_user(&val,buf,count); //從用戶空間buf拷貝count長(zhǎng)度的數(shù)據(jù)到內(nèi)核空間val中
        copy_to_user(buf,&val,,count); //從內(nèi)核空間val拷貝count長(zhǎng)度的數(shù)據(jù)到用戶空間buf中
        內(nèi)核空間不能直接訪問(wèn)物理地址,故要映射:
        gpfcon = (volatile unsigned long *)ioremap(0x56000050, 16);


        評(píng)論


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

        關(guān)閉
        主站蜘蛛池模板: 封丘县| 北碚区| 社旗县| 昂仁县| 龙口市| 辉县市| 嘉峪关市| 土默特左旗| 石门县| 黑水县| 安达市| 德清县| 石林| 广平县| 汉阴县| 花莲县| 赤城县| 塔河县| 内丘县| 华亭县| 聂荣县| 彝良县| 临澧县| 康平县| 哈密市| 汤阴县| 呼伦贝尔市| 佛学| 玉环县| 安塞县| 宁武县| 北安市| 内黄县| 贺兰县| 恩平市| 东兴市| 泽库县| 兴安盟| 兴化市| 化德县| 辽源市|