- UID
- 1029342
- 性别
- 男
|
最近花了一个多星期写了一个SPI驱动。这个驱动是用来读写SPI接口的BIOS Flash的。貌似这个FLASH的SPI对端(及主控制端)是与其它设备共同通过一个PCI桥接设备挂在PCI总线上。 SPI接口四条线,一个时钟CLK,一个片选CE,以及两数据线MOSI和MISO(主出从入和主入从出)。由于这里的SPI时序等都已经由SPI控制器做好了,所以我要做的就是读些那些控制器上的寄存器来控制读些flash,这个控制器的型号我不知道,是intel,貌似有点类似ICH系列的, flash是SST25VF016B的。
1、 SPI读Flash。
i)往地址寄存器中写入addr。
ii)设置好下一条执行命令,要读的数据个数,是否采用ACS(Atomic cycle Sequence,读书据时我没用这个,如设置它需设置好pre 命令),这些都可通过控制寄存器设置。
iii)清调状态寄存器的CDS等标志,然后读取SCIP标志确认设备空闲后,将控制寄存器在ii)的基础上置SCG0标志,这样SPI控制器将会启动一个读flash的过程。
iv)读取状态寄存器,确认读取过程后,从数据寄存器读取出数据。
2、SPI写Flash。整个流程与1类似,只是在i)中加入往数据寄存器中写入要发的数据,在iii)中需启动acs使flash写使能。但需要注意的是由于flash的只可1变0,而不可直接0写变成1,在写之前一般要将flash相关区域擦除下,而且flash本身的写保护以及主控端的BIOS写保护都得关掉,具体可参看手册。
3、整个驱动是字符类型的,遵循一般的linux字符驱动编写流程,只是配置信息是从PCI桥接设备的寄存器中读出的。
4、说明。写flash要写擦flash,但写时,很难判断当前flash 是否已擦除,所以我把擦flash独立到了ioctl操作中,而写flash就只管写了,这也符合功能独立的原则。
5、写驱动,如果对并发同步效率的要求不高的话,基本上就只剩下读写寄存器操作了。读写寄存器虽然机械,但一定要小心,因为寄存器之间是有耦合的,在操作某个寄存器时,一定也要检查相关的寄存器是否已正确设置,不要想当然。我当初就是忘了自己已经使能了BIOS写保护,而导致一个上午没写成功flash。
6、驱动是细心活。建议先单元测试,再集成测试。一下子就来集成测试问题可能有一大堆,会打击信心的~
最后贴上整个驱动的源码,没什么注释,大家将就下。相应的用户空间程序,见零一篇文章《读写SPI FLASH--应用程序部分》 |
|