歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

TQ2440上LED燈閃爍效果的驅動程序實現

本篇文章的驅動程序實現的要點:一是實現了設備文件的自動創建,不用每次運行驅動都要使用mknod指令自動創建設備文件,本文通過udev(mdev)來實現設備文件的自動創建。二是對LED燈的控制不是通過直接設置相關GPIO的二進制位來實現,本文使用linux系統中提供的對S3C2410 GPIO的操作函數,直接實現對相關GPIO的控制。三是實現了LED燈的閃爍效果,本文雖然沒有在驅動程序代碼中直接實現LED燈的閃爍效果,但是通過上層應用程序調用驅動程序中的ioctl間接實現了LED燈的閃爍效果。

Ubuntu下搭建TQ2440的程序下載環境 http://www.linuxidc.com/Linux/2011-03/32869.htm

Ubuntu 12.04(32位)下TQ2440開發板環境搭建 http://www.linuxidc.com/Linux/2014-04/100085.htm

【Linux驅動】TQ2440 LED驅動程序 http://www.linuxidc.com/Linux/2014-06/103328.htm

一,驅動程序源代碼My_Led.c:


#include <linux/module.h>

#include <linux/kernel.h>

#include <linux/fs.h>

#include <linux/init.h>

#include <linux/delay.h>

#include <asm/irq.h>

#include <mach/regs-gpio.h> //定義s3c2410的GPIO,S3C2410_GPB5至S3C2410_GPB8

#include <mach/hardware.h> //定義操作s3c2410的GPIO的函數 

#include <linux/device.h> //自動創建設備文件應該包含的頭文件

 

#define DEVICE_NAME  "My_led" //加載模塊後執行cat/proc/devices中看到的設備名稱

#define Led_MAJOR        103        //主設備號

#define LED_ON        1

#define LED_OFF      0

 

//Led的控制引腳

//注意S3C2410_GPB5就是GPIO的編號,類型定義為unsigned long

//編號的規則是把所有的io口從0開始進行統一編號,如S3c2410_GPA0=0 S3c2410_GPA1=1 S3C2410_GPB0=32

static unsigned long led_table[] =

{

    S3C2410_GPB5,

    S3C2410_GPB6,

    S3C2410_GPB7,

    S3C2410_GPB8,

};

 

static int My_led_open(struct inode *inode,struct file *file)

{

    printk("My_led  open\n");

    return 0;

}

 

static int My_led_ioctl(struct inode * inode, struct file * file,unsigned int cmd,unsigned long arg)

{

    if(arg > 4)

    {

      return -1;           

    }

    switch(cmd)

    {

      case LED_ON:

            s3c2410_gpio_setpin(led_table[arg], 0);//設置指定引腳為輸出電平為0

            return 0;

      case LED_OFF:

            s3c2410_gpio_setpin(led_table[arg], 1);//設置指定引腳為輸出電平為1

            return 0;

    default:

    return  -1;

  }

}

 

//定義文件操作 file_operations

static struct file_operations My_led_fops =

{

  .owner = THIS_MODULE,

  .open = My_led_open,

  .ioctl = My_led_ioctl,

};

 

 

static struct class *led_class;

 

static int __init My_led_init(void)

{

  int ret;

  printk("My_led start\n");

 

  //冊字符設備驅動程序

  //參數為主設備號、設備名字、file_operations結構

  //這樣主設備號就與file_operations聯系起來

  ret = register_chrdev(Led_MAJOR, DEVICE_NAME, &My_led_fops);

  if(ret < 0)

  {

      printk("can't register major number\n");

      return ret;

  }

 

  //注冊一個類,使mdev可以在"/dev/目錄下建立設備節點"

  led_class = class_create(THIS_MODULE, DEVICE_NAME);

  if(IS_ERR(led_class))

  {

      printk("failed in My_led class.\n");

      return -1;

  }

  device_create(led_class, NULL, MKDEV(Led_MAJOR,0), NULL, DEVICE_NAME);

  printk(DEVICE_NAME "initialized\n");

  return 0;

}

 

static void __exit My_led_exit(void)

{

  unregister_chrdev(Led_MAJOR, DEVICE_NAME);

  device_destroy(led_class, MKDEV(Led_MAJOR,0));//注銷設備節點

  class_destroy(led_class);//注銷類

}

 

module_init(My_led_init);

module_exit(My_led_exit);

 

MODULE_LICENSE("GPL");

源碼分析:

1.本驅動程序中設備文件的自動創建是通過在驅動初始化代碼裡調用class_create為該設備創建一個class,然後再為設備調用device_create創建對應的設備。class_create和device_create定義在內核源碼include/linux下,可去此目錄查看他們的定義。

2.本驅動程序通過內核中提供的對S3C2410 GPIO的操作函數S3C2410_gpio_setpin來控制指定引腳高低電平的輸出。此函數定義在hardware.h的頭文件中,需在驅動程序中添加#include<mach/hardware.h> 。

3.至於LED燈閃爍效果的實現等下將上層應用程序代碼列出來後再進行分析。

更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2014-08/106010p2.htm

Copyright © Linux教程網 All Rights Reserved