您的位置:首页 > 运维架构 > Linux

OK6410 Linux下LED驱动程序

2013-04-20 12:45 543 查看
如果你的飞凌Linux-3.0.1内核源码没有编译过,编译时可能会出现:

scripts/basic/fixdep: 1: scripts/basic/fixdep: ELF: not found

scripts/basic/fixdep: 2: scripts/basic/fixdep: Syntax error: "(" unexpected


这时要先到Linux-3.0.1目录下 执行make scripts



LED驱动:

s3c6410_leds.h

#ifndef _S3C6410_LED_CMD_H
#define _S3C6410_LED_CMD_H

#define S3C6410_LED_MAGIC 'x' //定义幻数
#define S3C6410_LED_MAX_NR 2 //定义命令的最大序数

#define LED_ON 		_IO(S3C6410_LED_MAGIC, 0)
#define LED_OFF _IO(S3C6410_LED_MAGIC, 1)

#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <asm/irq.h>
//#include <mach/regs-gpio.h>
#include <mach/hardware.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 <mach/map.h>
#include <mach/regs-clock.h>
#include <mach/regs-gpio.h>

#include <plat/gpio-cfg.h>
#include <mach/gpio-bank-e.h>
#include <mach/gpio-bank-m.h>

#endif /*_S3C6410_LED_CMD_H*/


s3c6410_leds.c

#include"s3c6410_leds.h"

#define DEVICE_NAME "leds"

static long s3c6410_leds_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
if(_IOC_TYPE(cmd) != S3C6410_LED_MAGIC) return - EINVAL;
if(_IOC_NR(cmd) > S3C6410_LED_MAX_NR) return - EINVAL; //这里命令为序号为0,1,总共二个,若命令数大于2,说明命令不合法
if (arg > 4) return -EINVAL;
unsigned tmp = readl(S3C64XX_GPMDAT);
switch(cmd)
{
case LED_OFF://close light
tmp &= (~(1<<arg));
break;
case LED_ON:
tmp |= (1<<arg);
break;
default:
return -EINVAL;
}
writel(tmp,S3C64XX_GPMDAT);
printk (DEVICE_NAME": %d %d\n", arg, cmd);
return 0;
}

static struct file_operations dev_fops = {
.owner			= THIS_MODULE,
.unlocked_ioctl	= s3c6410_leds_ioctl,
};

static struct miscdevice misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &dev_fops,
};

static int __init dev_init(void)
{
int ret;

unsigned tmp;

//gpm0-3 pull up
tmp = readl(S3C64XX_GPMPUD);
tmp &= (~0xFF);
tmp |= 0xaa;
writel(tmp,S3C64XX_GPMPUD);

//gpm0-3 output mode
tmp =readl(S3C64XX_GPMCON);
tmp &= (~0xFFFF);
tmp |= 0x1111;
writel(tmp,S3C64XX_GPMCON);

//gpm0-3 output 0
tmp = __raw_readl(S3C64XX_GPMDAT);
tmp |= 0x10;
writel(tmp,S3C64XX_GPMDAT);

ret = misc_register(&misc);
printk ("\n@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
printk (DEVICE_NAME"\tinitialized\n");
printk ("\n@@@@@@@@@@@@@@@@@@@@@@@@@@\n");

return ret;
}

static void __exit dev_exit(void)
{
misc_deregister(&misc);
}

module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("FriendlyARM Inc.");


MakeFile

ifneq ($(KERNELRELEASE),)

obj-m := s3c6410_leds.o

else

KDIR := /home/wu55uw/forlinx/linux-3.0.1
all:
make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-
clean:
rm -f *.ko *.o *.mod.o *.mod.c *.symvers  modul*

endif


测试程序:

app-led.c:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>

int main(int argc, char **argv)
{
int on;
int led_no;
int fd;
if (argc != 3 || sscanf(argv[1], "%d", &led_no) != 1 || sscanf(argv[2],"%d", &on) != 1 ||
on < 0 || on > 1 || led_no < 0 || led_no > 3) {
fprintf(stderr, "Usage: leds led_no 0|1\n");
exit(1);
}
fd = open("/dev/leds", 0);
if (fd < 0) {
perror("open device leds");
exit(1);
}
ioctl(fd, on, led_no);
close(fd);
return 0;
}


运行测试:

insmod
s3c6410_leds.ko

./app_led 0 1

./app_led 1 1

./app_led 2 1

./app_led 3 1
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: