Smart210---LED驱动

  经过几天的学习,终于linux驱动的基本框架弄清楚了。。。真的很艰辛,,,不过终于还是熬过来了,虽然还是最基础的,,,

今晚也完成了我第一个linux驱动,,,心里还是有点小兴奋的,哈哈O(∩_∩)O

直接上驱动源程序吧:::

我的开发板是Smart210,根据原理图,IO口输出0 led亮,输出1 led灭

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/delay.h>

#include <mach/gpio.h>
#include <mach/regs-gpio.h>
#include <plat/gpio-cfg.h>

#define DEVICE_NAME "leds"
  /* 应用程序执行ioctl(fd, cmd, arg)时的第2个参数 */
  /*the second parameter that application program execute*/
  #define IOCTL_GPIO_ON         1
  #define IOCTL_GPIO_OFF        0
  /* 用来指定LED所用的GPIO引脚 */
  /*appoint the pin the LED will use*/
  static unsigned long leds_table [] =
  {
          S5PV210_GPJ2(0),
          S5PV210_GPJ2(1),
          S5PV210_GPJ2(2),
          S5PV210_GPJ2(3),
          //arch\arm\mach-s5pv210\include\mach\gpio.h
  };
  static char leds_name[][4]={{"LED1"},{"LED2"},{"LED2"},{"LED3"}};
  #define LED_NUM                ARRAY_SIZE(leds_table)
   /**
  *函数功能:打开/dev/led设备
  *fuction:open /dev/leds device
  *设备名是:/dev/leds
  *devce name: /dev/leds
  **/
  static int my_led_open(struct inode *inode, struct file *file)
  {
       int i;
       int err;

       for (i = 0; i < LED_NUM; i++)
       {
           err = gpio_request(leds_table[i], leds_name[i]);
                      //drivers/gpio/gpiolib.c
           if(err)
           {
              printk(KERN_ERR "failed to request S5PV210_GPH2(%d) for LED%d \n",i-1,i);
              return err;
           }
       }

       for (i = 0; i < LED_NUM; i++)
       {
         s3c_gpio_cfgpin(leds_table[i], S3C_GPIO_OUTPUT);//Configuration pin function:input output multiplex
         gpio_set_value(leds_table[i], 1);//Set the pin level
          //arch\arm\plat-samsung\gpio-config.c
//          gpio_direction_output(leds_table[i], 0);//write a value to GPIO port ,also set the port to output mode
//          gpio_set_value(leds_table[i], 0);
          //drivers/gpio/gpiolib.c

       }
      printk(KERN_INFO "LEDs driver successfully close\n");
       return 0;
  }

 static long my_led_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
 {
    arg -= 1;
    if(arg > LED_NUM) {
        return -EINVAL;
    }

    switch(cmd) {
        case IOCTL_GPIO_ON:
            printk("led light\n");
            gpio_set_value(leds_table[arg], 0);
        break;

        case IOCTL_GPIO_OFF:
            printk("led no light\n");
            gpio_set_value(leds_table[arg], 1);
        break;

        default:
            printk("led failed\n");
            return -EINVAL;
    }
    return 0;
 }

 static int my_led_close(struct inode * inode,struct file * file)
 {
     int i;
    for(i= 0; i < LED_NUM; i++)
        gpio_free(leds_table[i]);
    printk(KERN_EMERG"close success\n");
    return 0;
 }

struct file_operations my_led_ops = {
    .owner = THIS_MODULE,
    .open  = my_led_open,
    .unlocked_ioctl = my_led_ioctl,
    .release = my_led_close,
};

static struct miscdevice led_misc = {
    .minor = MISC_DYNAMIC_MINOR,
    .name = DEVICE_NAME,
    .fops  = &my_led_ops,
};

static int __init my_led_init(void)
{
    int ret;

    ret = misc_register(&led_misc);
    if(ret) {
        printk(KERN_INFO"misc_register failed\n");
    }

    printk(KERN_INFO"misc_register sucessed\n");

    return 0;
}

static void __exit my_led_exit(void) {
    int i;
    misc_deregister(&led_misc);
    for(i= 0; i < LED_NUM; i++)
        gpio_free(leds_table[i]);
    printk(KERN_INFO "LEDs driver successfully exit\n");
}

module_init(my_led_init);
module_exit(my_led_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("qigaohua");

 

应用程序:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/time.h>

#define IOCTL_GPIO_ON           1
#define IOCTL_GPIO_OFF          0

int main(int argc, char **argv)
{
    int fd;

    fd = open("/dev/leds",0);
    if(fd < 0) {
        printf("/dev/leds open failed\n");
        exit(1);
    }

    do {
        printf("/dev/leds open sucessed\n");
        ioctl(fd, IOCTL_GPIO_ON, 1);
        ioctl(fd, IOCTL_GPIO_OFF, 2);
        ioctl(fd, IOCTL_GPIO_OFF, 3);
        ioctl(fd, IOCTL_GPIO_OFF, 4);
        sleep(1);

        ioctl(fd, IOCTL_GPIO_ON, 1);
        ioctl(fd, IOCTL_GPIO_ON, 2);
        ioctl(fd, IOCTL_GPIO_OFF, 3);
        ioctl(fd, IOCTL_GPIO_OFF, 4);
        sleep(1);

        ioctl(fd, IOCTL_GPIO_ON, 1);
        ioctl(fd, IOCTL_GPIO_ON, 2);
        ioctl(fd, IOCTL_GPIO_ON, 3);
        ioctl(fd, IOCTL_GPIO_OFF, 4);
        sleep(1);

        ioctl(fd, IOCTL_GPIO_ON, 1);
        ioctl(fd, IOCTL_GPIO_ON, 2);
        ioctl(fd, IOCTL_GPIO_ON, 3);
        ioctl(fd, IOCTL_GPIO_ON, 4);
        sleep(1);

        ioctl(fd, IOCTL_GPIO_OFF, 1);
        ioctl(fd, IOCTL_GPIO_OFF, 2);
        ioctl(fd, IOCTL_GPIO_OFF, 3);
        ioctl(fd, IOCTL_GPIO_OFF, 4);
    }while(0);

    close(fd);
    return 0;

}
时间: 2024-11-10 14:49:26

Smart210---LED驱动的相关文章

第7章:LED驱动的实现原理

本章完成了一个真正意义上的 Linux 驱动.该 Linux 驱动用来控 制开发版上的 4个 LED 小灯.也就是说通过向 Linux 驱动发送数据可以控制 LED 小灯的开关.为 了方便称呼这个驱动,本书及后面的章节都将其称为 LED 驱动. 虽然 LED 驱动并不复杂,只是控制 了 4个 LED,"但 LED 驱动已经包括了 Linux 驱动所有必要的部分 一个完整的 Linux 驱动主要由 内部处理和与硬件交互降部分组成.其中内部处理主要是指 Linux 驱动的装载.卸载.与设备文件 相关

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

本文转载自:http://www.voidcn.com/blog/lqxandroid2012/article/p-625005.html 目前的linux版本的许多驱动都是基于设备模型,LED也不例外. 简单地说,设备模型就是系统认为所有的设备都是挂接在总线上的,而要使设备工作,就需要相应的驱动.设备模型会产生一个虚拟的文件系统——sysfs,它给用户提供了一个从用户空间去访问内核设备的方法,它在linux里的路径是/sys.如果要写程序访问sysfs,可以像读写普通文件一样来操作/sys目录

编写LED驱动

1.创建LED驱动的设备文件: (1)使用cdev-init函数初始化cdev (2)指定设备号 设备号的分配有两种指定方法:直接在代码中指定(硬编码) 动态分配 (3)使用cdev-add函数将字符设备添加到内核中的字符设备数组中 (4)使用class-creat宏创建struct class (5)使用device-create函数创建设备文件 2.LED驱动通过两种方式控制LED 通过字符串控制LED 通过I/O命令LED 3.一个完整的linux驱动主要由内部处理和与硬件交互两部分组成.

linux驱动(九)platform驱动模型详解,以及基于platform驱动模型的led驱动

参考: http://blog.csdn.net/qq_28992301/article/details/52385518 http://blog.csdn.net/zoe6553/article/details/6372445 http://blog.chinaunix.net/uid-25014876-id-111745.html 1:什么是platform总线?platform总线是区别于实体总线USB. I2C.SPI .PIC总线的虚拟总线,一些usb设备选址的话需要通过USB总线来进

兼容可控硅调光的一款LED驱动电路记录

1.该款电路为兼容可控硅调光的LED驱动电路,采用OB3332为开关控制IC,拓扑方案为Buck: 2.FB1:磁珠的单位是欧姆,而不是亨利,这一点要特别注意.因为磁珠的单位是按照它在某一频率 产生的阻抗来标称的,阻抗的单位也是欧姆.磁珠的 DATASHEET上一般会提供频率和阻抗的特性曲线图,一般以100MHz为标准,比如[email protected],意思就是在100MHz频率的时候磁珠的阻抗相当于600欧姆: 3.UFM14PL-TP普通二极管: Maximum Recurrent P

(笔记)linux设备驱动--LED驱动

linux设备驱动--LED驱动 最近正在学习设备驱动开发,因此打算写一个系列博客,即是对自己学习的一个总结,也是对自己的一个督促,有不对,不足,需要改正的地方还望大家指出,而且希望结识志同道合的朋友一起学习技术,共同进步. 作者:liufei_learning(转载请注明出处) email:[email protected] IT学习交流群:160855096 转至:http://blog.csdn.net/liufei_learning/article/details/7025246 开发环

FL2440驱动添加(4)LED 驱动添加

硬件信息:FL2440板子,s3c2440CPU带四个LED,分别在链接GPB5,GPB6,GPB8,GPB10 内核版本:linux-3.8.0 led驱动代码如下: 值得注意地方地方: 1,定时器的使用:在include/linux/timer.h下定义struct timer_list struct timer_list { /* * All fields that change during normal runtime grouped to the * same cacheline *

有注释的LED驱动

裸机下控制LED灯非常方便,只需要配置好GPIO引脚功能,然后向GPIO引脚映射的内存地址处写入数据即可,但linux下驱动就不那么简单了,需要结合字符设备驱动的架构,然后将功能实现添加进去,笔者参考linux设备驱动程序(第三版)中介绍的新的接口来实现驱动.友善之臂官网提供的源码是基于miscdevice的驱动,而且接口似乎有点老,比如在linux设备驱动程序(第三版)中强调需要使用新的内存I/O接口来访问映射内存,建议使用ioread32,iowrite32等,但是它依然使用writel,r

驱动学习之LED驱动框架

一:什么是驱动框架  (1)内核中驱动部分维护者针对每个种类的驱动设计一套成熟的.标准的.典型的驱动实现,然后把不同厂家的同类硬件驱动中相同的部分抽出来自己实现好,再把不同部分留出接口给具体的驱动开发工程师来实现,这就叫驱动框架.  (2)内核维护者在内核中设计了一些统一管控系统资源的体系,这些体系让内核能够对资源在各个驱动之间的使用统一协调和分配,保证整个内核的稳定健康运行.譬如系统中所有的GPIO就属于系统资源,每个驱动模块如果要使用某个GPIO就要先调用特殊的接口先申请,申请到后使用,使用

嵌入式Linux学习笔记之LED驱动

最近在学习嵌入式Linux驱动开发,大致了解了驱动的基本开发流程,本文主要针对字符设备驱动开发做一个简要介绍,也当作是对这几天工作的一个小小总结. 计算机系统是由软硬件相互协调共同完成工作的,作为专用计算机系统的嵌入式系统也不例外,既要有CPU.SDRAM.FLASH.IO等硬件,同时也少不了操作系统和应用软件等软件的支持,而作为应用程序与硬件的桥梁--驱动程序,是整个嵌入式系统开发过程中的关键环节.驱动开发涉及底层,而了解底层作用机制对于整个系统的开发意义重大. Linux内核中有60%以上是