分类: LINUX
2009-03-09 16:53:21
LED是由CPU的GPIO(通用可编程IO口)控制的。GPIO一般由两组寄存器控制,即一组控制寄存器和一组数据寄存器。控制寄存器可设置GPIO口的工作方式为输入或输出。当引脚为输出时,向数据寄存器的对应位写入1和0会分别在引脚上产生高低电平,对led,bell的控制就是这样的;当引脚设置为输入时,读取数据寄存器的对应位可获得引脚上响应电平信号,按键操作就是这样,做LED驱动程序主要是做对led对应的GPIO口进行操作的函数,还包括定义的设备操作的结构体,驱动编写比较简单,下面是驱动操作源码:
#include
#include #include #include #include #include #include #include #include #include #include #define DEVICE_NAME "leds" //定义设备名 #define LED_MAJOR 241 //手动定义主设备号 //定义要操作的设备,把每一个led作为结构体的一个成员 static unsigned long led_table [] = { S3C2410_GPD8, S3C2410_GPD9, S3C2410_GPD10, S3C2410_GPD11, }; //对设备进行设置,结构体的每一个成员是对对应led的设置 static unsigned int led_cfg_table [] = { S3C2410_GPD8_OUTP, S3C2410_GPD9_OUTP, S3C2410_GPD10_OUTP, S3C2410_GPD11_OUTP, }; static int s3c2410_leds_open(struct inode *inode,struct file *file) { int i; for(i=0;i<4;i++) { s3c2410_gpio_cfgpin(led_table[i],led_cfg_table[i]); } return 0; } //设备驱动程序中对设备的I/O通道进行管理的函数,用来实现对led的操作 static int s3c2410_leds_ioctl( struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { if (arg > 4) { return -EINVAL; } switch(cmd) { case 0: s3c2410_gpio_setpin(led_table[arg], !cmd); return 0; case 1: s3c2410_gpio_setpin(led_table[arg], !cmd); return 0; default: return -EINVAL; } } static struct file_operations s3c2410_leds_fops = { .owner = THIS_MODULE, .open = s3c2410_leds_open, .ioctl = s3c2410_leds_ioctl, }; //模块加载函数 static int __init s3c2410_leds_init(void) { int ret; int i; //注册设备号 ret = register_chrdev(LED_MAJOR, DEVICE_NAME, &s3c2410_leds_fops); if (ret < 0) { printk(DEVICE_NAME " can't register major number\n"); return ret; } //devfs_mk_cdev(MKDEV(LED_MAJOR, 0), S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, DEVICE_NAME); for (i = 0; i < 4; i++) { s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]); s3c2410_gpio_setpin(led_table[i], 1); } printk(DEVICE_NAME " initialized\n"); return 0; } //模块卸载函数 static void __exit s3c2410_leds_exit(void) { //devfs_remove(DEVICE_NAME); unregister_chrdev(LED_MAJOR, DEVICE_NAME); } module_init(s3c2410_leds_init); module_exit(s3c2410_leds_exit); MODULE_LICENSE("GPL"); 把驱动加载进内核,采用静态加载方式:
1.s
在Makefile里面加入
obj-$(CONFIG_S3C2410_LEDS) += leds.o
在Congfig里面加入
config S3C2410_LEDS
tristate "S3C2410 LEDs Driver"
depends on ARCH_S
help
S3C2410 User leds.
2. 重新配置内核加入led支持
Device Drivers --->
Character devices --->
<*> S3C2410 LEDs Driver
编译内核生成内核镜像下到板子里面就可以了
=========================================
linux应用程序代码:
//ledshow.c
#include
#include
#include
#include "stdio.h"
#include "sys/types.h"
#include "sys/ioctl.h"
#include "stdlib.h"
#include "termios.h"
#include "sys/stat.h"
#include "fcntl.h"
#include "sys/time.h"
int main()
{
int on=1;
int led;
int fd;
fd = open("/dev/leds", 0);
if (fd < 0) {
perror("open device leds");
exit(1);
}
printf("leds test show. press ctrl+c to exit \n");
while(1)
{
for(led=0;led<5;led++)
{
ioctl(fd, on, led);
usleep(50000);
}
on=!on;
}
close(fd);
return 0;
} |