《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宏指定。

相关文章
|
1月前
|
Linux Shell C语言
【Shell 命令集合 设备管理 】Linux控制Linux系统的键盘LED setleds命令 使用指南
【Shell 命令集合 设备管理 】Linux控制Linux系统的键盘LED setleds命令 使用指南
37 0
|
1天前
|
Linux Shell Android开发
自动化脚本之GPIO/LED相关适用于Android/Linux
自动化脚本之GPIO/LED相关适用于Android/Linux
8 0
|
2天前
|
Linux 编译器 Android开发
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
在Linux环境下,本文指导如何交叉编译x265的so库以适应Android。首先,需安装cmake和下载android-ndk-r21e。接着,下载x265源码,修改crosscompile.cmake的编译器设置。配置x265源码,使用指定的NDK路径,并在配置界面修改相关选项。随后,修改编译规则,编译并安装x265,调整pc描述文件并更新PKG_CONFIG_PATH。最后,修改FFmpeg配置脚本启用x265支持,编译安装FFmpeg,将生成的so文件导入Android工程,调整gradle配置以确保顺利运行。
20 1
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
|
1月前
|
Linux
linux驱动开发-点亮第一个led灯
linux驱动开发-点亮第一个led灯
22 0
|
2月前
|
Linux 芯片 开发者
Linux 驱动开发基础知识——内核对设备树的处理与使用(十)
Linux 驱动开发基础知识——内核对设备树的处理与使用(十)
160 0
Linux 驱动开发基础知识——内核对设备树的处理与使用(十)
|
2月前
|
Ubuntu Linux 芯片
Linux 驱动开发基础知识——设备树的语法驱动开发基础知识(九)
Linux 驱动开发基础知识——设备树的语法驱动开发基础知识(九)
70 1
Linux 驱动开发基础知识——设备树的语法驱动开发基础知识(九)
|
2月前
|
Linux
Linux 驱动开发基础知识——总线设备驱动模型(八)
Linux 驱动开发基础知识——总线设备驱动模型(八)
39 0
Linux 驱动开发基础知识——总线设备驱动模型(八)
|
2月前
|
Linux
Linux 驱动开发基础知识——总线设备驱动模型(七)
Linux 驱动开发基础知识——总线设备驱动模型(七)
50 0
Linux 驱动开发基础知识——总线设备驱动模型(七)
|
2月前
|
Linux 芯片
Linux 驱动开发基础知识—— 驱动设计的思想(六)
Linux 驱动开发基础知识—— 驱动设计的思想(六)
51 0
Linux 驱动开发基础知识—— 驱动设计的思想(六)
|
2月前
|
Linux 编译器 芯片
Linux 驱动开发基础知识—— 具体单板的 LED 驱动程序(五)
Linux 驱动开发基础知识—— 具体单板的 LED 驱动程序(五)
50 0
Linux 驱动开发基础知识—— 具体单板的 LED 驱动程序(五)