本篇总结学驱动的抽象思维,作为写指导写驱动的思想,水平有限,持续更新:
看了Cortext M3的驱动编写,觉得主要作的工作是:
1.获取准确的时钟——用于延时。然后,可以根据基准时钟,例如获取了系统时钟,用数学公式,衍化成自己想要的延时。
2.寄存器——每个寄存器对应着管脚/具体功能。每当想到一个功能和管脚,第一反应应该是找datasheet,查找对应的寄存器和应该设定的值。有的程序是用enum枚举每个管脚的值的,而有的是用0x000000H这样的方式,定义值。关于管脚寄存器,在底层的机器代码中,其实就是做了地址映射,规定好哪个物理地址可以控制哪个管脚。如果具备数字电路知识,应该能理解为啥0x000FFFFE 就代表了某个GPIO脚。 我觉得这也是我们需要理解的,不要死记。
3.协议——高低电平。寄存器都是分散的资源,即使你把几十页,上百页的寄存器背下来,也无助于你写驱动。写驱动要以协议为准,高屋建瓴,协议规定了什么时候哪个端口该高电平,什么时候低电平,什么时候应该切换电平。然后,根据这些信息,去找管脚对应的寄存器(一般GPIO.h会define对应的管脚),然后我们根据功能重新define管脚宏名,方便理解记忆,本质上还是操作寄存器。所以,重点还是把协议的时序搞懂,知道多少毫秒或微秒需要拉高电平,知道要持续多长时间,等。
4.控制器——这是个好东西,如果有了针对某种协议如SPI和I2C的控制器,就不需要自己写控制时序函数了,转而只需要写控制器对应的寄存器,让控制器去控制时序,这样可以省掉很多功夫。所以,我们看到别人写驱动,有时候很注重时序,有时候不管时序。