基于S3C2440的linux-3.6.6移植——LED驱动

发布时间:2024-08-09  

目前的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<> 1

> 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,

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

相关文章

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>