Tiny6410 简单的LED字符设备驱动

发布者:740322lwj最新更新时间:2020-03-10 来源: eefocus关键字:Tiny6410  LED  字符设备驱动 手机看文章 扫描二维码
随时随地手机看文章

首先分析原来:


1.查看用户手册

led1、led2、led3、led4 连接的分别是 GPK4、GPK5、GPK6、GPK7


2、查询6410芯片手册



下面还需要3个步骤:


1、设置GPIO为OUTPUT。


   将GPK4、GPK5、GPK6、GPK7设置为输出output=0001


   即GPKCON0的19:28都配置为0001


2、设置GPIO的数据。


   将GPKDATA的4:7位赋值为0


3、设置GPKUP为上拉。


   将GPKUP的4:7位设置为10


3、代码


led_driver.c


#include   /*它定义了模块的 API、类型和宏(MODULE_LICENSE、MODULE_AUTHOR等等),所有的内核模块都必须包含这个头文件。*/ 

  

#include   /*使用内核信息优先级时要包含这个文件,一般在使用printk函数时使用到优先级信息*/

 

#include   

#include /* copy_to_user,copy_from_user */   

#include      /*readl writel*/

#include    

#include     

#include     

 

  

#define LED_MAJOR   243

 

#define LED_ON      1

#define LED_OFF     0

#define LED_1_ON    2

#define LED_1_OFF   3

#define LED_2_ON    4

#define LED_2_OFF   5

#define LED_3_ON    6

#define LED_3_OFF   7

#define LED_4_ON    8

#define LED_4_OFF   9

 

 

static int led_open (struct inode *inode,struct file *filp)  

  

{  

unsigned tmp;     

 

tmp = readl(S3C64XX_GPKCON);    

tmp = (tmp&0x0000ffff)| 0x1111ffff;

writel(tmp, S3C64XX_GPKCON);   

 

printk("#########open######n");  

return 0;  

}  

  

static int led_read (struct file *filp, char __user *buf, size_t count,loff_t *f_pos)  

{    

    return count;  

}  

  

  

static int led_write (struct file *filp, const char __user *buf, size_t count,loff_t *f_pos)

 

{  

char wbuf[10];  

unsigned tmp;     

    if(copy_from_user(wbuf,buf,count))

return -EFAULT;  

 

    switch(wbuf[0])  

    {  

case LED_ON: 

    tmp = readl(S3C64XX_GPKDAT);     

tmp &= (0x0f);     

writel(tmp, S3C64XX_GPKDAT);

printk("turn on!n");    

    break;

 

case LED_OFF:  

tmp  = readl(S3C64XX_GPKDAT);     

tmp |= (0xf0);     

writel(tmp, S3C64XX_GPKDAT); 

printk("turn off!n");   

break;   

 

case LED_1_ON:  

tmp = readl(S3C64XX_GPKDAT);     

tmp &= (0xef);     

writel(tmp, S3C64XX_GPKDAT); 

printk("turn off!n");   

break;  

 

case LED_1_OFF: 

    tmp = readl(S3C64XX_GPKDAT);     

tmp |= (0xf0);     

writel(tmp, S3C64XX_GPKDAT);

printk("turn on!n");    

    break;

 

case LED_2_ON:  

tmp = readl(S3C64XX_GPKDAT);     

tmp &= (0xdf);     

writel(tmp, S3C64XX_GPKDAT); 

printk("turn off!n");   

break;  

 

case LED_2_OFF: 

    tmp = readl(S3C64XX_GPKDAT);     

tmp |= (0xf0);     

writel(tmp, S3C64XX_GPKDAT);

printk("turn on!n");    

    break;

 

case LED_3_ON:  

tmp = readl(S3C64XX_GPKDAT);     

tmp &= (0xbf);     

writel(tmp, S3C64XX_GPKDAT); 

printk("turn off!n");   

break;  

 

case LED_3_OFF: 

    tmp = readl(S3C64XX_GPKDAT);     

tmp |= (0xf0);     

writel(tmp, S3C64XX_GPKDAT);

printk("turn on!n");    

    break;

 

case LED_4_ON:  

tmp = readl(S3C64XX_GPKDAT);     

tmp &= (0x7f);     

writel(tmp, S3C64XX_GPKDAT); 

printk("turn off!n");   

break;  

 

case LED_4_OFF: 

    tmp  = readl(S3C64XX_GPKDAT);     

tmp |= (0xf0);     

writel(tmp, S3C64XX_GPKDAT);

printk("turn on!n");    

    break;

 

default :  

    break;  

    }  

    return 0;  

}  

  

int led_release (struct inode *inode, struct file *filp)  

{  

printk("#########release######n");  

return 0;  

}  

  

struct file_operations led_fops =

{  

.owner = THIS_MODULE,  

.open = led_open,  

.read = led_read,  

.write = led_write,  

.release = led_release,  

};  

  

int __init led_init (void)  

{   

int rc;  

printk ("Test led devn");  

rc = register_chrdev(LED_MAJOR,"led",&led_fops); 

 

if (rc <0)  

{  

printk ("register %s char dev errorn","led");  

return -1;  

}  

printk ("ok!n");  

return 0;  

}  

  

void __exit led_exit (void)  

{  

unregister_chrdev(LED_MAJOR,"led");  

printk ("module exitn");  

return ;  

}  

  

module_init(led_init);  

module_exit(led_exit);  


Makefile


obj-m := led_driver.o  

KDIR :=/home/workdir/kernel/linux-2.6.38

all:  

make -C $(KDIR) M=$(shell pwd) modules  

install:  

cp driver_led.ko /tftpboot/  

clean:  

make -C $(KDIR) M=$(shell pwd) clean 


测试文件


test_led.c


#include   

#include   

#include   

#include   

 

#define LED_OFF     0

#define LED_ON      1

#define LED_1_ON    2

#define LED_1_OFF   3

#define LED_2_ON    4

#define LED_2_OFF   5

#define LED_3_ON    6

#define LED_3_OFF   7

#define LED_4_ON    8

#define LED_4_OFF   9

 

int main (void)  

{  

    int  i=0;

    int  fd;  

    char buf[10]={

LED_ON ,   LED_OFF ,

LED_1_ON,  LED_1_OFF,

LED_2_ON,  LED_2_OFF,

LED_3_ON,  LED_3_OFF,

LED_4_ON,  LED_4_OFF,

};  

 

    fd = open("/dev/led",O_RDWR);  

    if (fd < 0)  

    {  

        printf ("Open /dev/led file errorn");  

        return -1;  

    }     

 

    while(i<10)  

    {  

        write(fd,&buf[i],4);  

        sleep(1);  

        i++;

    }  

    close (fd);  

    return 0;  

  

}  


上述编译没有问题,就可以下到板子测试了。


加载驱动          insmod  led_driver.ko


创建设备文件    mknod /dev/led c 243 0  其中243要跟驱动文件中的设备号一致


运行测试文件    ./test_led


完成。


------------------------------------------------------------------------------------------


参考资料:


#include /*它定义了模块的 API、类型和宏(MODULE_LICENSE、MODULE_AUTHOR等等),所有的内核模块都必须包含这个头文件。/

#include /*使用内核信息优先级时要包含这个文件,一般在使用printk函数时使用到优先级信息*/

#include //头文件:module_init、module_exit等宏定义。

#include ////struct file_operations

#include

#include // S3C2410 GPIO寄存器定义

#include // s3c2410_gpio_setpin, s3c2410_gpio_cfgpin等

#include //class_create device_create(注意,有些2.6.27以前是的可能是class_device_create,如果出现implicate 错误时,看一下这个头问题里边是哪一个),udev,自动在/dev下创建设备节点

#include //字符设备节点注册,函数有cdev_init,cdev_add,cdev_del等早期的办法是register_chrdev,unregister_chrdev这种方法应避免使用。

#define DEVICE_NAME "leds" /* 加载模式后,执行”cat /proc/devices”命令看到的设备名称 */

#define LED_MAJOR 231 /* 主设备号 */

/* 应用程序执行ioctl(fd, cmd, arg)时的第2个参数 */

#define IOCTL_LED_ON 1

#define IOCTL_LED_OFF 0

/* 用来指定LED所用的GPIO引脚 */

static unsigned long led_table [] =

{

S3C2410_GPB5,

S3C2410_GPB6,

S3C2410_GPB7,

S3C2410_GPB8,

};

/* 用来指定GPIO引脚的功能:输出 */

static unsigned int led_cfg_table [] =

{

S3C2410_GPB5_OUTP,

S3C2410_GPB6_OUTP,

S3C2410_GPB7_OUTP,

S3C2410_GPB8_OUTP,

};

struct leds_type

{

struct cdev cdev;

};

struct leds_type *my_leds_dev;

/* 应用程序对设备文件/dev/EmbedSky-leds执行open(...)时,

* 就会调用EmbedSky_leds_open函数

*/

static int EmbedSky_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;

}

/* 应用程序对设备文件/dev/EmbedSky-leds执行ioclt(...)时,

* 就会调用EmbedSky_leds_ioctl函数

*/

static int EmbedSky_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;

}

}

/* 这个结构是字符设备驱动程序的核心

* 当应用程序操作设备文件时所调用的open、read、write等函数,

* 最终会调用这个结构中指定的对应函数

*/

static struct file_operations EmbedSky_leds_fops =

{

.owner = THIS_MODULE, /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */

.open = EmbedSky_leds_open, 

.ioctl = EmbedSky_leds_ioctl,

};

static char __initdata banner[] = "TQ2440/SKY2440 LEDS, (c) 2008,2009 www.embedsky.net/n";

[1] [2]
关键字:Tiny6410  LED  字符设备驱动 引用地址:Tiny6410 简单的LED字符设备驱动

上一篇:Linux内核模块驱动之---led驱动
下一篇:tiny4412内核自带led驱动分析

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

2015年发到占全球LED照明市场比重达55%
    从全球主要照明市场观察,已开发国家因LED照明发展时程较早,2015年市场规模占全球比重仍将较高,DIGITIMES Research预估美、欧、日各区皆超过50亿美元,合计比重将达55%,其中,欧洲、美国比重各达19.2%、18.8%,超越日本的17%;值得注意的是,日本2015年增率将仅为13.2%,低于美国及欧洲的33.1%、38%,主因其LED照明渗透率将高达78.6%所致。 相对的,人口数多、导入LED照明较为积极的新兴市场亦具成长潜力,其中,大陆因政府LED产业政策激励下,LED照明市场年增率优于已开发国家表现,2015年将达46.5%、市场规模将为45.7亿美元;全球人口数次高的印度在大城市公共照明换装为LE
[手机便携]
打破中国LED芯片发展瓶颈 需掌握客观规律
  突破芯片领域的发展,为我国LED照明产业做大做强、应对未来激烈国际竞争的必由之路。在LED照明时代渐已到来的今天,大功率对于支撑终极“照明世界”具有更重要的战略意义,无疑已成为中国军团借机进军国际照明市场的“硬道理”。那么要提升中国芯片产业的发展,企业都应该怎么做呢?   由于大尺寸液晶LED背光市场的提前到来和LED照明市场的快速推进给中国芯片厂带来了巨大的、前所未有的历史机遇。可是由于我们的企业还没有很好地解决自身发展的关键问题,这么好的商机却无法抓住。   尽管我过LED芯片产业这几年有了长足的进步,但是经过了十多年的发展,还是缺少核心技术,发展不快,产品档次较低,这说明了很多问题。这些问题包括,大部门企业没能有效地组建
[电源管理]
未来LED灯具技术趋势
LED 小巧轻量、 驱动 电压低、全彩色、寿命长、效率高、耐振动、易于控光等特性,为设计用于不同场所和目的的照明系统提供了优越条件。人们习惯于看日光下的东西,对于通用照明来说,人们需要的主要是接近太阳光质量的光源,所以 白光LED 是 半导体照明 科技的重要指标。由于单只LED 功率 小,光 亮度 低,不宜单独使用,为此必须将多个LED组装在一起设计成为实用的 LED照明 系统。但目前白光LED与通用照明的要求还有一定的距离,还存在诸多技术与成本问题急需解决。    1、半导体照明灯具系统的主要技术概况 1)灯具系统的热量管理 一般常称LED为 冷光源 ,这是因为LED发光原理是电子经过复合
[电源管理]
我国实现LED芯片生产设备MOCVD国产化
    12月12号,中国首台具有世界先进水平的大型国产MOCVD设备发运庆典在张江高新区核心园举行。张江高新区管委会副主任侯劲及工信部、市经信委、浦东新区、常州等有关领导和5家客户出席了发运庆典仪式。   作为LED芯片生产过程中最为关键的设备,MOCVD的核心技术长期被欧美企业所垄断,严重制约了中国LED产业的健康发展。中晟光电设备(上海)有限公司于今年初1月18日成功实现了拥有自主创新知识产权的具有世界先进水平的大型国产MOCVD设备下线,仅用了10个月时间,又完成了工艺的开发和设备进一步的改进优化,完成了设备产业化生产必备条件与设施的建立;在此基础上又完成了4家客户的多次实地考察,亲临操作设备和验证各项工艺。   客户充
[家用电子]
低电流LED应用的简单、经济及强固的线性恒流稳压方案
   凭借着节能、长使用寿命及色彩组合丰富等优势, LED 成为增速最快的 半导体 领域之一,近年来的年复合增长率(CAGR)高达20%,预计2012年全球LED市场总值更将达114亿美元,前景非常可观。   市场上典型的LED 驱动器 包括两类,即线性驱动器和开关驱动器;进一步细分,则有三种,分别是开关 稳压器 、线性稳压器和电阻型驱动器。这三种驱动器分别适合不同等级的电流应用,见图1。如电流大于500 mA的大电流应用采用开关稳压器,因为线性驱动器限于自身结构原因,无法提供这样大的电流;而在电流低于200 mA的低电流应用中,通常采用线性稳压器及电阻型驱动器;而在200至500 mA的中等电流应用中,既可以采用线性稳压器
[电源管理]
LED道路照明低温运行环境下的可靠性保障
随着led照明技术的快速发展,在国内的许多城市,道路照明已经不乏LED路灯的身影。尤其是大功率LED器件的光效超过100lm/W以后,LED路灯作为道路照明的发展趋势已经得到普遍认同。2009年,国内几个城市分别组织了LED道路照明产品的评估测试工作,大多数LED路灯产品在配光曲线、系统光效等关键技术指标方面进步显着,在道路照明标准的符合性、节能效果等方面已经达到相关标准和规范的要求。      尽管LED路灯技术水平的发展较快,但是大多数LED路灯厂商在产品研发过程中忽略了在寒地应用环境下的特殊技术要求。一个普遍的错误认识是,LED在寒冷地区应用有利于散热,不容易发生故障。殊不知,寒冷应用环境下,对LED路灯有着更为严格的技
[电源管理]
LED照明 跨国巨头设置的天大陷阱
      说到LED,我们能想象到的就是因为其能够为当今社会节能事业做出突出贡献而带来的辉煌前景。是的从理论上来看LED以其寿命长低压直流供电,节能环保,无频闪等天生丽质的优势让其集社会的万千宠爱于一身。以至于个人,企业,政府,社会均为LED而狂。似乎光源只要一沾LED就光芒四射,前程无限,LED 的作用被社会上的各种论炒得神乎其神,似乎只有LED才是节能救世主。     LED照明 :跨国巨头设置的天大陷阱     其实,照明用LED这类产品早在数十年前就已经在飞利浦和欧司朗的实验室出现。但为什么这此财大气粗的的国际巨头没有大规模的推广呢。我们可以相信,如果这两家像节能灯一样的推陈广LED.恐怕LED就是今天的节能灯,
[电源管理]
基于手机蓝牙控制的LED灯的设计
  1.引言   随着,2012年10月30日飞利浦在AppleStore出售最新的高科技Hue系列LED灯,并且只会交由苹果出售。Hue系列将是完全可有自定义的,并且通过一个灯泡内红蓝绿三原色的LED可以混合出1600万种颜色的灯光。整个过程完全由iPhone上的App来进行控制。从而引发了智能灯控发展的新思考,国内相关人士也纷纷进行研究。考虑到Hue是采用WiFi无线控制,而国内WiFi并未普及,本研究采用更普遍的蓝牙技术,采用手机蓝牙与单片机通信产生可调占空比PWM波信号控制LED驱动电路实现LED的调光和DIY调色。   2.脉冲宽制(PWM)调光技术   PWM调光是一种利用简单的数字脉冲,反复开关LED驱动器的调光技术
[电源管理]
基于手机蓝牙控制的<font color='red'>LED</font>灯的设计
小广播
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件
更多每日新闻

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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