驱动两大利器︰电路图(通过电路图找寄存器)和芯片手册。
寄存器
芯片手册第六章P89∶
字段名 | 描述 | 用法 |
---|---|---|
GPFSEL0 | GPIO Function select 0,功能选择输出/输入 | 以引脚9举例:000 = GPIO Pin 9 is an input 001 = GPIO Pin 9 is an output |
GPSET0 | GPIO Pin output Set 0,输出0 | 0 = No effect 1 = Set GPIO pin n |
GPSET1 | GPIO Pin output set 1,输出1 | 0 = No effect 1 = Set GPIO pin n |
GPCLR0 | GPIO Pin output clear 0,清0 | 0 = No effect 1 = Clear GPIO pin n |
文档中的功能说的非常清楚了,引脚输出是001,输入是000等等,我们的寄存器都是分组的,寄存器第0组是FESL0–9,寄存器第1组是FESL0–9…如图所示。
需要注意的是,我们寄存器对应的引脚是BCM,而不是wiringPi的引脚,如图所示。
更多的引脚详细介绍可以去树莓派官网查看
https://pinout.xyz/pinout/pin7_gpio4
我们在编写驱动程序的时候,IO空间的起始地址是0x3f000000,加上GPIO的偏移量0x2000000,所以GPIO的物理地址应该是从0x3f200000开始的,然后在这个基础上进行Linux系统的MMU内存虚拟化管理,映射到虚拟地址上。
特别注意,BCM2708 和BCM2709 IO起始地址不同,BCM2708是0x20000000,BCM2709是0x3f000000,这是造成大部分人驱动出现“段错误”的原因。树莓派3B的CPU为BCM2709。
通过对首图的尾部偏移,那么GPIO的物理地址0x3f200000的偏移也应如此。
GPFSEL0 0x3f200000
GPSET0 0x3f20001c
GPCLR0 0x3f200028