micro2440写的第一个驱动-LED

发布者:leader5最新更新时间:2022-07-08 来源: csdn关键字:micro2440  驱动  LED 手机看文章 扫描二维码
随时随地手机看文章

这是学习驱动开发中,在MICRO 2440开发板上写的第一个驱动程序。实现对S3C2440的GPIO的控制,是一个ARM-LINUX上最简单的驱动。本驱动通过S3C2440的GPB5~8控制4个LED,属MISC(混杂)驱动,其实MISC也是一种特殊的字符驱动,只不过是把主设备号为10的字符驱动归类为MISC类驱动。


MISC类驱动结构如下:


static struct miscdevice misc = {

.minor = MISC_DYNAMIC_MINOR,

.name = DEVICE_NAME,

.fops = &dev_fops,

  };


minor为指定次设备号,等于MISC_DYNAMIC_MINOR表示为动态获取次设备号。


name为设备名。


fops为 file_operations结构,设备的操作函数指针集合。


file_operations结构:


static struct file_operations dev_fops = {

.owner = THIS_MODULE,

.ioctl = sbc2440_leds_ioctl,

  };


该设备省略了OPEN和RELESE操作函数,即默认为打开状态。我们只需要对IO口操作就可以实现LED灯的亮和灭,所以只需要一个IOCTL操作函数就可以满足要求了。


GPIO口的设置:


S3C2440设置GPIO口主要是设置3个寄存器。分别为GPxCON, GPxDAT, GPxUP(x=A….J)。


GPxCON用于设置IO口的功能,每两位对应一个IO口,输入=00,输出=01;特殊功能=10;


GPxDAT为IO口的数据寄存器,每一位对应一个IO口。


GPxUP为是否使用上拉电阻,0为使用,注意的是并不是每组IO口都有内部集成上拉电阻,如果没有集成,则没该寄存器。


设置这三个寄存器相对应的函数为:s3c2410_gpio_cfgpin,s3c2410_gpio_setpin。


驱动程序代码:


加载函数:


static int __init dev_init(void)

{

int ret;

 

int i;

for (i = 0; i < 4; i++) {

s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);

s3c2410_gpio_setpin(led_table[i], 0);

}

 

ret = misc_register(&misc);

 

printk (DEVICE_NAME"tinitializedn");

 

return ret;

}


在加载函数里,主要完成的就是初始化IO口和注册一个MISC类设备,MISC类在misc_register这个调用里,会帮我们根据struct miscdevice里面的成员帮我们注册一个字符设备,所以我们这个MISC的驱动加载函数比较短。


卸载函数:


static void __exit dev_exit(void)

  {

misc_deregister(&misc);

  }


在卸载函数里,只需要调用misc_deregister卸载掉MISC设备就OK了。


IOCTL函数:


static int sbc2440_leds_ioctl(

struct inode *inode, 

struct file *file, 

unsigned int cmd, 

unsigned long arg)

{

switch(cmd) {

case 0:

case 1:

if (arg > 4) {

return -EINVAL;

}

s3c2410_gpio_setpin(led_table[arg], !cmd);

return 0;

default:

return -EINVAL;

}

}


在这个MISC设备里,主要用到的是控制函数。通过之前介绍的操作IO寄存器的函数,我们就可以很轻松地对IO口进行控制。


编译、加载:


把源码放进/drivers/char下。


修改内核源码目录linux-2.6.32.2/drivers/char下的Kconfig文件,添加以下文本把驱动程序加进代码树。


config LOCKER_LEDS             


tristate "Locker_Liang leds"


depends on MACH_MINI2440


default m if MACH_MINI2440


help


Locker_Liang leds.


config"为定义了一新的配置选项。Tristate为选项名称。depends on为基于哪类处理器。Default表示如果上一个处理器不可用则默认选这个。Help为帮助信息,下一行为帮助信息。Kconfig的语法详细说明看Kconfig文档。


修改Makefile,添加


obj-$(CONFIG_LOCKER_LEDS)+= MY_leds.o


这里注意的是LOCKER_LEDS一定要和Kconfig上的相同,.o文件也要和源文件名相同。


在linux-2.6.32.2目录输入make menuconfig,在 Device Drivers -》Character devices中选中我们添加的模块,选为M,即编译为模块方式。


输入make modules编译模块。这时在/drivers/char就会生成一个MY_leds.ko文件。把该文件拷贝到开发板上,输入insmod MY_leds.ko 就可以加载模块到内核中。并且自动生成设备文件。输入rmmod MY_leds.ko可以卸载模块。


这样做就可以对设备操作了,但还有一个问题就是复位后,还要重新加载驱动模块和重新生成设备文件。这时我们可以在/etc/init.d/rcS文件里,加上加载驱动模块和生成设备文件的命令,这样每次开机后都会自动完成设置。


完整代码:


#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

 

#define DEVICE_NAME "MY_leds"

 

static unsigned long led_table [] = {

S3C2410_GPB(5),

S3C2410_GPB(6),

S3C2410_GPB(7),

S3C2410_GPB(8),

};

 

static unsigned int led_cfg_table [] = {

S3C2410_GPIO_OUTPUT,

S3C2410_GPIO_OUTPUT,

S3C2410_GPIO_OUTPUT,

S3C2410_GPIO_OUTPUT,

};

 

static int sbc2440_leds_ioctl(

struct inode *inode, 

struct file *file, 

unsigned int cmd, 

unsigned long arg)

{

switch(cmd) {

case 0:

case 1:

if (arg > 4) {

return -EINVAL;

}

s3c2410_gpio_setpin(led_table[arg], !cmd);

return 0;

default:

return -EINVAL;

}

}

 

static struct file_operations dev_fops = {

.owner = THIS_MODULE,

.ioctl = sbc2440_leds_ioctl,

};

 

static struct miscdevice misc = {

.minor = MISC_DYNAMIC_MINOR,

.name = DEVICE_NAME,

.fops = &dev_fops,

};

 

static int __init dev_init(void)

{

int ret;

 

int i;

for (i = 0; i < 4; i++) {

s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);

s3c2410_gpio_setpin(led_table[i], 0);

}

 

ret = misc_register(&misc);

 

printk (DEVICE_NAME"tinitializedn");

 

return ret;

}

 

static void __exit dev_exit(void)

{

misc_deregister(&misc);

}

 

module_init(dev_init);

module_exit(dev_exit);

MODULE_LICENSE("GPL");

MODULE_AUTHOR("Locker_Liang Inc.");


测试程序:


  #include

  #include

  #include

  #include

  

  #define IOCTL_LED_ON    1

  #define IOCTL_LED_OFF   0

  

  void usage(char *exename)

  {

      printf("Usage:n");

      printf("    %s n", exename);

      printf("    led_no = 1, 2, 3 or 4n");

  }

  

  int main(int argc, char **argv)

  {

      unsigned int led_no;

      int fd = -1;

  

      if (argc != 3)

          goto err;

          

      fd = open("/dev/MY_leds", 0);  // 打开设备

      if (fd < 0) {

          printf("Can't open /dev/ledsn");

          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;

  }


测试指令   ./test 1 on 


关键字:micro2440  驱动  LED 引用地址:micro2440写的第一个驱动-LED

上一篇:Linux(AT91SAM9260)增加UBIFS文件系统支持
下一篇:移植U-BOOT-2.14.07至MICRO2440开发板

推荐阅读最新更新时间:2024-11-20 11:00

LED背光灯用驱动器技术
前言 LED光源已在众多汽车应用中迅速普及。ROHM凭借高效的LED光源驱动技术,打造了用于尾灯、背光灯以及前照灯的LED驱动器等丰富的产品阵容。在此,将为您介绍用于背光灯的LED驱动器。 车载背光灯用LED驱动器的开发 近年来,在车载用显示器领域,为满足有害物质限制要求,使用水银的CCFL背光灯正在被LED背光灯迅速取代。另外,仪表盘、汽车导航、音响显示、后座娱乐等各种车载用显示器正朝多样化、大型化方向发展。在这种趋势下,对于增加LED灯数量以及高亮度、高调光率的要求日益高涨。ROHM为满足LED灯数量增加的这种发展趋势需求,将实现高耐压的升降压DC/DC转换器、可多灯驱动小功率LED且实现了高调光率的电流驱动器电路内置于一枚芯片
[嵌入式]
基于STM32F407库函数开发按键控制LED
按键控制灯的亮与灭的效果图: 一、寄存器开发与库函数开发的优缺点 1、寄存器开发 缺点: (1)开发难度大,查阅相关手册比较多 (2)开发效率相对低,产品周期长 (3)可维护性较差 (4)可移植性、阅读性差 优点: 运行效率高。 2、库函数开发 优点: (1)开发难度小,有库函数封装,即可实现功能 (2)开发效率高,产品周期短 (3)可维护性高 (4)可移植性、阅读性强 缺点: 运行效率相对寄存器低一些。 STM32库函数实际是ST公司对寄存器开发封装。 二、LED库函数开发 LED库开发要添加库文件:stm32f4xx_gpio.c (1)原理图可参看上篇文章:入门篇 | STM32F407寄存器开发--点灯 (2)
[单片机]
基于STM32F407库函数开发按键控制<font color='red'>LED</font>灯
应用于汽车内部及外部照明的LED驱动器方案概览
  近年来,随着LED在光效及成本等几乎各个方面的持续改进,其应用领域不断拓宽,从传统的便携设备背光向中大尺寸LCD显示器/液晶电视背光、汽车及通用照明等领域不断迈进。本文将专门介绍适合于汽车照明应用的各种LED驱动器方案,并探讨一些典型应用。   LED为汽车照明应用提供众多优势     LED在汽车中的应用领域非常广泛,但可以简单归纳为内部照明及外部照明(参见图1)。外部照明有如前照灯、尾部照明等,内部照明包括内部便利及舒适照明和仪表盘背光等。   图1:多种多样的汽车LED照明应用   推动汽车LED照明应用的因素很多。以前照灯为例,采用LED作为光源拥有众多优势:   利于灵活或新颖的造型设计——
[嵌入式]
买电视可别被忽悠了OLED显示屏电视和LED电视差别挺大!
    我们经常听到别人说什么LED、LCD和OLED,但是我们真的能够准确的区分其中的不同吗?今天,eeworld网LED小编就为大家整理了一下LEC、LCD与OLED电视之间的区别,我们来一起看看吧。     LCD与LED工作原理   LED(Light Emit TI ng Diode),即发光二极管,是一种半导体固体发光器件,它是利用固体半导体芯片作为发光材料,当两端加上正向电压,半导体中的载流子发生复合引起光子发射而产生光。LED可以直接发出红、黄、蓝、绿、青、橙、紫、白色的光。   LED 就是 light emit TI ng diode ,发光二极管的英文缩写,简称LED。它是一种通过控制半导体发光二极管的显
[电源管理]
高压变频器中功率驱动PWM信号的远距离传送实现
  随着市场经济的发展和自动化,智能化程度的提高,采用高压变频器对泵类负载进行速度控制,不但对改进工艺、提高产品质量有好处,又是节能和设备经济运行的要求,是可持续发展的必然趋势。对泵类负载进行调速控制的好处甚多。从应用实例看,大多已取得了较好的效果(有的节能高达30%-40%),大幅度降低了自来水厂的制水成本,提高了自动化程度,且有利于泵机和管网的降压运行,减少了渗漏、爆管,可延长设备使用寿命。   高压变频系统        图1-高压变频框图   单元串联多电平PWM电压源型变频器,采用若干个低压PWM变频功率单元串联的方式实现直接高压输出,该变频器对电网谐波污染小,谐波输入电流很低,输入功率因数高
[电源管理]
高压变频器中功率<font color='red'>驱动</font>PWM信号的远距离传送实现
通过蓝牙控制RGB LED颜色
智能灯 越来越受欢迎,并且正在稳步成为智能家居的关键部分。智能灯使用户能够通过智能手机上的应用程序控制灯光,可以在APP界面打开和关闭灯,也可以调节颜色。在本文中,我们将介绍一个如何实现智能灯控制器的项目,可以手动按钮或用移动APP通过蓝牙进行控制。为了给这个项目增加一些特色,我们添加了一些功能,允许用户从APP界面中包含的颜色列表中选择照明颜色。还可以激活“自动混合”以产生彩色效果,也可以每半秒改变一次灯光。用户可以使用PWM功能创建自己的颜色混合,该功能也可以用作三种基本颜色(红色、绿色、蓝色)的调光器。我们还在电路中添加了外部按钮,以便用户可以切换到手动模式并通过外部按钮调换灯光颜色。 本文由两部分组成:GreenPAK
[嵌入式]
通过蓝牙控制RGB <font color='red'>LED</font>颜色
高精度低成本:一款LED老化测试方案
本文所介绍的一种LED 照明产品长时间通电老化试验的方案,主要说明了如何结合系统中的硬件产品,和主要的监控软件,实现最大程度的发挥电源在老化系统中的作用,提高多个LED 产品老化测试的同时性和自动化性,得到最准确的监控数据以及最大程度的节约人力成本的目标。该系统已经应用到实际的老化试验中,并将进一步在LED 行业中推广和应用。   LED 发光的原理   中国LED 产业起步于20 世纪70 年代。经过30 多年的发展,中国LED 产业已初步形成了包括LED 外延片的生产、LED 芯片的制备、LED 芯片的封装以及LED 成品应用在内的较为完整的产业链。   LED 照明的LED 是由Ⅲ-Ⅳ族化合物,如GaAs(砷化镓)、G
[模拟电子]
高精度低成本:一款<font color='red'>LED</font>老化测试方案
开关电源设计中有源驱与动无源驱动矩阵的比较
一.结构的不同 无源 驱动矩阵的像素由阴极和阳极单纯基板构成,阳极和阴极的交叉部分可以发光,驱动用IC需要由TCP或COG等连接方式进行外装。 有源 驱动的每个像素配备具有开关功能的低温多晶硅薄膜晶体管(Low Temperature Poly-Si Thin Film Transistor, LT P-Si TFT),而且每个象素配备一个电荷存储电容,外围驱动电路和显示阵列整个系统集成在同一玻璃基板上。与LCD相同的TFT结构,无法用于OLED。这是因为LCD采用电压 驱动 ,而OLED却依赖电流驱动,其亮度与电流量成正比,因此除了进行ON/OFF切换动作的选址TFT之外,还需要能让足够电流通过的ON阻抗较低的小型驱动TFT
[电源管理]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved