Linux2.6.32下的Led灯驱动

来源:互联网 发布:vb.net winform 编辑:程序博客网 时间:2024/04/30 13:10
开发环境:
主机与开发板内核:Linux2.6.32(主机与开发板内核尽量一致,不然安装模块时,可能不兼容)
开发板:mini2440

驱动程序:
myleds_mini2440.h
#ifndef _MYLEDS_MINI2440_H_
#define _MYLEDS_MINI2440_H_

#define LED_IOC_MAGIC 'k'
#define LEDON _IOW(LED_IOC_MAGIC,0,int)
#define LEDOFF _IOW(LED_IOC_MAGIC,1,int)

#endif

myleds_mini2440.c
#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 <linux/gpio.h>

#include "myleds_mini2440.h"

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Dr. Wang");

//#define LEDON 0
//#define LEDOFF 1

dev_t ledid;
struct cdev *led_cdev;
struct class *led_class;

static unsigned long led_table [] = {
S3C2410_GPB(5),
S3C2410_GPB(6),
S3C2410_GPB(7),
S3C2410_GPB(8),
}; //定义引脚的寄存器数组(无符号长整形,对应于引脚的地址)

/*static unsigned int led_cfg_table [] = {
S3C2410_GPB5_OUTP,
S3C2410_GPB6_OUTP,
S3C2410_GPB7_OUTP,
S3C2410_GPB8_OUTP,
};*/ //定义引脚功能,为输出(无符号整形)

static int led_open(struct inode *inode,struct file *file)
{
/***led初始化***/
int i;
for (i = 0; i < 4; i++)
{
/*设置GPIO对应的配置寄存器GPIOCON为输出状态*/     
//s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);
s3c2410_gpio_cfgpin(led_table[i], S3C2410_GPIO_OUTPUT);
}
return 0;
}

static int led_ioctl(struct inode *inode,struct file *file,
unsigned int cmd,unsigned long arg)
{
if (arg > 4)
return -EINVAL;

switch (cmd)
{
case LEDON:
s3c2410_gpio_setpin(led_table[arg], 0);
printk("led_table[%d]\ton\n",arg);
break;

case LEDOFF:
s3c2410_gpio_setpin(led_table[arg], 1);
printk("led_table[%d]\toff\n",arg);
break;

default:
break;
}

return 0;
}

static struct file_operations led_ops = {
.owner = THIS_MODULE,
.open = led_open,
.ioctl = led_ioctl,

};


int __init led_init(void)
{
/***动态分配led设备号***/
alloc_chrdev_region(&ledid,0,1,"myled");

/***注册led设备***/
led_cdev=cdev_alloc();
cdev_init(led_cdev,&led_ops);
cdev_add(led_cdev,ledid,1);

/***自动创建led设备文件***/
led_class = class_create(THIS_MODULE,"myled_class");
device_create(led_class,NULL,ledid,NULL,"myled");

printk("LEDS initialized.\n");

return 0;
}


void __exit led_exit(void)
{
/***注销led设备***/
cdev_del(led_cdev);

/***注销led设备号***/
unregister_chrdev_region(ledid,1);
device_destroy(led_class,ledid);
class_destroy(led_class);
}

module_init(led_init);
module_exit(led_exit);

Makefile:
ifneq ($(KERNELRELEASE),)

obj-m := myleds_mini2440.o

else
KDIR := /kernel/linux-2.6.32
#KDIR := /lib/modules/2.6.34/build
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


测试程序:
ledtest_mini2440.c
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/input.h>
#include<stdlib.h>

#include "myleds_mini2440.h"

int main(int argc, char **argv)
{
if (argc != 3)
{
printf("Usage:\n");
printf(" <LEDON/LEDOFF>\t<led_no>\t<on/off>\n");
printf(" led_no = 1, 2, 3, 4\n");
}

int fd;
fd = open("/dev/myled", O_RDWR);
if (fd < 0) 
{
printf("Can't open /dev/myleds\n");
return -1;
}

unsigned int led_no;
led_no = strtoul(argv[1], 0, 0) - 1;
if (led_no > 5)
goto err;
/*{
close(fd);
printf("Usage:\n");
printf(" %s\t<led_no>\t<on/off>\n",argv[0]);
printf(" led_no = 1, 2, 3, 4\n");
return -1;
}*/

if (!strcmp(argv[2],"on"))
{
ioctl(fd,LEDON,led_no);
printf("led %d has been on",led_no);
}
else if (!strcmp(argv[2],"off"))
{
ioctl(fd,LEDOFF,led_no);
printf("led %d has been off",led_no);
}

else
goto err;

return 0;

err:
close(fd);
printf("Usage:\n");
printf(" %s\t<led_no>\t<on/off>\n",argv[0]);
printf(" led_no = 1, 2, 3, 4\n");
return -1;
}
如果内核版本是linux2.6.29,要稍作修改,否则会出现S3C2410_GPB5' undeclared here (not in a function)的错误。

供参考:http://blog.sina.com.cn/s/blog_ba08e8e00101ckja.html

阅读(87) | 评论(0) | 转发(0) |
0

上一篇:开发板开机自动运行QT应用程序

下一篇:修改开发板IP地址并使其启动有效

相关热门文章
  • OK6410(256M RAM ,1G SLC NA...
  • 积分制管理加速了健康企业文化...
  • 麻将桌遥控器
  • 基于2.6.35内核的OV9650摄像头...
  • 麻将机技术打法
  • shell中字符串操作
  • shell中的特殊字符
  • stagefright与opencore对比
  • linux守护进程的几个关键地方...
  • Android常用的一些make命令...
  • 我的ChinaUnix博客被锁定了,...
  • 虚拟机中ubuntu无线连接问题...
  • IBM DS3400 盘阵怎么查看是单...
  • 启动auditd时,报错如下,怎么...
  • CGSL系统中root密码正确,但无...
给主人留下些什么吧!~~
原创粉丝点击