加入收藏 | 设为首页 | 会员中心 | 我要投稿 开发网_开封站长网 (http://www.0378zz.com/)- 科技、AI行业应用、媒体智能、低代码、办公协同!
当前位置: 首页 > 教程 > 正文

TQ2440上LED灯闪烁效果的驱动程序达成

发布时间:2021-11-20 13:49:41 所属栏目:教程 来源:互联网
导读:一,驱动程序源代码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 #inc

一,驱动程序源代码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  openn");
 
    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 startn");
 
 
 
  //册字符设备驱动程序
 
  //参数为主设备号、设备名字、file_operations结构
 
  //这样主设备号就与file_operations联系起来
 
  ret = register_chrdev(Led_MAJOR, DEVICE_NAME, &My_led_fops);
 
  if(ret < 0)
 
  {
 
      printk("can't register major numbern");
 
      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 "initializedn");
 
  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灯闪烁效果的实现等下将上层应用程序代码列出来后再进行分析。

(编辑:开发网_开封站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读