Welcome 微信登录
编程资源 图片资源库 蚂蚁家优选 PDF转换器

首页 / 操作系统 / 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.htmUbuntu 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=32static 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 ");    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_operationsstatic 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 ");   //册字符设备驱动程序  //参数为主设备号、设备名字、file_operations结构  //这样主设备号就与file_operations联系起来  ret = register_chrdev(Led_MAJOR, DEVICE_NAME, &My_led_fops);  if(ret < 0)  {      printk("can"t register major number ");      return ret;  }   //注册一个类,使mdev可以在"/dev/目录下建立设备节点"  led_class = class_create(THIS_MODULE, DEVICE_NAME);  if(IS_ERR(led_class))  {      printk("failed in My_led class. ");      return -1;  }  device_create(led_class, NULL, MKDEV(Led_MAJOR,0), NULL, DEVICE_NAME);  printk(DEVICE_NAME "initialized ");  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