tiny4412内核自带led驱动分析

发布者:梦幻之光最新更新时间:2020-03-10 来源: eefocus关键字:tiny4412内核  自带led  驱动分析 手机看文章 扫描二维码
随时随地手机看文章

内核版本:linux-3.5 

平台:tiny4412


一、关于混杂设备

此版本内核led驱动使用的是混杂设备misc,具体misc.c的实现路径:linux-3.5/drivers/char/misc.c


这就很大程度简化了我们的驱动代码,没有发现ldd3中提到的各种字符设备注册函数,而是发现了一个misc_register函数(共用的注册函数),这说明led设备是作为杂项设备出现在内核中的,在内核中,misc杂项设备驱动接口是对一些字符设备的简单封装,他们共享一个主设备号,有不同的次设备号,共享一个open调用,其他的操作函数在打开后运用linux驱动程序的方法重载进行装载。


二、关于gpio:

查找tiny4412的datasheet以及pcb电路图


1、查找I/O口对应引脚:

 这里写图片描述 

从图中我们可以看出,四个led灯分别对应四个i/o口1,2,3,4。 

所以可以创建结构体来保存:


static int led_gpios[] = {

    EXYNOS4X12_GPM4(0),

    EXYNOS4X12_GPM4(1),

    EXYNOS4X12_GPM4(2),

    EXYNOS4X12_GPM4(3),

};


2、查看led电路图:

 这里写图片描述 

由电路图可知当led为低电平时,led灯被点亮。。。且为输出模式。


s3c_gpio_cfgpin(led_gpios[i], S3C_GPIO_OUTPUT); //设置为输出模式

gpio_set_value(led_gpios[i], 1); //将引脚设置为高电平,默认为全灭


3、相关gpio函数:

1、int gpio_request(unsigned gpio, const char *label);

    获得并占有 GPIO port 的使用权,由参数 gpio 指定具体 port,非空的lables指针有助于诊断。主要是告诉内核这地址被占用了。当其它地方调用同一地址的gpio_request就会报告错误,该地址已被申请。在/proc/mem应该会有地址占用表描述。

这种用法的保护作用前提是大家都遵守先申请再访问,有一个地方没遵守这个规则,这功能就失效了。好比进程互斥,必需大家在访问临界资源的时候都得先获取锁一样,其中一个没遵守约定,代码就废了。


2、void gpio_free(unsigned gpio);//释放 GPIO port 的使用权,由gpio 指定具体 port。

例2:gpio_free(RK29_PIN0_PA0);//释放GPIO0_A0


3、int gpio_direction_input(unsigned gpio);//设置输入模式

例3:gpio_direction_input (RK29_PIN0_PA0);//把GPIO0_A0设置为输入



4、int gpio_direction_output(unsigned gpio, int value);//设置输出模式

例4:gpio_direction_output(RK29_PIN0_PA0,GPIO_LOW);//把GPIO0_A0设置为输出口,且其电平拉低。   


5、int gpio_get_value(unsigned gpio);//获取电平值

 例5:ret = gpio_get_value (RK29_PIN0_PA0);// 读取GPIO0_A0的电平,并赋值给变量ret。


6、void gpio_set_value(unsigned gpio, int value);设置引脚电平值

gpio_set_value (RK29_PIN0_PA0, GPIO_HIGH);// 设置RK29_PIN0_PA0电平为高。



7、 int gpio_pull_updown(unsigned gpio,unsigned value);

        value = 0, normal

        value = 1, pull up

        value = 2, pull down

例7、gpio_pull_updown(RK29_PIN0_PA0,1)上拉

       int gpio_cansleep(unsigned gpio);

支持这种gpio的平台为了通过在这个函数中返回非零来区分其它类型的gpio(需要一个已经被  gpio_request申请的gpio号)为了访问这些端口,定义了另一组函数接口:


8、 int gpio_get_value_cansleep(unsigned gpio);

        void gpio_set_value_cansleep(unsigned gpio, int value);只能在允许睡眠的上下文中访问这些端口,比如线程化的中断中,


9、 static inline int gpio_is_valid(int number)//判断GPIO是否有效,有效返回0


10、 int gpio_export(unsigned gpio, bool direction_may_change);//返回0成功


void gpio_unexport();  //返回0成功


int gpio_export_link(struct device *dev, const char *name, unsigned gpio) 

//创建到导出GPIO的 sysfs link  ,第一个参数是在哪个dev下创建,第二个是参数名字,第三个是gpio编号 


具体可参考: 

http://blog.csdn.net/andrinux/article/details/38725619 

http://blog.sina.com.cn/s/blog_a6559d9201015vx9.html


三、驱动代码分析:

流程:初始化(注册misc设备)—>定义fops结构体与misc结构体—>实现fops中相关函数—>把fops绑定到misc结构体—>注销misc设备。


#include

#include

#include

#include

#include

#include

#include

#include

#include

#include


#include

#include

#include



#define DEVICE_NAME "leds"     //设备名


static int led_gpios[] = {

    EXYNOS4X12_GPM4(0),

    EXYNOS4X12_GPM4(1),

    EXYNOS4X12_GPM4(2),

    EXYNOS4X12_GPM4(3),

};


#define LED_NUM     ARRAY_SIZE(led_gpios)



//因为是低电平点亮,但是这里我们cmd的值传入1点亮led灯,这是为了照顾惯性思维,当然,也可以让它传入0变亮。

static long tiny4412_leds_ioctl(struct file *filp, unsigned int cmd,

        unsigned long arg)

{

    switch(cmd) {

        case 0:

        case 1:

            if (arg > LED_NUM) {

                return -EINVAL;

            }


            gpio_set_value(led_gpios[arg], !cmd); //取反,所以传入1后点亮

            //printk(DEVICE_NAME": %d %dn", arg, cmd);

            break;


        default:

            return -EINVAL;

    }


    return 0;

}


//fops的实现,无需加入open,使用misc.c中共用的open

static struct file_operations tiny4412_led_dev_fops = {

    .owner          = THIS_MODULE,

    .unlocked_ioctl = tiny4412_leds_ioctl, //led控制函数

};


//混杂设备结构体,将fops绑定到其中

static struct miscdevice tiny4412_led_dev = {

    .minor          = MISC_DYNAMIC_MINOR,

    .name           = DEVICE_NAME,

    .fops           = &tiny4412_led_dev_fops,

};


//初始化:申请I/O口--->设置为输出模式--->默认设置全灭

static int __init tiny4412_led_dev_init(void) {

    int ret;

    int i;


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

        ret = gpio_request(led_gpios[i], "LED"); //获得并占有 GPIO port 的使用权

        if (ret) {

            printk("%s: request GPIO %d for LED failed, ret = %dn", DEVICE_NAME,

                    led_gpios[i], ret);

            return ret;

        }


        s3c_gpio_cfgpin(led_gpios[i], S3C_GPIO_OUTPUT); //设置为输出模式

        gpio_set_value(led_gpios[i], 1); //将引脚设置为高电平,默认为全灭

    }


    ret = misc_register(&tiny4412_led_dev); //注册混杂设备


    printk(DEVICE_NAME"tinitializedn");


    return ret;

}


static void __exit tiny4412_led_dev_exit(void) {

    int i;


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

        gpio_free(led_gpios[i]); //释放 GPIO port 的使用权

    }


    misc_deregister(&tiny4412_led_dev); //注销混杂设备

}


module_init(tiny4412_led_dev_init);

module_exit(tiny4412_led_dev_exit);


MODULE_LICENSE("GPL");

MODULE_AUTHOR("FriendlyARM Inc.");


四、测试用例:

#include

#include

#include

#include

int main(int argc, char **argv)

{

    int on;

    int led_no;

    int fd;

/* 检查 led 控制的两个参数,如果没有参数输入则退出。 */

    if (argc != 3 || sscanf(argv[1], "%d", &led_no) != 1 || sscanf(argv[2],"%d", &on) != 1 ||on < 0 || on > 1 || led_no < 0 || led_no > 3)  

    {

        fprintf(stderr, "Usage: leds led_no 0|1n");

        exit(1);

    }

/*打开/dev/leds 设备文件*/

    fd = open("/dev/leds0", 0);

    if (fd < 0) {

        fd = open("/dev/leds", 0);

    }


    if (fd < 0) {

        perror("open device leds");

        exit(1);

    }

/*通过系统调用 ioctl 和输入的参数控制 led*/

    ioctl(fd, on, led_no);  

/*关闭设备句柄*/

    close(fd);

    return 0;

}


交叉编译后将a.out拷贝到开发板。


运行:(第一个参数表示第led 0/1/2/3,第二个参数1表示开启,0表示关闭) 

./a.out 1 1 //开启第二盏灯 

./a.out 2 0 //关闭第三盏灯

关键字:tiny4412内核  自带led  驱动分析 引用地址:tiny4412内核自带led驱动分析

上一篇:Tiny6410 简单的LED字符设备驱动
下一篇:Arm 2440——Nand flash启动模式详解(LED程序为例)

推荐阅读最新更新时间:2024-11-19 17:10

汽车驱动电机结构原理及故障分析
电动汽车驱动 电机 是指应用于电动汽车上,用于驱动车轮运动的电机。(区别于 伺服电机 )
[嵌入式]
汽车<font color='red'>驱动</font>电机结构原理及故障<font color='red'>分析</font>
22.Linux-RTC驱动分析及使用
    linux中的rtc驱动位于drivers/rtc下,里面包含了许多开发平台的RTC驱动,我们这里是以S3C24xx为主,所以它的RTC驱动为rtc-s3c.c 1.进入./drivers/rtc/rtc-s3c.c     还是首先进入入口函数,如下图所示:     这里注册了一个“s3c2410-rtc”名称的平台设备驱动     而“s3c2410-rtc”的平台设备,在./arch/arm/plat-s3c24xx/dev.c里定义了,只不过这里没有注册,如下图所示:     当内核匹配到有与它名称同名的平台设备,就会调用.probe函数,接下来我们便进入s3c2410_rtcdrv- probe函
[单片机]
22.Linux-RTC<font color='red'>驱动</font><font color='red'>分析</font>及使用
分析:DSP正在驱动半导体产业
根据一位在DSP领域跟踪已久的分析师的报告,数字信号处理器正在不断的失去其作为独立芯片的特性,而且DSP事实上已经成为整个半导体产业的驱动力量。 ForwardConcepts的总裁和首席分析师WillStrauss在最新的无线分析报告中指出,半导体产业协会在上周发布的数据,乍一看来,DSP出货量(基于3个月的移动平均)同比上一年下降了47.2%,环比十二月份下降了38.6%,在各个领域的下跌比例处于领先。 “然而,该有戏剧性的下降并不是简单的DSP市场的下降,而是反映出许多在去年被划分为DSP的产品今年都被划到了ASIC一类。比如说,为摩托罗拉公司供货的飞思卡尔3G基带芯片(去年被划分到DSP)目前就已
[嵌入式]
集成氮化镓电机驱动分析
欧洲大约一半的电力流入电力驱动。因此,欧盟委员会和成员国政府制定了法规和标准,使电力消耗尽可能高效,电网需求尽可能低也就不足为奇了。变速驱动器(VSD)现已成为行业标准,因为与旧的恒速感应电机相比,它们可降低高达90%的能耗。同时,它可以减小尺寸并提高性能和可靠性。 IEC 61000等标准旨在保证电网稳定性,因为特别是电机等大型感性用电设备会严重破坏本地电网。为此有多种解决方案,例如功率因数校正(PFC),以优化每个负载点电网的有功功耗。 氮化镓改进性能和成本 氮化镓(GaN)是一种具有宽带隙的半导体,其开关速度比硅元件快20倍,并且可以处理高达三倍的功率密度。如果在电机驱动器的PFC和转换器级中使用GaN开关,则可以显
[嵌入式]
集成氮化镓电机<font color='red'>驱动</font>器<font color='red'>分析</font>
几种常用51单片机的I/O口驱动能力分析
在 控制 系统中,经常用 单片机 的I/O口 驱动 其他 电路 。几种常用 单片机 I/O口 驱动 能力在相关的资料中的说法是:GMS97C2051、AT89C2051的P1、P3的口线分别具有 10mA、20mA的输出驱动能力,AT89C51的P0、P1、P2、P3的口线具有10mA的输出驱动能力。在实际应用中,仅有这些资料是远远不够的。笔者通过实验测出了上述几种单片机的I/O口线的伏安特性(图1、图2),从中可以得到这些I/O口的实际驱动能力。 说明:1、测试方法:所测试的口线输出的信号是周期为4秒的方波。当测试口线为低电平时的驱动能力时,该口线通过 电阻 箱接+5V 电源 ,测出该口线对地的电压,从而计算出通过 电阻 的
[模拟电子]
LED驱动电源的应用分析
LED由于环保、寿命长、光电效率高等众多优点,近年来在各行业应用得以快速发展,LED的驱动电源成了关注热点,理论上,LED的使用寿命在10万小时以上,但在实际应用过程中,由于驱动电源的设计及驱动方式选择不当,使LED极易损坏。   我们设计LED驱动电源时,有必要知道LED电流、电压特性,由于LED的生产厂家及LED规格不同,电流、电压特性均有差异。现以白光LED典型规格为例,按照LED的电流、电压变化规律,一般应用正向电压为3.0-3.6V左右,典型值电压为3.3V,电流为20mA,当加于LED两端的正向电压超过3.6V后,正向电压很小的增加,LED的正向电流都有可能会成倍增涨,使LED发光体温升过快,从而加速LED光衰减,
[电源管理]
LED驱动器IC轻松实现无闪烁调光案例分析
   LED 亮度 高、功耗小、小型化、寿命长等优点推动了该技术的迅速发展,但 LED照明 技术仍存在成本高、散热器过大、发光率低以及调光等挑战。在设计过程中,工程师进行LED常规调节时往往会遇到启动速度慢、闪烁、光照不均匀等情况,因此如何解决LED闪烁问题成为工程师当务之急。如果能够提供高精度恒流控制(能够分析 可控硅 控制器 的可变相位角输出,对流向LED的恒流进行单向调整),输入 EMI 滤波器 电感 和电容非常小,那么进行有效的无闪烁调光是否便能成为可能?   日前,Power Integrations (PI)公司LinkSwitch-PH系列 LED驱动 器 IC 很好地解决这一困扰,该产品的初级侧控制技术还省去了隔
[电源管理]
<font color='red'>LED</font><font color='red'>驱动</font>器IC轻松实现无闪烁调光案例<font color='red'>分析</font>
tiny4412 串口驱动分析三 --- log打印的几个阶段之内核自解压
开发板:tiny4412ADK+S700 4GB Flash 主机:Wind7 64位 虚拟机:Vmware+Ubuntu12_04 u-boot:U-Boot 2010.12 Linux内核版本:linux-3.0.31 Android版本:android-4.1.2 内核自解压时期的串口打印 在zImage格式的内核启动时会自解压内核,此时打印信息如下: Uncompressing Linux... 这句话是在arch/arm/boot/compressed/misc.c中: void decompress_kernel(unsigned long output_start, unsigned lo
[单片机]
<font color='red'>tiny4412</font> 串口<font color='red'>驱动</font><font color='red'>分析</font>三 --- log打印的几个阶段之<font color='red'>内核</font>自解压
小广播
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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