BeagleBone Black Linux驅動程序開發入門(1): LED驅動程序

這篇文章展現如何在BBB平臺上編寫LED驅動程序,本文的程序是根據國嵌S3C2440的LED驅動的例子並結合內核中OMAP系列的gpio操做來改的。本文中的程序包括驅動程序模塊和用戶空間程序。廢話很少說,先貼程序出來吧。linux

/****************************************************app

am3359_led_misc.catom

*****************************************************/ci

/***************頭文件也許不用包含這麼多*************/cmd

#include <linux/miscdevice.h>string

#include <linux/delay.h>it

//#include <asm/irq.h>io

#include <linux/gpio.h>asm

#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\n");

/* 根據命令,執行相應的操做 */

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"\tinitialized\n");

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"\tdriver module exit\n");

/*註銷混雜型字符設備驅動*/

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\n",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!\n");

ioctl(fd, MEMDEV_IOCON, 0);

}

else {

printf("turn off all leds!\n");

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熄滅.

相關文章
相關標籤/搜索