S3C2440 led 驱动的编写 我用的板子使用引脚GPB5~7外节三个LED
此驱动参考卫东山的书籍编写的
操作步骤:
(1)、引脚功能设置位输出。
(2)、要点亮LED,令引脚输出0。
(3)、要熄灭LED,令引脚输出1。
1、LED驱动代码。
static 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 mahor
number\n");
return
ret;
}
printk(DEVICE_NAME " initialized\n");
return
0;
}
static void __exit s3c24xx_leds_eixt(void)
{
unregister_chardev(LED_MAJOR,
DEVICE_NAME);
}
module_init(s3c24xx_leds_init);
module_exit(s3c24xx_leds_exit);
static struct file_operations s3c24xx_leds_fops={
.owner = THIS_MODULE,
.open =
s3c24xx_leds_open,
.ioctl =
s3c24xx_leds_ioctl.
};
static init s3c24xx_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;
}
static int s3c24xx_leds_ioctl(
struct inode * inode,
struct file * file,
unsigned int cmd,
unsigned ling arg)
{
if(arg > 4)
{
return -EINVAL;
}
switch(cmd)
{
case IOCTL_LED_ON:
s3c2410_gpio_setpin(led_table[arg],0);
return 0;
cas3 IOCTL_LED_OFF:
s3c2410_gpio_setpin(led_table[arg],1)
return
0;
default:
return -EINVAL;
}
}
最后将s3c24xx_leds.c 文件放到内核 /devers/char
子目录下,在drivers/char/Makefile 中增加如下一行:
obj -m += s3c24xx_leds.o
然后在内核根目录下执行make modules
就可以生成模块、drivers/char/s3c24xx_leds.ko。把它放到单板根目录/lib/modules/2.6.22.6/目录下,就可以用
insmod s3c24xx_leds 和 rmmod s3c24xx_leds命令进行加载和卸载了。
2、led.c 源码及驱动测试程序源码
#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"
#define
LED_MAJOR
231
#define
IOCTL_LED_ON
0
#define IOCTL_LED_OFF 1
static unsigned long led_table [] = {
S3C2410_GPB5,
S3C2410_GPB6,
S3C2410_GPB7,
};
static unsigned int led_cfg_table [] = {
S3C2410_GPB5_OUTP,
S3C2410_GPB6_OUTP,
S3C2410_GPB7_OUTP,
};
static int s3c24xx_leds_open(struct inode *inode, struct file
*file)
{
int i;
for (i = 0;
i < 4; i++) {
// 设置GPIO引脚的功能:本驱动中LED所涉及的GPIO引脚设为输出功能
s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);
}
return
0;
}
static int s3c24xx_leds_ioctl(
struct inode
*inode,
struct file
*file,
unsigned int
cmd,
unsigned
long arg)
{
if (arg
> 4) {
return -EINVAL;
}
switch(cmd)
{
case
IOCTL_LED_ON:
// 设置指定引脚的输出电平为0
s3c2410_gpio_setpin(led_table[arg], 0);
return 0;
case
IOCTL_LED_OFF:
// 设置指定引脚的输出电平为1
s3c2410_gpio_setpin(led_table[arg], 1);
return 0;
default:
return -EINVAL;
}
}
static struct file_operations s3c24xx_leds_fops = {
.owner =
THIS_MODULE,
.open
=
s3c24xx_leds_open,
.ioctl =
s3c24xx_leds_ioctl,
};
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);
MODULE_AUTHOR("http://www.100ask.net");
// 驱动程序的作者
MODULE_DESCRIPTION("S3C2410/S3C2440 LED
Driver"); // 一些描述信息
MODULE_LICENSE("GPL");
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#define
IOCTL_LED_ON
0
#define IOCTL_LED_OFF 1
void usage(char *exename)
{
printf("Usage:\n");
printf(" %s
<led_no>
<on/off>\n", exename);
printf("
led_no = 1, 2, 3 or 4\n");
}
int main(int argc, char **argv)
{
unsigned int
led_no;
int fd =
-1;
if (argc !=
3)
goto err;
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; //
操作哪个LED?
if (led_no
> 3)
goto err;
if
(!strcmp(argv[2], "on")) {
ioctl(fd, IOCTL_LED_ON,
led_no); //
点亮它
} else if
(!strcmp(argv[2], "off")) {
ioctl(fd, IOCTL_LED_OFF,
led_no); // 熄灭它
} else
{
goto err;
}
close(fd);
return
0;
err:
if (fd
> 0)
close(fd);
usage(argv[0]);
return
-1;
}
|