zoukankan      html  css  js  c++  java
  • BeagleBone Black Linux驱动程序开发入门(1): LED驱动程序

    这篇文章展示如何在BBB平台上编写LED驱动程序,本文的程序是根据国嵌S3C2440的LED驱动的例子并结合内核中OMAP系列的gpio操作来改的。本文中的程序包括驱动程序模块和用户空间程序。废话不多说,先贴程序出来吧。

    /****************************************************

    am3359_led_misc.c

    *****************************************************/

    /***************头文件也许不用包含这么多*************/

    #include <linux/miscdevice.h>

    #include <linux/delay.h>

    //#include <asm/irq.h>

    #include <linux/gpio.h>

    #include <linux/kernel.h>

    #include <linux/module.h>

    #include <linux/init.h>

    #include <linux/mm.h>

    #include <linux/fs.h>

    #include <linux/types.h>

    #include <linux/delay.h>

    #include <linux/moduleparam.h>

    #include <linux/slab.h>

    #include <linux/errno.h>

    #include <linux/ioctl.h>

    #include <linux/cdev.h>

    #include <linux/string.h>

    #include <linux/list.h>

    #include <linux/pci.h>

    #include <asm/uaccess.h>

    #include <asm/atomic.h>

    #include <asm/unistd.h>

    #include <asm/io.h>

    #include <asm/system.h>

    #include <asm/uaccess.h>

    //#include <mux.h>

    #include "memdev.h"

    #define DEVICE_NAME "leds"

    static unsigned long led_table[] = { 53, 54, 55,56, };

    /*static unsigned int led_cfg_table[] = { OMAP_PIN_OUTPUT, OMAP_PIN_OUTPUT,

    OMAP_PIN_OUTPUT, OMAP_PIN_OUTPUT, };*/

    static int sbc2440_leds_ioctl(

    struct file *file,

    unsigned int cmd,

    unsigned long arg) {

    int i = 0;

    /* 检测命令的有效性 */

    if (_IOC_TYPE(cmd) != MEMDEV_IOC_MAGIC)

    return -EINVAL;

    if (_IOC_NR(cmd) > MEMDEV_IOC_MAXNR)

    return -EINVAL;

    printk("here in kernel ioctl ");

    /* 根据命令,执行相应的操作 */

    switch (cmd) {

    case MEMDEV_IOCOFF:

    /*灯全灭*/

    cmd = 0;

    for (i = 0; i < 4; i++)

    gpio_set_value(led_table[i], cmd);

    return 0;

    case MEMDEV_IOCON:

    /*灯全亮*/

    cmd = 1;

    for (i = 0; i < 4; i++)

    gpio_set_value(led_table[i], cmd);

    return 0;

    default:

    return -EINVAL;

    }

    }

    /*文件操作结构体*/

    static struct file_operations dev_fops = { .owner = THIS_MODULE, .unlocked_ioctl =

    sbc2440_leds_ioctl, };

    static struct miscdevice misc = { .minor = MISC_DYNAMIC_MINOR, .name =

    DEVICE_NAME, .fops = &dev_fops, };

    static int __init dev_init(void)

    {

    int ret;

    int i;

    /*设置GPIO控制寄存器,GPIO设置为输出模式,默认下灯全灭*/

    for (i = 0; i < 4; i++) {

    // 这四个引脚内核中已经初始化为输出了

    // omap_mux_init_gpio(led_table[i], led_cfg_table[i]);

    gpio_set_value(led_table[i], 1);

    }

    /*注册混杂型字符设备驱动*/

    ret = misc_register(&misc);

    printk (DEVICE_NAME" initialized ");

    return ret;

    }

    static void __exit dev_exit(void)

    {

    int i;

    for (i = 0; i < 4; i++) {

    gpio_set_value(led_table[i], 0);

    }

    printk(DEVICE_NAME" driver module exit ");

    /*注销混杂型字符设备驱动*/

    misc_deregister(&misc);

    }

    module_init(dev_init)

    ;

    module_exit(dev_exit)

    ;

    MODULE_AUTHOR("David Xie")

    ;

    MODULE_LICENSE("GPL")

    ;

    /*****************************************************************

    memdev.h

    *****************************************************************/

    #ifndef _MEMDEV_H_

    #define _MEMDEV_H_

    #include <linux/ioctl.h>

    /* 定义幻数 */

    #define MEMDEV_IOC_MAGIC 'k'

    /* 定义命令 */

    #define MEMDEV_IOCON _IO(MEMDEV_IOC_MAGIC, 1)

    #define MEMDEV_IOCOFF _IO(MEMDEV_IOC_MAGIC, 2)

    #define MEMDEV_IOC_MAXNR 2

    #endif /* _MEMDEV_H_ */

    /*******************************************************************

    Makefile

    ********************************************************************/

    ifneq ($(KERNELRELEASE),)

    obj-m := am3359_leds_misc.o

    else

    KDIR := /root/beaglebone/origin-kernel/kernel/

    all:

    make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-

    clean:

    rm -f *.ko *.o *.mod.o *.mod.c *.symvers modul*

    endif

    以上就是内核模块的所有代码了。在Ubuntu中make一下,马上就得到了一个内核模块am3359_leds_misc.ko,用SSH把它和下面这个appled.c以及上面的memdev.h头文件COPY到板子的/home/root/drivers/led文件夹里面(user app可以直接在板子上编译)。

    /********************************************************************

    appled.c

    ********************************************************************/

    #include <stdio.h>

    #include <stdlib.h>

    #include <unistd.h>

    #include <sys/ioctl.h>

    #include "memdev.h" /* 包含命令定义 */

    int main(int argc, char **argv)

    {

    int on;

    int fd;

    if (argc != 2 || sscanf(argv[1],"%d", &on) != 1 ||on < 0 || on > 1 ) {

    fprintf(stderr, "Usage:%s 0|1 ",argv[0]);

    exit(1);

    }

    fd = open("/dev/leds", 0);

    if (fd < 0) {

    perror("open device leds");

    exit(1);

    }

    /*通过ioctl来控制灯的亮、灭*/

    if(on){

    printf("turn on all leds! ");

    ioctl(fd, MEMDEV_IOCON, 0);

    }

    else {

    printf("turn off all leds! ");

    ioctl(fd, MEMDEV_IOCOFF, 0);

    }

    close(fd);

    return 0;

    }

    输入以下命令编译用户程序:

    gcc appled.c -o appled

    加载led驱动模块之前运行以下命令可以关闭所有四个led:

    /usr/bin/led_aging.sh~

    输入以下命令加载led驱动模块:

    insmod am3359_leds_misc.ko

    运行LED用户程序:

    ./appled 1

    参数为1的时候所有4个LED被点亮.

    ./appled 0

    参数为0的时候所有4个LED熄灭.

  • 相关阅读:
    cmder
    navicat 查询保存的位置
    git使用
    怎么保证测试用例的覆盖率
    python3.7-初学篇-19-良好的习惯
    python基础篇-使用list和tuple
    python基础篇-字符串和编码
    python基础篇-输入和输出
    python3.7-初学篇-21
    python3.7-初学者-20
  • 原文地址:https://www.cnblogs.com/dolphi/p/3184280.html
Copyright © 2011-2022 走看看