Linux 3.10内核ARMv7架构下readl()与writel()是否会阻塞?
readl()/writel() 在ARMv7 Linux 3.10下是否会阻塞?
结论:readl()和writel()本身不会导致内核线程阻塞,以下是具体分析:
1. 函数本质:无阻塞的MMIO读写操作
从你给出的内核代码来看:
readl()是对__raw_readl()的封装,仅增加了字节序转换(__le32_to_cpu)__raw_writel()直接通过 volatile 指针完成32位写操作
在ARMv7架构下,这类MMIO(内存映射IO)读写对应的是CPU的同步总线指令(比如LDR/STR):
- 执行时CPU会等待总线完成单次读写传输,但这个等待是指令执行周期内的硬件级等待,耗时极短(通常几个时钟周期)
- 整个过程不会触发内核调度,也不会让当前线程进入睡眠状态,完全不属于内核定义的“阻塞”行为
2. SPI场景的误区:轮询≠阻塞
如果在SPI通信中出现长时间等待,那通常是业务代码的轮询逻辑导致的忙等,而非readl()/writel()本身阻塞:
- 比如你用
readl()循环读取SPI控制器的状态寄存器,等待发送/接收完成标志位 - 这种情况下CPU一直在执行循环和readl()操作,没有让出CPU,属于忙等,并非线程阻塞(阻塞是指线程主动睡眠、让出CPU资源)
3. 关键概念区分
- 阻塞:线程进入睡眠状态(如
TASK_UNINTERRUPTIBLE),主动放弃CPU,直到某个事件触发(比如中断)才被唤醒 - 忙等:线程持续占用CPU循环执行指令,不放弃控制权,属于原地等待,而非阻塞
readl()/writel()的执行只会产生极短的硬件级等待,既不属于阻塞,也不会导致长时间的忙等——除非你在代码里基于它们实现了轮询逻辑。
内容的提问来源于stack exchange,提问作者just a student
相关产品推荐
相关产品推荐

