AM437x AM335x gpio驱动调试心得

GPIO驱动的编码来源于设备树的的状态值,修改设备树会改变其gpio编号,见我博客中的其他文档有队GPIO号的描述

1. GPIOchar型驱动,这里主要就是点个灯,感受一下驱动的设计和硬件的控制驱动程序:

 

  1. #include <linux/init.h>
    #include <linux/module.h>
    #include <linux/leds.h>
    #include <linux/io.h>

    #include <linux/semaphore.h>
    #include <linux/kernel.h>
    #include <linux/cdev.h>

    #include <linux/types.h>
    #include <linux/fs.h>
    #include <mach/gpio.h>
    #include <plat/mux.h>

    #include <linux/gpio.h>

    /*******************************************/
    #define NAME "leds" 
    #define GPIO_TO_PIN(bank, gpio) (32 * (bank) + (gpio))

    static int major =251;//定义主设备号 
    /*******************************************/
    void led_on(void)

    gpio_set_value(GPIO_TO_PIN(1,22), 1);
    }

    void led_off(void)

    gpio_set_value(GPIO_TO_PIN(1,22), 0);
    }

    void led_init(void)

    int result;
    /* Allocating GPIOs and setting direction */
    result = gpio_request(GPIO_TO_PIN(1,22), "Leds");//usr1
    if (result != 0)
    printk("gpio_request(1_22) failed!\n");
    result = gpio_direction_output(GPIO_TO_PIN(1,22), 1);
    if (result != 0)
    printk("gpio_direction(1_22) failed!\n");

    }

    struct light_dev
    {
    struct cdev cdev;
    unsigned char value;
    };

    struct light_dev *light_devp;

    MODULE_AUTHOR("chenzhufly");
    MODULE_LICENSE("Dual BSD/GPL");

    // 打开和关闭函数
    int light_open(struct inode *inode,struct file *filp)
    {
    struct light_dev *dev;

    // 获得设备结构体指针
    dev = container_of(inode->i_cdev,struct light_dev,cdev);
    // 让设备结构体作为设备的私有信息
    filp->private_data = dev;

    return 0;
    }

    int light_release(struct inode *inode,struct file *filp)
    {
    return 0; 
    }


    // ioctl
    int light_ioctl(struct file *filp,unsigned int cmd,
    unsigned long arg)
    {
    struct light_dev *dev = filp->private_data;

    switch(cmd)
    {
    case 0:
    dev->value = 0;
    led_off(); 
    break;

    case 1:
    dev->value = 1;
    led_on();
    break;

    default:

    return -ENOTTY;
    // break;
    }

    return 0;


    struct file_operations light_fops = 
    {
    .owner = THIS_MODULE,
    .unlocked_ioctl = light_ioctl,
    .open = light_open,
    .release = light_release,
    };
    // 模块加载函数
    int light_init(void)
    {
    int ret;
    led_init();
    printk(KERN_ALERT "led modules is install\n"); 
    ret=register_chrdev(major,NAME,&light_fops); 
    if(ret<0) 

    printk("unable to register myled driver!\n"); 
    return ret; 

    return 0; 

    }

    // 模块卸载函数
    void light_cleanup(void)
    {
    unregister_chrdev(major,NAME); 
    printk("Goodbye,cruel world!\n"); 
    }

    module_init(light_init);
    module_exit(light_cleanup);
复制代码

 

 

 

应用程序:

 

 

  1. #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <linux/input.h>
    #include <unistd.h>
    #include <sys/ioctl.h>

    int main(int argc, char * argv)
    {
    int i, n, fd;

    fd = open("/dev/leds", O_RDWR);
    if (fd < 0)
    {
    printf("can't open /dev/leds!\n");
    exit(1);
    }

    while (1) {
    ioctl(fd, 1, 1);
    sleep(1);

    ioctl(fd, 0, 1);
    sleep(1);
    }

    close(fd);

    return 0;
    }
复制代码

 

 

 

Makefile文件:

 

 

  1. ARCH=arm
    CROSS_COMPILE=/home/chenzhufly/beaglebone/linux-devkit/bin/arm-arago-linux-gnueabi-
    obj-m := leds.o
    KDIR := /home/chenzhufly/beaglebone/board-support/linux-3.1.0-psp04.06.00.03.sdk
    PWD := $(shell pwd)
    default:
    make -C $(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules
    app: leds_test.c
    $(CROSS_COMPILE)gcc -o leds_test leds_test.c
    clean:
    $(MAKE) -C $(KDIR) M=$(PWD) clean
复制代码

 

 

 

leds.sh脚本

 

 

  1. insmod leds.ko
    mknod /dev/leds c 251 0
    ./leds_test
复制代码

 

 

2. 使用echo命令,这个我在前面也说过

 

  1. 点亮usr1
    root@beaglebone:~# echo 1 >
    /sys/class/leds/beaglebone::usr1/brightness

    关闭usr1
    root@beaglebone:~# echo 0 > /sys/class/leds/beaglebone::usr1/brightness
复制代码

 

 

3. 做个应用程序实现流水灯功能吧

 

  1. #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/ioctl.h>
    #include <fcntl.h> 
    #define LED1 "/sys/class/leds/beaglebone::usr1/brightness" // usr1 led
    #define LED2 "/sys/class/leds/beaglebone::usr2/brightness" // usr2 led
    #define LED3 "/sys/class/leds/beaglebone::usr3/brightness" // usr3 led

    int main(void)
    {
    int f_led1 = open(LED1, O_RDWR);
    int f_led2 = open(LED2, O_RDWR);
    int f_led3 = open(LED3, O_RDWR);

    unsigned char dat1, dat2, dat3;
    unsigned char i = 0;

    if (f_led1 < 0)

    printf("error in open %s",LED1);
    return -1;

    if (f_led2 < 0)
    {
    printf("error in open %s",LED2);
    return -1;

    if (f_led3 < 0) 
    {
    printf("error in open %s",LED3);
    return -1;

    //add 10 times
    for(i=1; i<30; i++)
    {
    dat1 = ((i%3) == 1) ? '1' : '0';
    dat2 = ((i%3) == 2) ? '1' : '0';
    dat3 = ((i%3) == 0) ? '1' : '0';
    write(f_led1, &dat1, sizeof(dat1));
    write(f_led2, &dat2, sizeof(dat2));
    write(f_led3, &dat3, sizeof(dat3));
    usleep(300000);

    // all the bright
    {
    dat1 = '1';
    dat2 = '1';
    dat3 = '1';
    write(f_led1, &dat1, sizeof(dat1));
    write(f_led2, &dat2, sizeof(dat2));
    write(f_led3, &dat3, sizeof(dat3));

    }

猜你喜欢

转载自blog.csdn.net/wlf_go/article/details/81252319