regmap
[TOC] regmapRegmap 简介Regmap 是 Linux 内核中的一个子系统,用于抽象和管理设备寄存器的访问。它为驱动程序提供了统一的接口,支持多种总线(如 I2C、SPI、MMIO 等)上的寄存器操作,同时提供了缓存、锁机制和调试功能。Regmap 的设计目标是简化驱动开发,减少重复代码,并提高寄存器访问的效率和安全性。 工作原理1. 核心概念 寄存器映射 (Register Map):Regmap 将设备的寄存器抽象为一个统一的映射,屏蔽了底层总线的差异。 寄存器缓存:Regmap 提供了可选的寄存器缓存机制,用于减少总线访问次数,提高性能。 寄存器访问控制:通过配置文件(struct regmap_config),可以定义哪些寄存器是可读、可写或易失的。 总线适配器:Regmap 支持多种总线(如 I2C、SPI、MMIO 等),通过总线适配器实现具体的读写操作。 2. 数据结构 struct regmap:表示寄存器映射的核心数据结构,包含寄存器的地址、值、缓存等信息。 struct regmap_config:配置寄存器映射的结构体,用...
regulator
[TOC] drivers/regulator Regulator框架(Regulator Framework) 内核统一的电源供应管理框架历史与背景这项技术是为了解决什么特定问题而诞生的?Regulator(电源稳压器)框架的诞生是为了解决在现代嵌入式系统(尤其是SoC)中一个核心且日益复杂的问题:电源管理。 在此框架出现之前,对电源的控制是混乱、不可移植且与硬件高度耦合的: 代码的混乱与不可移植:设备驱动程序(例如一个Wi-Fi芯片驱动)需要电源才能工作。在没有统一框架的情况下,这个驱动必须包含特定于某个主板的代码来打开它的电源,例如通过I2C与PMIC(电源管理集成电路)通信,或者直接翻转一个GPIO引脚。这意味着同一个Wi-Fi驱动,如果要用在另一块使用不同PMIC的主板上,就需要被修改和重新编译。 缺乏电源拓扑视图:内核无法了解系统中复杂的电源供应关系(即“电源树”),例如哪个LDO(低压差稳压器)是由哪个Buck(降压)转换器供电的。这使得实现复杂的、系统级的电源优化变得几乎不可能。 无法实现动态电压与频率调整(DVFS):DVFS是现代CPU节能的...
reset
[TOC] drivers/reset/core.c 复位控制器框架(Reset Controller Framework) 内核统一的硬件复位管理机制历史与背景这项技术是为了解决什么特定问题而诞生的?Reset(复位)控制器框架的诞生是为了解决在现代SoC(片上系统)中一个基本但关键的问题:如何以一种统一、可移植、安全的方式来管理硬件外设的复位信号。 在此框架出现之前,对硬件复位的控制是零散且与平台强耦合的: 代码的混乱与不可移植:一个设备驱动程序(例如以太网控制器驱动)在初始化硬件时,通常需要先对硬件进行一次复位,以确保其处于一个已知的、干净的状态。在没有统一框架的情况下,驱动程序必须包含特定于某个SoC的代码来执行这个操作,例如直接读写某个全局的复位寄存器,或者手动翻转一个GPIO引脚。这导致驱动代码充满了平台相关的实现,难以移植。 缺乏资源管理:复位信号线是共享资源。没有一个中央管理机制,就无法防止两个不同的驱动程序意外地去控制同一个复位信号,或者在一个驱动正在使用某个设备时,另一个驱动错误地将其复位。 操作顺序的复杂性:复位操作通常需要精确的...
rtc
[TOC] drivers/rtc 实时时钟(Real Time Clock) 驱动框架与硬件驱动集合历史与背景这项技术是为了解决什么特定问题而诞生的?RTC(Real Time Clock)驱动框架和相关驱动是为了解决计算机系统在**主电源关闭后维持和提供真实世界时间(“wall-clock time”)**这一根本问题而诞生的。 时间持久化:计算机系统的主处理器和内存是易失性的,一旦断电,所有状态信息都会丢失。然而,系统需要一个持久化的时钟来记录日期和时间,以便在下次启动时能够知道当前的时间,这对于文件系统时间戳、日志记录、证书验证和网络协议至关重要。 低功耗运行:这个持久化的时钟必须功耗极低,因为它通常仅由一块小型的纽扣电池供电,需要维持数年的运行。 定时唤醒:除了计时,RTC硬件通常还具备闹钟(Alarm)功能。这允许系统进入深度休眠或关机状态,并由RTC在预设的时间点产生一个硬件中断信号,从而唤醒系统执行预定任务(如定时备份、系统维护等),这是实现高级电源管理的关键。 它的发展经历了哪些重要的里程碑或版本迭代?Linux RTC子系统的发展反映了Li...
watchdog
[toc] drivers/watchdog Watchdog子系统(Watchdog Subsystem) 确保系统在软件故障时自动重启历史与背景这项技术是为了解决什么特定问题而诞生的?Watchdog(看门狗)子系统的诞生是为了解决一个在计算系统中,尤其是高可靠性系统中,至关重要的问题:如何从致命的软件故障中自动恢复。 软件系统可能会因为各种原因(如内核死锁、驱动程序中的无限循环、用户空间关键进程假死)而完全“卡死”(Hang),导致系统停止响应。在这种状态下,系统无法执行任何有效任务,也无法被正常地远程管理。对于无人值守的嵌入式设备或需要高可用性的服务器而言,这种状态是不可接受的。 Watchdog技术通过一个简单的“死人开关”(Dead Man’s Switch)机制来解决这个问题: 它提供一个硬件或软件定时器,一旦启动,就会开始倒计时。 系统中的监控软件(通常是一个用户空间的守护进程)必须周期性地“喂狗”(Feed the dog)或“踢狗”(Kick the dog),即重置这个定时器。 如果监控软件因为系统卡死而未能按时重置定时器,定时器就会超时。...
atomic
[TOC] include/asm-generic/bitops/generic-non-atomic.h generic_test_bit 和 const_test_bit 是两个用于测试位图中某个位是否被设置的函数。它们的实现方式略有不同,主要体现在对 volatile 关键字的使用上。generic_test_bit 函数使用了 volatile 关键字,这意味着它会读取内存中的值,而不是使用寄存器中的缓存值。这对于多线程或中断上下文中的位操作非常重要,因为它确保了读取的是最新的值。const_test_bit 函数则不使用 volatile 关键字,这意味着它可以在编译时进行优化,适用于编译时常量的测试。两者的实现都使用了位操作来确定指定的位是否被设置。这里仅进行了读取操作,没有进行写入操作.所以不需要进行原子操作 generic_test_bit 这里具有volatile会在每次读取时都从内存中读取值,而不是进行优化 1234567891011121314/** * generic_test_bit - 确定是否设置了位 * @n...
bits
[toc] include/linux/bits.hBIT_WORD 位图的字数12345678//include/asm-generic/bitsperlong.h#ifdef CONFIG_64BIT#define BITS_PER_LONG 64#else#define BITS_PER_LONG 32#endif /* CONFIG_64BIT */#define BIT_WORD(nr) ((nr) / BITS_PER_LONG) include/linux/bitmap.hbitmap_weight 位图的权重 用于计算位图(bitmap)中设置为 1 的位的数量(即权重) 1234567static __always_inlineunsigned int bitmap_weight(const unsigned long *src, unsigned int nbits){ if (small_const_nbits(nbits)) return hweight_long(*src & BIT...
compiler
[toc] include/linux/build_bug.hstatic_assert 静态编译警告123456789101112131415161718/** * static_assert - 在构建时检查整数常量表达式 * * static_assert() 是 C11 _Static_assert的包装器,具有 * little 宏魔术使消息成为可选的(默认为 * 测试表达式的字符串化)。 * * 与 BUILD_BUG_ON() 相反,static_assert() 可以在 global * 范围,但要求表达式为整数常量 * 表达式(即,__builtin_constant_p() 是不够的 * true 表示 expr)。 * * 另请注意BUILD_BUG_ON,如果条件为 * true,而 static_assert() 如果表达式为 *假。 */#define static_assert(expr, ...) __static_assert(expr, ##__VA_ARGS__, #expr)#define __static_ass...
hashtable
[TOC] include/linux/hashtable.hDEFINE_HASHTABLE 定义哈希表123#define DEFINE_HASHTABLE(name, bits) \ struct hlist_head name[1 << (bits)] = \ { [0 ... ((1 << (bits)) - 1)] = HLIST_HEAD_INIT } hlist_for_each_entry 遍历哈希表12345678910111213141516171819202122232425262728293031323334#define hlist_entry(ptr, type, member) container_of(ptr,type,member)#define hlist_for_each(pos, head) \ for (pos = (head)->first; pos ; pos = pos->next)#define hlist_for_each...
内存管理与访问
[toc] include/linux/cache.h: 提供与CPU缓存行对齐相关的宏,如 ____cacheline_aligned__cacheline_aligned 缓存行对齐 这个修饰符确保变量在内存中对齐到缓存行的边界上。缓存行对齐可以减少缓存行冲突,提高缓存命中率,从而提高系统性能。在多处理器系统中,缓存行对齐尤为重要,因为多个处理器可能同时访问相同的内存区域。通过对齐,可以减少缓存一致性协议带来的开销。 在多处理器系统中,缓存行对齐可以减少缓存一致性协议带来的开销,主要原因如下: 缓存一致性协议:在多处理器系统中,每个处理器都有自己的缓存,用于存储频繁访问的数据。为了确保所有处理器看到的数据是一致的,系统使用缓存一致性协议(如MESI协议)。当一个处理器修改了某个缓存行中的数据,其他处理器必须更新或失效其缓存中的相应数据。这种一致性维护会带来额外的开销。 缓存行对齐的好处 减少伪共享:伪共享(False Sharing)是指多个处理器访问同一个缓存行中的不同数据项,导致频繁的缓存一致性操作。通过缓存行对齐,可以确保每个处理器访问的...








