《Android深度探索(卷1):HAL与驱动开发》——1.7节见识一下什么叫Linux驱动:LED...

本节书摘来自异步社区《Android深度探索(卷1):HAL与驱动开发》一书中的第1章,第1.7节见识一下什么叫Linux驱动:LED,作者李宁,更多章节内容可以访问云栖社区“异步社区”公众号查看

1.7 见识一下什么叫Linux驱动:LED
Android深度探索(卷1):HAL与驱动开发
Linux驱动这个家伙到现在为止仍然是只见其声,未见其人,不过在本节会向读者展示一下Linux驱动到底是个什么东西。如果读者看到Linux驱动的代码感到头晕,这属于正常现象。因为如果一看就明白的话,那就没有阅读本书的必要了。本节的目的只为向读者展示Linux驱动程序的结构,以及使读者对Linux驱动有一个大致的印象,读者无须理解其中的细节。当读者阅读完本书时,自然会对这些细节部分了如指掌。

下面给出一个简单的Linux驱动的核心代码(用C语言实现),这个驱动的作用就是控制S3C6410开发板上的4个LED(关于开发板的使用方法将在后面详细介绍)。我们姑且将其称为LED驱动。LED驱动属于字符设备驱动,核心代码如下:

#include <linux/miscdevice.h>
… …
//此处包含了多个头文件

// 定义了设备名,驱动程序会在/dev目录下建立一个leds设备文件,通过访问该设备文件可以访问LED驱动
#define DEVICE_NAME "leds"
// 向LED发送数据及从LED读取数据
static long s3c6410_leds_ioctl(struct file *filp, unsigned int cmd,
    unsigned long arg)
{
switch (cmd)
{
  unsigned tmp;
  case 0:
  case 1:
  if (arg > 4)
  {
      return -EINVAL;
  }
  tmp = readl(S3C64XX_GPMDAT);

  if (cmd == 0) // 关闭LED
  {
     tmp &= (~(1 << arg));
  }
  else     // 打开LED
  {
     tmp |= (1 << arg);
  }
   // 向LED设备写数据
  writel(tmp, S3C64XX_GPMDAT);
   // 输出调试信息
  printk(DEVICE_NAME"_lining: %d %d\n", arg, cmd);
  return 0;
  default:
  return -EINVAL;
}
}
// 描述设备文件的操作和相关数据的结构体
static struct file_operations dev_fops =
{ .owner = THIS_MODULE, .unlocked_ioctl = s3c6410_leds_ioctl, };

static struct miscdevice misc =
{ .minor = MISC_DYNAMIC_MINOR, .name = DEVICE_NAME, .fops = &dev_fops, };
// 驱动的初始化函数
static int _init dev_init(void)
{
int ret;

unsigned tmp;

//gpm0-3 pull up
tmp = readl(S3C64XX_GPMPUD);
tmp &= (~0xFF);
tmp |= 0xaa;
writel(tmp,S3C64XX_GPMPUD);

//gpm0-3 output mode
tmp =readl(S3C64XX_GPMCON);
tmp &= (~0xFFFF);
tmp |= 0x1111;
writel(tmp,S3C64XX_GPMCON);

//gpm0-3 output 0
tmp = _raw_readl(S3C64XX_GPMDAT);
tmp |= 0x10;
writel(tmp,S3C64XX_GPMDAT);

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);
// 指定了当前驱动在哪个协议下发布,在这里是GPL协议
MODULE_LICENSE("GPL");

LED驱动的代码涉及了很多系统的函数和结构体,如readl、writel、printk、miscdevice 、module_exit 、file_operations、miscdevice等。读者目前并不需要了解这些函数和结构体的作用和使用方法。只要知道任何的Linux驱动都有一个装载函数(装载驱动时调用)和一个卸载函数(卸载驱动时调用)即可。装载函数和卸载函数分别通过mobule_init和module_exit宏指定。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值