zoukankan      html  css  js  c++  java
  • AM335x内核模块驱动之LED

    在Ubuntu的任意可操作的文件才建立text目录

    在text中建立zyr-hello.c:

    #include<linux/kernel.h>
    #include<linux/module.h>
    #include<linux/init.h>
    #include <linux/miscdevice.h>
    #include <linux/types.h>
    #include <linux/ioctl.h>
    #include <linux/cdev.h>
    #include <linux/delay.h>
    #include <linux/gpio.h>
    #include <linux/errno.h>
    #include <linux/fs.h>
    #include <linux/init.h>
    
    #define CORE_LED (1*32 + 7)  //硬件上的一个led灯为goip1_7
    #define DEVICE "led_core"
    #define MAGIC_NUM 0xDB
    #define MAGIC_SET_LOW _IO(MAGIC_NUM,0)
    #define MAGIC_SET_HIGH _IO(MAGIC_NUM,1)
    
    int led_open(struct inode *inode, struct file *file)
    {
        int ret;
        ret = gpio_request_one(CORE_LED,
                (GPIOF_DIR_OUT|GPIOF_OUT_INIT_HIGH),"core_led");
        if(ret)
        {
            printk("Error: cannot request gpio CORE_LED. 
    ");
            printk("Error ret = %d but still can be manipulated. 
    ", ret);
        }            
        
        gpio_set_value(CORE_LED,1);
        return 0;
                
    }
    
    int led_release(struct inode *inode, struct file *filp)
    {
        gpio_free(CORE_LED);
        printk("GPIO LED dev release. 
    ");
        return 0;
    }
    
    long led_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
    {
        switch(cmd)
        {
            case MAGIC_SET_LOW:
                printk("GPIO LED set low.
    ");
                gpio_set_value(CORE_LED,0);
                break;
            case MAGIC_SET_HIGH:
                printk("GPIO LED set high.
    ");
                gpio_set_value(CORE_LED,1);
                break;
            default:
                printk("ERROR unvalid cmd.
    ");
                break;    
        }
        return 0;
    }
    
    struct file_operations led_fops ={
        .owner             = THIS_MODULE,
        .open              = led_open,
        .release         = led_release,
        .unlocked_ioctl = led_ioctl,
    };
    
    struct miscdevice led_dev ={
        .minor        = MISC_DYNAMIC_MINOR,
        .name        = DEVICE,
        .fops        = &led_fops,
    };
    
    static int led_init(void)
    {
        int ret;
        ret = misc_register(&led_dev);
        if (ret)
        {
            printk("Error: cannot register misc. 
    ");
            return ret;
        }
        printk("misc-register %s
    ",DEVICE);
        return 0;
    }
    
    static void led_exit(void)
    {
        misc_deregister(&led_dev);
        printk("misc-deregister %s
    ",DEVICE);
    }
    
    module_init(led_init);
    module_exit(led_exit);
    MODULE_LICENSE("GPL");
    MODULE_AUTHOR("zyr<yr736002477@qq.com>");

    在该目录下建立Makefile文件:

    ifneq ($(KERNELRELEASE),)
    obj-m := zyr-hello.o
    else
    KDIR :=/home/zyr/Source_code/linux-3.14.65/
    all:
        make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j8
    clean:
        rm -f *.ko *.o *.mod.o *.mod.c *.symvers *.order
    endif

    其中KDIR为内核的路径,要想编译arm可运行的驱动,一定要指定交叉编译器

    在该目录下执行make,会编译器出zyr-hello.ko文件,此文件为可加载于内核的.ko模块的文件。

    然后编写这个led驱动的的测试文件(运行在文件系统中):

    同样在任意的可执行处建立一个目录放测试文件比如aa:

    在该目录下建立led_test.c:

    #include<stdio.h>
    #include<stdlib.h>
    #include<unistd.h>
    #include<fcntl.h>
    #include<errno.h>
    #include<string.h>
    #include<asm-generic/ioctl.h>
    
    #define DEVICE          "/dev/led_core"
    #define MAGIC_NUM       0xDB
    #define MAGIC_SET_LOW   _IO(MAGIC_NUM, 0)
    #define MAGIC_SET_HIGH  _IO(MAGIC_NUM, 1)
    
    int main(int argc, char *argv[])
    {
           int fd;
    
            printf("Start led test.
    ");
    
            fd = open(DEVICE, O_RDWR);
            if (fd < 2) {
                    printf("Cannot open device %s
    ", DEVICE);
                    return -EFAULT;
            }       
            while (1) {
                    ioctl(fd, MAGIC_SET_LOW, 0);
                    sleep(1);
                    ioctl(fd, MAGIC_SET_HIGH, 0);
                    sleep(1);
            }
            return 0;       
    }

    在该目录下建立Makefile文件:

    #----------------------------
    CC    = arm-linux-gnueabihf-gcc 
    CFLAGS    =         
    main : led_test.c 
        $(CC) $(CFLAGS) led_test.c -o led_test

    在该目录下执行make:生成led_test可执行文件。

    将led_test可执行文件和zyr-hello.ko模块文件copy到建立好的NFS共享文件夹下敲击命令(在arm板的终端中):

    [root@zyr-am335x ]#mount -t nfs -o nolock 192.168.200.123:/home/zyr/Source_code/text/nfs /mnt
    [root@zyr-am335x ]#cd /mnt
    [root@zyr-am335x mnt]#ls
    led_test      zyr-hello.ko
    [root@zyr-am335x mnt]#insmod zyr-hello.ko
    [ 5299.759382] misc-register led_core
    [root@zyr-am335x mnt]#./led_test
    Start led test.
    [ 5309.324907] GPIO LED set low.
    [ 5310.338522] GPIO LED set high.
    [ 5311.342169] GPIO LED set low.
    [ 5312.345413] GPIO LED set high.

    参考博客:

    http://www.eefocus.com/marianna/blog/15-02/310302_72e75.html

  • 相关阅读:
    2013年3月1日星期五
    2013年2月26日星期二本地图片预览
    2013年3月2日星期六
    2013年第10周三低潮
    2013年第9周日见同学
    header发送Cookie
    HTTP Cookie header 中setcookie格式
    多台服务器共享session问题
    PHP中header头设置Cookie与内置setCookie的区别
    session原理及实现共享
  • 原文地址:https://www.cnblogs.com/BigOBlue/p/7071476.html
Copyright © 2011-2022 走看看