Linux -- 字符设备驱动--LED的驱动开发(初级框架)

驱动框架一阶段

我们怎样去点亮一个 LED 呢?分为三步:

  1. 看原理图确定引脚,确定引脚输出什么电平才能点亮/熄灭 LED
  2. 看主芯片手册,确定寄存器操作方法:哪些寄存器?哪些位?地址是?
  3. 编写驱动:先写框架,再写硬件操作的代码
    注意 :在芯片手册中确定的寄存器地址被称为 物理地址 ,在 Linux 内核中无法直接使用。
    需要使用内核提供的 ioremap 把物理地址映射为 虚拟地址 ,使用虚拟地址。
    ioremap 函数的使用:

编写驱动程序的套路:

  • 确定主设备号,也可以让内核分配;
  • 定义自己的 file_operations 结构体;
  • 实现对应的 drv_open/drv_read/drv_write 等函数,填入 file_operations 结构体;
  • 把 file_operations 结构体告诉内核:register_chrdev**;**
  • 谁来注册驱动程序啊?得有一个入口函数:安装驱动程序时,就会去调用这个入口函数;
  • 有入口函数就应该有出口函数:卸载驱动程序时,出口函数调用 unregister_chrdev
  • 其他完善:提供设备信息,自动创建设备节点:class_create, device_create

驱动怎么操作硬件?
◼ 通过 ioremap 映射寄存器的物理地址得到虚拟地址,读写虚拟地址。驱动层访问硬件外设寄存器依靠的是 ioremap 函数去映射到寄存器地址,然后开始控制寄存器。
驱动怎么和 APP 传输数据?
◼ 通过 copy_to_user 、 copy_from_user 这 2 个函数。

驱动框架二阶段:分层思想

  • 上层实现硬件无关的操作,比如注册字符设备驱动:leddrv.c
  • 下层实现硬件相关的操作,比如 board_A.c 实现单板 A 的 LED 操作

驱动框架三阶段:分离

引脚操作那么有规律,并且这是跟主芯片相关的,那可以针对该芯片写出比较通用的硬件操作代码。
比如 board_A.c 使用芯片 chipY ,那就可以写出: chipY_gpio.c ,它实现 芯片 Y 的 GPIO 操作,适用于芯片 Y 的所有 GPIO 引脚。
使用时,我们只需要在 board_A_led.c 中指定使用哪一个引脚即可。程序结构如下:

以面向对象的思想,在 board_A_led.c 中实现 led_resouce 结构体,它定 义"资源"──要用哪一个引脚。
在 chipY_gpio.c 中仍是实现 led_operations 结构体,它要写得更完善,支持所有 GPIO 。
总结:
程序仍分为上下结构:
上层 leddrv.c 向内核注册 file_operations 结构体;
下层 chip_demo_gpio.c 提供 led_operations 结构体来操作硬件。
下层的代码分为 2 个:

  1. chip_demo_gpio.c 实现通用的 GPIO 操作,
  2. board_A_led.c 指定使用哪个 GPIO,即"资源",也就是硬件的引脚信息,它实现一个 led_resource 结构体,并提供访问函数。
相关推荐
晚风予卿云月5 分钟前
【linux】进程优先级
linux·运维·服务器
一拳一个娘娘腔7 分钟前
从sudo配置到Root Shell:Linux Sudo提权全景深度解析与防御指南
linux·网络·安全
万法若空21 分钟前
Cortex-A7的运行模式
linux·arm开发
zhangrelay34 分钟前
三分钟云课实践速通--C/C++程序设计--
linux·c语言·c++·笔记·学习·ubuntu
Max_uuc1 小时前
【调度心法】别用 Mutex 制造“人质危机”!撕碎互斥锁的防御幻觉,论优先级反转与火星探测器的史诗级瘫痪
linux·运维·制造
孙同学_1 小时前
【Linux篇】NTA机制与网络地址转换原理详解
linux·网络·智能路由器
小趴菜要进步1 小时前
Kali/Linux 更改国内镜像源
linux·运维·服务器
cookies_s_s1 小时前
C++ 内存模型与无锁编程:从底层原理到实战
linux·服务器·开发语言·c++
郝学胜-神的一滴2 小时前
Python 鸭子类型:优雅的多态哲学,让代码更自由
linux·服务器·开发语言·python·网络协议
北冥湖畔的燕雀2 小时前
POSIX信号量操作全解析
linux·运维·服务器