目前的linux版本的许多驱动都是基于设备模型,LED也不例外。
简单地说,设备模型就是系统认为所有的设备都是挂接在总线上的,而要使设备工作,就需要相应的驱动。设备模型会产生一个虚拟的文件系统——sysfs,它给用户提供了一个从用户空间去访问内核设备的方法,它在linux里的路径是/sys。如果要写程序访问sysfs,可以像读写普通文件一样来操作/sys目录下的文件。
对于基于s3c2440的开发板来说,linux-3.6.6自动的LED驱动只需改变连接LED的IO端口,及高、低电平响应即可。我的开发板的四个LED连接在了B口的5到8引脚上,当输出低电平时被点亮,与linux自带的LED驱动一致,因此无需做任何改动。
使用menuconfig来配置内核,这里要加上对LED模块的内容,即:
Device Drivers--->
[*]LED Support--->
<*>LED Class Support
<*>LED Support for Samsung S3C24xx GPIO LEDs
编译内核,并把编译好的内核下载到开发板上,运行:
[root@zhaocj /]#ls
bin etc lib proc sys usr
dev home linuxrc sbin temp
[root@zhaocj /]#cd sys
[root@zhaocj /sys]#ls
block class devices fs module
bus dev firmware kernel power
进入sys目录下,我们看到该目录下有一些子目录。
[root@zhaocj /sys]#cd class
[root@zhaocj class]#ls
backlight hidraw leds rtc vc
bdi hwmon mem sound video_output
block i2c-adapter misc spi_master vtconsole
firmware i2c-dev mmc_host spidev watchdog
gpio input mtd tty
graphics lcd net udc
进入class目录,我们会看到在该目录下有一些设备,其中leds就是本次我们要操作的LED。
[root@zhaocj class]#cd leds
[root@zhaocj leds]#ls
backlight led1 led2 led3 led4
在leds目录下,会看到四个LED的目录,这就是开发板上的四个LED。另外backlight目录是关于LCD的背光,与LED无关。
[root@zhaocj leds]#cd led1
[root@zhaocj led1]#ls
brightness max_brightness subsystem
device power uevent
brightness文件就是LED设备,对其进行操作就可完成对LED的控制。
[root@zhaocj led1]#cat brightness
0
可以看出led1当前的状态是关闭。(0表示关闭,1表示打开)
[root@zhaocj led1]#cat >brightness< > eof #[root@zhaocj led1]# 向brightness写1,表示打开LED。这时led1会被点亮。 当然,我们也可以编写用户程序来控制开发板上的四个LED /********************** ****leds.c************** **********************/ #include #include #include #include #include #include #include int main(int argc, char *argv[]) { int fd, no; /*判断是要控制哪个LED,并打开相应的文件*/ no=(int)argv[1][3]-48; switch(no) { case 1: fd = open('/sys/class/leds/led1/brightness', O_RDWR); break; case 2: fd = open('/sys/class/leds/led2/brightness', O_RDWR); break; case 3: fd = open('/sys/class/leds/led3/brightness', O_RDWR); break; case 4: fd = open('/sys/class/leds/led4/brightness', O_RDWR); break; default: return -1; } if(fd<0) { printf('can not open file.n'); return -1; } /*完成打开或关闭LED操作*/ if(!strcmp(argv[2],'on')) write(fd, '1', 1); else if(!strcmp(argv[2],'off')) write(fd, '0', 1); close(fd); return 0; } 上面的程序只做简单测试之用。编译该文件: arm-linux-gcc -o leds leds.c 把leds文件下载到temp目录下,运行: [root@zhaocj /temp]# ./leds led2 on 则点亮led2。 [root@zhaocj /temp]# ./leds led2 off 则关闭led2。 下面我就来简单分析一下linux自带的LED子系统。 在mach-zhaocj2440.c文件,创建了LED设备,如下: /* LEDS */ static struct s3c24xx_led_platdata zhaocj2440_led1_pdata = { .name = 'led1', .gpio = S3C2410_GPB(5), .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE, .def_trigger = 'heartbeat', }; static struct s3c24xx_led_platdata zhaocj2440_led2_pdata = { .name = 'led2', .gpio = S3C2410_GPB(6), .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE, .def_trigger = 'nand-disk', }; static struct s3c24xx_led_platdata zhaocj2440_led3_pdata = { .name = 'led3', .gpio = S3C2410_GPB(7), .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE, .def_trigger = 'mmc0', }; static struct s3c24xx_led_platdata zhaocj2440_led4_pdata = { .name = 'led4', .gpio = S3C2410_GPB(8), .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE, .def_trigger = '', }; 定义了四个LED数据,名字分别为led1~led4,这就是我们在leds目录下看到这四个子目录。它们所连接的引脚分别为B口的5~8,这是由S3C2410_GPB()宏定义完成的。标识S3C24XX_LEDF_ACTLOW表示的是低电平有效,S3C24XX_LEDF_TRISTATE表示的三态无效。另外def_trigger表示的是触发控制,如我们对nand进行读写操作时,led2会不停的闪,在这里我们没有用到这个功能,暂时不用理会。 static struct platform_device zhaocj2440_led1= { .name = 's3c24xx_led', .id = 1, .dev = { .platform_data = &zhaocj2440_led1_pdata, }, }; static struct platform_device zhaocj2440_led2= { .name = 's3c24xx_led', .id = 2, .dev = { .platform_data = &zhaocj2440_led2_pdata, }, }; static struct platform_device zhaocj2440_led3= { .name = 's3c24xx_led', .id = 3, .dev = { .platform_data = &zhaocj2440_led3_pdata, }, }; static struct platform_device zhaocj2440_led4= { .name = 's3c24xx_led', .id = 4, .dev = { .platform_data = &zhaocj2440_led4_pdata, }, }; 上面则创建了总线平台设备,四个LED的设备名称都是s3c24xx_led,子设备id分别从1到4,设备数据则是上面定义的四个LED数据。然后把这四个LED设备再添加到开发板的设备数组中,即: static struct platform_device *zhaocj2440_devices[]__initdata = { …… &zhaocj2440_led1, &zhaocj2440_led2, &zhaocj2440_led3, &zhaocj2440_led4, …… }; 最后,在开发板系统初始化过程中,再把设备数组中的设备逐一注册到系统总线上,即: static void __init zhaocj2440_init(void) { …… platform_add_devices(zhaocj2440_devices,ARRAY_SIZE(zhaocj2440_devices)); …… } 这样就完成了LED设备的创建。 光有设备还不能工作,任何一个设备的运行还需要与之相对应的驱动。对于基于s3c24xx的LED来说,它的驱动是在drivers/leds目录下Leds-s3c24xx.c文件内创建的,即: static struct platform_driver s3c24xx_led_driver = { .probe = s3c24xx_led_probe, .remove = s3c24xx_led_remove, .driver = {
上一篇:LCD驱动移植在在mini2440(linux2.6.29)和FS4412(linux3.14.78)上实现对比(deep dive)
下一篇:Ubuntu 12.04嵌入式交叉编译环境arm-linux-gcc搭建过程图解
推荐阅读最新更新时间:2026-03-25 15:07
- 使用 Analog Devices 的 ADP3334 的参考设计
- LTC3588IMSE-1 5V 至 16V 太阳能供电 2.5V 电源的典型应用电路,具有用于增加输出能量存储和电池备份的超级电容器
- XRP7659、1.5A DC 至 DC 非同步降压稳压器的典型应用
- 使用 ON Semiconductor 的 NCP3120MNTX 的参考设计
- MAXREFDES1003:150mA、4通道、LED驱动器,SEPIC配置
- LTC4223-2 演示板,用于 AMC 的双电源热插拔控制器(故障后自动重试)
- MC33072ADR2G 运算放大器用作晶体管驱动器的典型应用
- 使用 Diodes Incorporated 的 AP1509-12S 的参考设计
- NCP382HD10AAGEVB:单输入双输出高侧配电开关评估板
- 使用 Analog Devices 的 AD7730 的参考设计



dm9000cep网卡通信
正点原子I.MX6U嵌入式Qt开发指南
现代雷达系统的信号设计
BFR340T






京公网安备 11010802033920号