新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > OK6410A學習筆記四:嵌入式Linux驅動之LED驅動進階

        OK6410A學習筆記四:嵌入式Linux驅動之LED驅動進階

        作者: 時間:2016-11-21 來源:網絡 收藏
        作為上一篇介紹的LED驅動的續篇,主要的改動之處在于實現了利用Linux系統支持的mdev機制在驅動加載的過程中自動創建設備節點的功能,另外,對write函數有了比較大的改進。

        //s3c6410_led.c – driver file
        #include
        #include
        #include
        #include
        #include
        #include
        #include
        #include

        #define DEV_MAJOR 176
        #define DEV_NAME "s3c6410_leds"



        #define GPMCON 0x7F008820
        #define GPMDAT 0x7F008824
        #define GPMPUD 0x7F008828


        volatile unsigned long *gpmcon = NULL;
        volatile unsigned long *gpmdat = NULL;
        volatile unsigned long *gpmpud = NULL;

        static struct class *s3c6410_led_class;
        static struct class_device *s3c6410_led_class_dev;


        static int s3c6410_led_open(struct inode *inode, struct file *filp)
        {
        //int ret;

        printk(KERN_ALERT "This is open function of s3c6410 led driver.n");

        *gpmpud &= 0xffffffaa; //set GPM0~3 as pull up enabled
        *gpmcon &= 0xffff1111; //set GPM0~3 as output
        *gpmdat &= 0xfffffff0; //set GPM0~3 to low level, which turn on leds

        return 0;

        }

        static ssize_t s3c6410_led_write(struct file *filp, const char __user *buf,
        size_t count, loff_t *ppos)
        {
        char val;

        copy_from_user(&val,buf,count);

        //printk("val is %cn",val);

        printk(KERN_ALERT "This is write function of s3c6410 led driver.n");

        *gpmpud &= 0xffffffaa;
        *gpmcon &= 0xffff1111;

        if((int)val){
        //turn on leds
        printk(KERN_ALERT "Turn on the leds.n");
        *gpmdat &= 0xfffffff0; //set GPM0~3 to low level, which turn on leds

        }else{
        printk(KERN_ALERT "Turn off the leds.n");
        *gpmdat |= 0x0000000f; //set GPM0~3 to low level, which turn off leds
        }

        return count;
        }


        struct file_operations s3c6410_led_flops = {
        .owner = THIS_MODULE,
        .open = s3c6410_led_open,
        .write = s3c6410_led_write,
        };

        static int __init s3c6410_led_init(void)
        {
        int ret;

        //register led device driver into kernel
        ret = register_chrdev(DEV_MAJOR,DEV_NAME,&s3c6410_led_flops);

        //retriver the vritual address by ioremap
        gpmcon = (volatile unsigned long *)ioremap(GPMCON,4); //32-bit reg
        gpmdat = gpmcon + 1;
        gpmpud = gpmcon + 2;

        //create led device node
        s3c6410_led_class = class_create(THIS_MODULE,"s3c6410_led");
        s3c6410_led_class_dev = device_create(s3c6410_led_class,NULL,MKDEV(DEV_MAJOR,0),
        NULL,DEV_NAME);

        return 0;
        }

        static void __exit s3c6410_led_exit(void)
        {
        //unregister led device dirver from kernel
        unregister_chrdev(DEV_MAJOR,DEV_NAME);

        //iounmap
        iounmap(gpmcon);

        //delete led driver node
        device_unregister(s3c6410_led_class_dev);
        class_destroy(s3c6410_led_class);
        }

        module_init(s3c6410_led_init);
        module_exit(s3c6410_led_exit);

        MODULE_DESCRIPTION("This is led driver sample for OK6410A board.");
        MODULE_VERSION("1.0");
        MODULE_AUTHOR("");
        MODULE_LICENSE("Dual BSD/GPL");

        //s3c6410_led_test.c – test file
        #include
        #include
        #include
        #include

        int main(int argc,char* argv[])
        {
        int fd;
        int val;

        if(argc != 2){
        printf("Usage: n");
        printf("%s n",argv[0]);
        return 0;
        }
        else{
        if(strcmp(argv[1],"on") == 0) val = 1;
        else if(strcmp(argv[1],"off") == 0) val = 0;
        else{
        printf("Usage: n");
        printf("%s ",argv[0]);
        return 0;
        }
        }

        fd = open("/dev/s3c6410_leds",O_RDWR);

        write(fd,&val,1);

        return 0;
        }

        操作過程:





        評論


        技術專區

        關閉
        主站蜘蛛池模板: 渭源县| 通江县| 靖边县| 清远市| 商南县| 秭归县| 晋州市| 昌邑市| 额济纳旗| 揭阳市| 巩留县| 白银市| 上犹县| 义马市| 临邑县| 金堂县| 哈巴河县| 洞头县| 彭水| 洛隆县| 宜章县| 普宁市| 遂昌县| 察隅县| 岳阳县| 定南县| 廊坊市| 乳山市| 大丰市| 岑巩县| 阳朔县| 博湖县| 云梦县| 会理县| 凤城市| 武城县| 泰和县| 蓬莱市| 茶陵县| 南漳县| 新乡县|