三星S5PV210Android系统下LED灯驱动程序
驱动文件:hello.c/************************************************LED的驱动,在Real210A开发板上做测试维护记录: 2011-10-31 V1.0 linux内核:2.6.35.7驱动用法: 设备名称:Real210-led 点亮一个灯:LED_ON
驱动文件:hello.c
/************************************************
LED的驱动,在Real210A开发板上做测试
维护记录: 2011-10-31 V1.0
linux内核:2.6.35.7
驱动用法:
设备名称:Real210-led
点亮一个灯:LED_ON
熄灭一个灯:LED_OFF
点亮所有灯:ALL_LED_ON
熄灭所有灯:ALL_LED_OFF
*************************************************/
#include<linux/init.h>
#include<linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <linux/device.h>
#include <linux/gpio.h>
#define DEVICE_NAME "Real210-led" /* 设备名称 */
static int LED_Major = 0; /* 主设备号 ,系统自动分配*/
#define LED_OFF 0
#define LED_ON 1
#define ALL_LED_OFF 3
#define ALL_LED_ON 4
/* 用来指定LED所用的GPIO引脚 */
static unsigned long led_table [] =
{
//S5PV210_GPH0(_nr);
//在头文件“~/kernel/arch/arm/mach-s5pv210/include/mach/”
S5PV210_GPH0(6),
S5PV210_GPH0(7),
S5PV210_GPH0(4),
S5PV210_GPH0(5),
};
static int Real210_led_open(struct inode *inode, struct file *file)
{
// MOD_INC_USE_COUNT;
printk("Real210-LED Driver Open Called!\n");
return 0;
}
static int Real210_led_release(struct inode *inode, struct file *file)
{
// MOD_DEC_USE_COUNT;
printk("Real210-LED Driver Release Called!\n");
return 0;
}
static int Real210_led_ioctl( struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
int i;
if (arg > 4)
{
return -EINVAL;
}
switch(cmd)
{
case LED_ON: //set the pin
gpio_set_value (led_table[arg], 0);
break;
case LED_OFF: //clr the pin
gpio_set_value (led_table[arg], 1);
break;
case ALL_LED_ON: //set all pin
for (i = 0; i < 4; i++)
gpio_set_value (led_table[i], 0);
break;
case ALL_LED_OFF: //clr all pin
for (i = 0; i < 4; i++)
gpio_set_value (led_table[i], 1);
break;
default:
return -EINVAL;
}
}
static struct file_operations Real210_led_fops =
{
.owner = THIS_MODULE,
.open = Real210_led_open,
.release = Real210_led_release,
.ioctl = Real210_led_ioctl,
};
static struct class *led_class;
static int __init Real210_led_init(void)
{
printk("Real210 LED DRIVER MODULE INIT\n");
LED_Major = register_chrdev(0, DEVICE_NAME, &Real210_led_fops);
if (LED_Major < 0)
{
printk(DEVICE_NAME " can't register major number\n");
return LED_Major;
}
printk("register Real210-LED Driver OK! Major = %d\n", LED_Major);
led_class = class_create(THIS_MODULE, DEVICE_NAME);
if(IS_ERR(led_class))
{
printk("Err: failed in Real210-LED class. \n");
return -1;
}
device_create(led_class, NULL, MKDEV(LED_Major, 0), NULL, DEVICE_NAME);
//IO初始化
//IO方向配置
gpio_direction_output (S5PV210_GPH0(6), 1);
gpio_direction_output (S5PV210_GPH0(7), 1);
gpio_direction_output (S5PV210_GPH0(4), 1);
gpio_direction_output (S5PV210_GPH0(5), 1);
//IO初始化
gpio_set_value (S5PV210_GPH0(6), 1);
gpio_set_value (S5PV210_GPH0(7), 0);
printk(DEVICE_NAME " initialized\n");
return 0;
}
static void __exit Real210_led_exit(void)
{
printk("Real210 LED DRIVER MODULE EXIT\n");
unregister_chrdev(LED_Major, DEVICE_NAME);
device_destroy(led_class, MKDEV(LED_Major, 0));
class_destroy(led_class);
}
module_init(Real210_led_init);
module_exit(Real210_led_exit);
//MODULE_LICENSE("Dual BSD/GP");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("wzl");
MODULE_DESCRIPTION("This is an example of hello drivers");
MODULE_ALIAS("A simplest module.");
Makefile文件:
ifneq ($(KERNELRELEASE),)
obj-m := hello.o
else
KDIR := /home/light/A8Android/android_gingerbread_realv210_ver_1_0/out/target/product/smdkv210/obj/KERNEL
all:
make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-eabi-
clean:
rm -f *.ko *.o *.mod.o *.mod.c *.symvers
endif
测试文件:led.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include <sys/ioctl.h>
int main(int argc, char **argv)
{
unsigned int on;
unsigned int led_num;
int fd;
printf("Enter the test led !\n");
fd = open("/dev/Real210-led", 0);
if (fd < 0)
{
perror("open device led");
exit(1);
}
ioctl(fd, 1, 0); //可修改本句代码
close(fd);
return 0;
}
Makefile文件:
CROSS=arm-linux-
all: led
led:led.c
$(CROSS)gcc -o led led.c -static
$(CROSS)strip led
clean:
@rm -vf led *.o *~
说明:
编译驱动时候应该指明内核源码编译后的中间文件。编译器用的是arm-eabi-gcc 4.4.3
编译测试程序时应该添加-static声明。编译器arm-linux-gcc 4.4.1
更多推荐
所有评论(0)