关键词:eCos器件,驱动AT45DB dataflash,GNU工具,开源,Ronetix EB55800评估板
这篇文章告诉你如何为Atmel的SPI DataFlash建立一个eCos设备驱动。我们将要运行eCos的硬件是Ronetix EB55800评估板,这个是可以被Atmel AT91M55800 CPU驱动的。这个板有外加的512KB SRAM,2MB的FLASH和有1分辨率的 Dataflash数据存储的AT45DB011B。
低成本启动资金对于产品的开发很重要,当然,最好是像免费的GNU GCC系列和源代码公开的RTOS eCos开发工具用到你的项目里。
GNU GCC 不需要介绍,它是正式的Linux序列开发工具,但是简而言之:GNU GCC是一款高质量的,免费的,开放源码包的可以支持很多处理器(从8位AVR到32位ARM)的工具。
eCos支持很多的开发平台,包括现在流行的ARM7TDMI核(也叫做21世纪的8051),已经被设计成大多数32位微处理器了。eCos是可配置的,它的ROM从20KB(仅可配置的核)到几百KB(包括一个完整函数TCP/IP堆积,文件系统的支持等等)。
eCos包含很多准备好将要用的工具包,像一个FAT文件系统执行,TCP/IP堆栈,以太网和其他设备驱动。但是在OS里面自动提供的不一定能满足你所有的驱动,如果你工程里的设备的驱动在eCos没有的,你需要自己写驱动。
这篇文章告诉你如何为Atmel的SPI DataFlash建立一个eCos设备驱动。我们将要运行eCos的硬件是Ronetix EB55800评估板,这个是可以被Atmel AT91M55800 CPU驱动的。这个板有外加的512KB SRAM,2MB的FLASH和有1分辨率的 Dataflash数据存储的AT45DB011B。
每个调试器需要一个硬件的接口来调试内部的设备。我用Ronetix'的 PEEDI,它是一个像二合一的工具:一个支持很多调试器的接口,一个拥有可支持超过800种闪存芯片的闪存编程器。PEEDI在push-to-program方式下可以像单机一样运行(没有pc的连接和任何的文件服务器,仅有一根电源线),当其他的板需要很多时间调试的时候PEEDI可以节省大量的时间。
移动驱动器
我给你展示的驱动器是AT91M55800 SPI的 DataFlash驱动器,因为AT45DB011B是一个SPI驱动。
幸运的是,eCos提供AT91M55800 的SPI的驱动,我们直接可以用了。每个eCos驱动设备都需要用两个OS-provided的宏“注册”它自己,所以它的init函数每次都会调用,不论什么时候,只要应用程序引用cyg_io_lookup()跟设备连接,OS boots和它的查找函数将会被调用。具体说明这个设备的名字是争论点。
这两个宏是BLOCK_DEVIO_TABLE() and BLOCK_DEVTAB_ENTRY().
关于SPI驱动的eCos,在那时候我们需要确定一个简单的SPI操作参与,作为多用户终端执行程序我们需要校准ISP的过程:
cyg_mutex_t mutex; // mutex used to synchronize the access |
每个驱动都要输出指向最少五个强制的函数指针:
-init 函数—以前提过的,叫做OS boot
-lookup函数—当用户程序每次连接到设备的时候访问的
-write和read函数—用来传输数据的
-set和get设备构造函数。
在我们的例子里,init函数仅用来初始化mutex和 SPI设备的连接:
cyg_mutex_init( &mutex ); // init the mutex we use |
然后,驱动函数在进入的时候要封锁mutex,在推出的时候释放它。
现在,有了驱动的检查函数。这个函数在实际的用途能够很好的建立设备,打开中断,设置控制器等等。但我们不需要做什么,所有需要的工作都被eCos SPI驱动做完了。
我们当然需要一个函数用来等待DataFlash完成当前内在的运行。如果能建立一个RDY flag来预先确定时间的话将是一个很好的主意。这就是我们面临在第一次发送什么样的命令给DataFlash。每个SPI设备在接受信号的时候都要发送数据,在我们例子里指向板的命令和第二次的数据输入—这个板发送给我们的在STATUS REGISTER READ里的指令是我们将要检测到的状态寄存器的值。
cyg_mutex_lock( &mutex ); |
cyc_spi_transfer()函数是通过SPI接口发送和接受数据的。第一个争论就是对接口的把握,第二个就是类型的转变,即剪切,没有中断,跟随着字节数将会被发送/接受,最好到达TX和RX缓冲器。
第七个位状态寄存器,作为接受数据的第二个位,是我们感兴趣的RDY位,所以让我们检查它。
cyg_spi_transfer(spi_device, FLAG_POLLED, 2, tx_buff, rx_buff); |
当和SPI接口工作的时候读和写的驱动函数有点稍微的不同:they use cyg_spi_transaction_begin(), cyg_spi_transaction_transfer() 和 cyg_spi_transaction_end(),这是由于过去经常用的复杂的读指令:
在这个写驱动函数里,在每一个新页写之前,这个集成芯片一定要完成当前的写运行,所以集成块的状态一定要检查。
我们几乎都做完了,但我们需要执行这个驱动的取值/设定的配置函数。这里没有多少要设置了,所以这个函数是空的,我用get config函数回到 FlashData 集成块:
if ( rx_buff[1] & 0x80 ) break; // check if the chip is ready |
把驱动器带到生活中来
有时候这里还有更麻烦的事—使它工作。在以前,深入内核的调试是不容易的。但是当CPUs含有特殊的调试电路的时候,就变得简单了。这个调试电路允许开发者直接读和写CPU 的寄存器和存储器,或者用中断和观察点来管理核的执行。像Ronetix's PEEDI的JTAG这个接口工具就能实现这个功能。现在这就像调试PC桌面程序一样简单!
总的来说,这个调试器跟PEEDI连接(在我们的例子里,GNU在调试器里),发送不同的调试指令,为了腾出特殊的调试电路(在ARM7 CPUs叫做EmbeddedICE)来理解,PEEDI被转移到JTAG指令。虽然我们的测试应用程序很小,下载速度不那么重要了,一个深入的程序可以超过1MB,所以下载的时间变得很显著了。但是用带JTAG的PEEDI可以达到1MB/s,下载这么大的工程来说已经很快了。
为了测试这个驱动,我写了一些测试路径如下,这样可以使驱动很好的掌握,写一些东西到DataFlash里,读取回来保证所有的ok了。这里我用eCos驱动IO API函数:
// start SPI access |
为了调试我的计算机应用程序测试,首先我需要启动内部调试器指向编制执行中的example1_ram:
为了连接到PEEDI,我要把它加到 Insight的控制窗口:
int at45_get_config(cyg_io_handle_t handle, int key, void *buffer, cyg_uint32 *len) |
192.168.1.10是IP地址我分配给PEEDI的,2000是TCP port等待从调试器上连接的。
现在我可以下载我的应用程序到目标的存储地:
// declare device handler |
在连接的过程中,它会下载需要的程序部分到目标存储空间,你可以用连接脚本文件管理这些地址。当下载指令被执行后,Insight将会设置PC到应用程序的进入点。
我想确定我的应用程序在所有中断关闭的情况下启动,所以我将会设置 CPSR 存储器。
我的应用程序已经准备调试了,我将会在我想知道发生什么的地方放一些中断点。实际上,我会启动执行:
arm-elf-insight example1_ram |
为了使我的文件更加简单,在Insight初始化文件里我定义了我自己的指令,然后在启动的时候告诉Insight下载文件:
(gdb) target remote 192.168.1.10:2000 |
my_gdb_初始化文件包含着些:
最后我想提到PEEDI可以同样用在一些企业如ARM,IAR,GreenHill等生产的知名的商业ARM调试器里。
让我们把它烧到FLASH里
当测试我的驱动时,我想看看它是如何从Flash执行的。PEEDI给了我知道另外一个真相的机会—快速和强大。用FLASH编程器很简单。所有我需要对我应用程序编写的都经过协议连接到PEEDI上了。
(gdb) load |
另外,当一个目标连接到JTAG时候,如果我设定它立刻启动编程,PEEDI将会简化和提高了编写大的目标程序的速度。所以我要做的就是把下一个目标连接到PEEDI上。
未来的计划
现在有一个数据保存的驱动器,你或许会想建另外一个驱动器读取它—一一个文件系统!一个很好的选择就是YAFFS—一个快速轻便的FLASH文件系统。
索取更多资料,请联系我们:
广州虹科电子 http://www.hkaco.com
吴工 020-38743030 wj@hkaco.com QQ:534807413
文章评论(0条评论)
登录后参与讨论