十二.LED驱动程序
时间:2009-03-20 来源:chenkuizhong
一.编写模块的初始化函数:
static int __init s3c24xx_leds_init(void)
{
int ret;
ret = register_chrdev(LED_MAJOR, DEVICE_NAME, &s3c24xx_leds_fops);
if(ret < 0) {
printk(DEVICE_NAME "can't register major number\n");
return ret;
}
printk(DEVICE_NAME "initialized\n");
return 0;
}
二.编写模块的撤销函数
static void __exit s3c24xx_leds_exit(void)
{
unregister_chrdev(LED_MAJOR, DEVICE_NAME);
}
三.指定驱动程序的初始化函数和卸载函数
module_init(s3c24xx_leds_init);
module_exit(s3c24xx_leds_exit);
四.定义s3c24xx_leds_fops:
static sturct file_operations s3c24xx_leds_fops = {
.owner = THIS_MODULE,
.open = s3c24xx_leds_open,
.ioctl = s3c24xx_leds_ioctl
};
五.编写s3c24xx_leds_open函数:
static int s3c24xx_leds_open(struct inode *inode, struct file *file)
{
int i;
for(i=0; i<4; i++) {
s3c2410_gpio_cfpin(led_table[i], led_cfg_table[i])
}
return 0;
}
六.编写s3c24xx_leds_ioctl函数:
static int s3c24xx_leds_iotcl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
if (arg > 4) {
return -EINVAL;
}
switch(cmd) {
case IOCTL_LED_ON:
s3c2410_gpio_setpin(led_table[arg], 0);
return 0;
case IOCTL_LED_OFF:
s3c2410_gpio_setpin(led_table[arg], 1);
return 0;
default:
return -EINVAL;
}
}
七.加入描述信息:
MODULE_AUTHOR("ckz");
MODULE_DESCRIPTION("S3C2440 LED Driver");
MODULE_LICENSE("GPL");
八.加入头文件信息:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <asm/arch/regs-gpio.h>
#include <asm/hardware.h>
九.加入宏定义:
#define DEVICE_NAME "leds" /* 加载模式后,执行”cat /proc/devices”命令看到的设备名称 */
#define LED_MAJOR 231 /* 主设备号 */
/* 应用程序执行ioctl(fd, cmd, arg)时的第2个参数 */
#define IOCTL_LED_ON 0
#define IOCTL_LED_OFF 1
/* 用来指定LED所用的GPIO引脚 */
static unsigned long led_table [] = {
S3C2410_GPB5,
S3C2410_GPB6,
S3C2410_GPB7,
S3C2410_GPB8,
};
/* 用来指定GPIO引脚的功能:输出 */
static unsigned int led_cfg_table [] = {
S3C2410_GPB5_OUTP,
S3C2410_GPB6_OUTP,
S3C2410_GPB7_OUTP,
S3C2410_GPB8_OUTP,
};
十.把源代码s3c24xx_leds.c文件放入内核drivers/char子目录下,在drivers/char/Makefile中增加下面一行Obj-m += s3c24xx_leds.o
十一. 在内核根目录上执行 make modules,可以生成drivers/char/s3c24xx_leds.ko,把它放到文件系统的/lib/modules/2.6.22目录下,就可以使用insmod s3c24xx_leds, rmmod s3c24xx_leds
十二.编写驱动测试程序:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#define IOCTL_LED_ON 0
#define IOCTL_LED_OFF 1
int main(int argc, char **argv)
{
unsigned int led_no;
int fd = -1;
fd = open("/dev/leds", 0);
if (fd < 0) {
printf("Can't open /dev/leds\n");
return -1;
}
led_no = strtoul(argv[1], 0 , 0) - 1;
if (led_no > 3) {
printf("Led number too larger\n");
close(fd);
return 0;
}
if(!strcmp(argv[2], "on")) {
ioctl(fd, IOCTL_LED_ON, led_no);
} else {
ioctl(fd, IOCTL_LED_OFF, led_no);
}
close(fd);
return 0;
}
十三.测试程序的Makefile:
CROSS=arm-linux-
all: led_test
led_test: led_test.c
$(CROSS)gcc -o $@ led_test.c -static
clean:
@rm -rf led_test *.o
十四.把生成led_test程序放到文件系统中
十五.在板子的根目录中建立设备文件:
Mknod /dev/leds c 231 0
测试:
Led_test 1 on
Led_test 1 off