mini2440 led驱动程序经典分析

Linux内核为2.6.32.2

源码分析工具source insight

前言:在裸机中操作几个gpio口很简单,对控制寄存器和数据寄存器进行配置即可,但要在linux系统中实现同样的功能还是得费上一番周折的。

以下是驱动的源码。

#include <……>
#define DEVICE_NAME "leds"        //设备名

static unsigned long led_table [] = {
 S3C2410_GPB(5),
 S3C2410_GPB(6),
 S3C2410_GPB(7),
 S3C2410_GPB(8),
};

static unsigned int led_cfg_table [] = {
 S3C2410_GPIO_OUTPUT,
 S3C2410_GPIO_OUTPUT,
 S3C2410_GPIO_OUTPUT,
 S3C2410_GPIO_OUTPUT,
};

static int sbc2440_leds_ioctl(
 struct inode *inode,
 struct file *file,
 unsigned int cmd,
 unsigned long arg)
{
 switch(cmd) {
 case 0:
 case 1:
  if (arg > 4) {
  return -EINVAL;
  }
  s3c2410_gpio_setpin(led_table[arg], !cmd);
  return 0;
 default:
  return -EINVAL;
 }
}

static struct file_operations dev_fops = {
 .owner = THIS_MODULE,
 .ioctl = sbc2440_leds_ioctl,
};

static struct miscdevice misc = {  //杂项设备结构体
 .minor = MISC_DYNAMIC_MINOR,      //次设备号
 .name = DEVICE_NAME,
 .fops = &dev_fops,
};

static int __init dev_init(void)
{
 int ret;

int i;
 
 for (i = 0; i < 4; i++) {
  s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);
  s3c2410_gpio_setpin(led_table[i], 0);
 }

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

printk (DEVICE_NAME"\tinitialized\n");

return ret;
}

static void __exit dev_exit(void)
{
 misc_deregister(&misc);                      //混杂设备注销                             
}

module_init(dev_init);                      //模块加载函数             

module_exit(dev_exit);                      //模块卸载函数
MODULE_LICENSE("GPL");                          //证书
MODULE_AUTHOR("FriendlyARM Inc.");              //作者

以上列出了加入简单注释的MINI2440led驱动程序的源码,头文件已被省去。对于上述的驱动,我们主要分析这个驱动的整体框架以及里面涉及到的一些重要的函数和宏定义内容。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/d562f68641e0e5c5b0954599b055a0c0.html