为什么在44B0操作RTL8019时必须关闭cache呢?
来源:互联网 发布:莱茵矩阵国际房价走势 编辑:程序博客网 时间:2024/06/02 19:42
最近花了好长一段时间调试44B0板子上的RTL8019网卡驱动,在原来的uboot的驱动中由于参数设置不正确,甚至连数据包都无法发送出来。我将一个在ADS1.2工程中好用的代码移植到uboot内,将原来的8bit模式更改为16bit模式,并对内存控制器的设置也做了相应的修改。本以为这种移植工作应该是比较容易调通的,可是实际调试中却发现,发送数据没有问题了,但是在接收数据时读到的数据长度总是错误的。再仔细追踪调试时,甚至发现设置到MAC地址寄存器的地址也会发生变化,我在程序里初始化阶段设置了一个MAC地址,然后立即读出,发现读出数值与设置值是一样的。在每次发送数据前和接受数据前也都读取一次MAC地址,发现只有第一次发送时读出的数值与最初的设置值是一样的,后面再次发送和接收时读取的数值都是错误的。这个问题困扰了我好久,最初时我还以为是memory controller的设置有问题呢,可是在初始化阶段时能够正确读出RTL8019的芯片ID的,而且对于某个寄存器,如果在写入后立即读出那么其数值也是正确的,因此可以肯定memory controller的设置没有问题啊。那么为什么在后来的读取中MAC地址会改变呢,我在反复对比了程序后发现,原来都是cache搞得鬼。
我们知道44B0内部是有8K的internal memory,这部分memory可以有三种用途。数据手册上的描述如下:The CPU wrapper has an 8-Kbyte internal memory. The internal memory can be used in three ways. First the 8-Kbyte memory can be used as an 8KB unified (instruction/data) cache. Second, the internal memory can be used as a 4-Kbyte unified cache and a 4-Kbyte internal SRAM. Third, the internal memory can be used wholly as an 8-Kbyte internal SRAM.
前两种方式都是作为cache使用的,如果作为cache使用那么是会缓存最近读写的数据的,然而在对外部设备(RTL8019)进行读写时,如果缓存了上次读取的数据,那么下次再次读取时就不会向I/O发送真实的命令,而是会直接取到cache中数据送给CPU。然而,cache中的数据是可能会被改变的,而不从外部设备的寄存器中读取数据也不是程序员设计的本意,因此这是就会出错了。这也就是上面我提到的发现MAC地址寄存器中的数值与设置的数值不一样的原因,其实我的程序后面读到的数据根本就不是真正从RTL8019的registers中读取的,而是从cache中取到的。为了解决这种不一致的问题,在对外部设备操作时通常都是要关闭cache的。
之前,一直在有MMU的ARM处理器上开发程序,知道对于外设I/O的地址空间在设置其page entry属性时必须将其设置为uncached,这样才能保证cache不会对I/O通信造成影响。而44B0中既没有MMU也没有MPU,因此在对外部设备操作前只能采取先关闭cache,然后操作,操作结束后再开启cache的方法了。
以上,我个人的一点分析,不对之处还望指正。
PS:各种数据都表明,cache对处理器性能的提升是很重要的,尤其是在那些对于性能要求较高的场合往往必须要合理高效的利用cache才能实现设计目标,因此掌握如何正确的操作cache也是成为高级嵌入式程序员的必备技能之一吧。
- 为什么在44B0操作RTL8019时必须关闭cache呢?
- 在第一阶段中为什么要关闭Cache
- 为什么必须是final的呢?
- 为什么必须是final的呢?
- iOS 为什么必须在主线程中操作UI
- 为什么必须在主线程中操作UI
- iOS 为什么必须在主线程中操作UI
- uclinux在44B0上的移植
- 44B0
- 流操作时为什么要关闭流
- 为什么要关闭 MySQL Query Cache?
- 没有任何关闭socket的日志,客户端和服务端进程都在, 网络连接完好, 为什么进行某操作后好好的tcp连接莫名其妙地断了呢?
- 没有任何关闭socket的日志,客户端和服务端进程都在, 网络连接完好, 为什么进行某操作后好好的tcp连接莫名其妙地断了呢?
- Android Activity的setTitle,AlertDialog,Toast操作是否都必须在非主UI线程中操作呢?
- 如何在44B0板子的RAM中运行uclinux
- 为什么要漂在北京呢?
- 44B0中断分析
- 44b0中断
- 硬件开发的那点事
- 109_《Delphi4核心编程技术》
- 小字节序和大字节序
- 110_《Delphi4编程技术内幕》
- 111_《数据管理COOL-Delphi 4.0 + Visual FoxPro 6.0》
- 为什么在44B0操作RTL8019时必须关闭cache呢?
- 总结File操作
- 112_《Delphi2高级程序设计指南》
- good man
- 今晚去看下放松一下
- 软件开发中的11个系统思维定律
- linux网卡多IP的配置
- 软件编程十要
- 欢迎大家访问我的博客