linux下如何点亮LED

来源:互联网 发布:alien skin插件mac 编辑:程序博客网 时间:2024/05/18 18:19

linux究竟是如何点亮mini2440上的LED呢?没有操作系统的单片机系统中,操作相关寄存器就可以点亮LED。为了弄明白点灯问题,现对linux点灯过程做出大胆的猜测,文中错误还请linux老鸟不令赐教!
友善提供了led控制程序可以点亮或熄灭指定LED:
执行:led 1 1
点亮led1
执行:led 1 0
熄灭led1

友善提供的led控制程序的源代码(为了简化,剃除了其中的错误处理):
led.c

01 #include <stdio.h>
02 #include <stdlib.h>
03 #include <unistd.h>
04 #include <sys/ioctl.h>
05 
06 int main(int argc, char **argv)
07 {
08     int on;
09     int led_no;
10     int fd;
11     sscanf(argv[1], "%d", &led_no);
12     sscanf(argv[2],"%d", &on);
13 
14     fd = open("", 0);
15 
16     ioctl(fd, on, led_no);
17 }

led程序打开/dev/leds驱动文件,调用ioctl函数将新的led状态写入驱动文件中。

led驱动程序是linux内核的一部分,它可以直接抄作最底层的寄存器。友善也提供了led驱动程序源代码。led驱动保存在linux-2.6.32.2/drivers/char/mini2440_leds.c

01 static int sbc2440_leds_ioctl(
02     struct inode *inode, 
03     struct file *file, 
04     unsigned int cmd, 
05     unsigned long arg)
06 {
07     switch(cmd{
08     case 0:
09     case 1:
10         if (arg > 4{
11             return -EINVAL;
12         }
13         s3c2410_gpio_setpin(led_table[arg], !cmd);
14         return 0;
15     default:
16         return -EINVAL;
17     }
18 }
19 
20 static struct file_operations dev_fops = {
21     .owner    =    THIS_MODULE,
22     .ioctl    =    sbc2440_leds_ioctl,
23 };
内核将 led.c 中函数ioctl(fd, on, led_no)参数传递给sbc2440_leds_ioctl,并执行sbc2440_leds_ioctl函数。sbc2440_leds_ioctl中执行s3c2410_gpio_setpin函数修改led状态。继续追踪!!
按照手册指引,在linux-2.6.32.2/arch/arm/plat-s3c24xx/gpio.c中找到了
s3c2410_gpio_setpin。
gpio.c
01 void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
02 {
03     void __iomem *base = S3C24XX_GPIO_BASE(pin);
04     unsigned long offs = S3C2410_GPIO_OFFSET(pin);
05     unsigned long flags;
06     unsigned long dat;
07 
08     local_irq_save(flags);
09 
10     dat = __raw_readl(base + 0x04);      //读取之前状态
11     dat &= ~(1 << offs);                 //指定复位指定GPIO
12     dat |= to << offs;                   //设置指定GPIO
13     __raw_writel(dat, base + 0x04);      //将GPIO新状态写入GPIO控制器
14 
15     local_irq_restore(flags);
16 }
执行
__raw_writel(dat, base + 0x04)终于点亮了LED。

如何在成千上万的源代码中找到自己需要的.h.c文件呢?
{2010-09-27 11:47 发布在百度空间,2011-03-29 22:06 搬至CSDN}