花了两周时间(实际上就是一个周末加两三个晚上时间), 终于把eCos网卡驱动——DM9000驱动移植好了。在STM32的片外RAM中运行,ping时间稳定在2ms。
调试过程中,走了一些弯路,遇到了一些比较棘手的问题,如DM9000收发包问题、eCos stm32 GPIO中断、ping一会儿就ping不通了等等。
为了说明的方便,先把自己的调试过程梳理下,呈现给大家,避免大家在调试网卡驱动时走弯路。然后介绍redboot中移植DM9000驱动和eCos中移植DM9000的驱动。
DM9000调试
eCos中已有DM9000网卡的驱动,所以我们的主要工作就是移植并调试。开始时,对DM9000在eCos中的工作方式没弄明白就匆忙调试,导致在移植和调试时候走了一些弯路。
DM9000的工作方式
DM9000在eCos中使用了两种工作模式:轮询方式和中断方式。由于redboot中不支持中断,所以采用的是轮询方式。eCos中采用中断方式,提高对网卡的响应速度。
这个很重要。初始时我没考虑这个问题,调试时发现:DM9000怎么只有发包,没有收包呢?但在PC机上ping板子的时候,DM9000又能收到一些乱七八糟的数据包,而且PC机上能够建立ARP映射关系。这时候就去怀疑DM9000的初始化问题,实际上根本就不是初始化问题,而是中断没有安装成功的问题。
所以移植网卡时,建议先在redboot中移植,再在eCos中移植。因为redboot中是轮询工作方式,所以不用考虑中断是否安装成功等问题。另外,可以帮你确定eCos中的驱动程序是否OK的。
ARP(地址解析协议)
任何网络数据通讯之前,都要先进行ARP,否则就不能通讯。在ping新的目标时,协议层会先驱动网卡广播发送ARP包,正常情况下,目标会返回一个ARP响应包,这样就建立了ARP映射关系(也就是找到了对方在哪里),然后开始正常的数据包收发。
为什么要了解下ARP呢?因为网卡第一个发送的数据包就是ARP数据。当它发送这个ARP包的时候,你可要能认识它哦。下图就是一个ARP包:
打印信息
我是采用串口打印信息来跟踪调试的。DM9000驱动里面有两个宏:DEBUG和DEBUG_DUMP,可以打开这两个宏来跟踪调试信息,当然你也可以增加其它跟踪调试信息。
调试方法与步骤
- 把网卡驱动移植到eCos中并展开调试信息;
- 确定DM9000的访问总线(寄存器读写)没问题,一般能正确读取到DM9000的ID,就说明读写DM9000寄存器正常;
- 把网卡驱动移植到redboot中并展开调试信息;
- 在redboot中调试好后(PC机能ping通,在redboot中也能ping能PC机),然后再在eCos中调试,特别关注中断是否安装成功、是否能正确响应。
eCos DM9000 driver
eCos DM9000驱动分为DM9000芯片驱动和平台网卡定义(platform specific support),后者实际上就是在目标(target)板上定义网卡设备。eCos上的其它网卡驱动都采用这种结构。
DM9000芯片驱动对应的软件包名称:CYGPKG_DEVS_ETH_DAVICOM_DM9000,对应的源文件:if_dm9000.c。驱动支持POLL和中断两种工作方式。
平台网卡定义(platform specific support)
这部分我们参考其它模板来实现,我参考的是FRV的CB70模板,对应目录:ecos/packages/devs/eth/frv/cb70。
把ecos/packages/devs/eth/frv目录下cb70文件夹拷贝到ecos/packages/devs/eth/cortexm目录下,并重命名为:stm32f10xxx,同时也重命名该目录下的相关文件。然后修改CDL和inl文件的内容。怎么修改就不做多介绍了,反正依葫芦画瓢,把一些名称修改掉。
由于MAC地址不从EEPROM中读取,所以在CDL文件中加一个MAC地址配置项:
cdl_option CYGDAT_DEVS_ETH_CORTEXM_STM32_STM32F10XXX_ETH0_NAME { display "Device name for the ETH0 ethernet port driver" flavor data default_value {"\"eth0\""} description " This option sets the name of the ethernet device for a DM9000-based STM32F10XXX board." } cdl_option CYGDAT_DEVS_ETH_CORTEXM_STM32_STM32F10XXX_ETH0_ESA { display "The ethernet station address for the ETH0 ethernet port driver" flavor data default_value {"{0x08, 0x88, 0x12, 0x34, 0x56, 0x78}"} description " This option sets the ethernet station address of the ethernet device for a DM9000-based STM32F10XXX board." }
MAC地址配置项放在了网卡名称配置项后面。
然后在INL文件中添加使用MAC地址配置项(#elif那里):
extern int cyg_hal_dm9000_present(void); //#define CYG_HAL_DM9000_PRESENT() cyg_hal_dm9000_present() #ifdef CYGPKG_DEVS_ETH_CORTEXM_STM32_STM32F10XXX_ETH0 static struct dm9000 dm9000_eth0_priv_data = { #if defined(CYGPKG_REDBOOT) && defined(CYGVAR_ETH_DM9000_REDBOOT_HOLDS_ESA_ETH0) mac_address: CYGDAT_DEVS_ETH_CORTEXM_STM32_STM32F10XXX_ETH0_DEFAULT_ESA, #elif defined(CYGDAT_DEVS_ETH_CORTEXM_STM32_STM32F10XXX_ETH0_ESA) mac_address: CYGDAT_DEVS_ETH_CORTEXM_STM32_STM32F10XXX_ETH0_ESA, #endif io_addr: (volatile unsigned char *)0x6C100000, io_data: (volatile unsigned char *)0x6C100008 };
上面代码中 ,除了添加使用MAC地址配置项,还配置DM9000的io_addr和io_data的地址,屏蔽了CYG_HAL_DM9000_PRESENT(),我们不需要它。
DM9000驱动修改
FSMC初始化
stm32是通过FSMC来访问DM9000的数据和寄存器的。所以,在初始化DM9000之前,必须先初始化好DM9000对应的FSMC Bank。
在我的stm32板子上,DM9000与LCD使用同样的FSMC Bank,所以,它们使用了同样的时序参数,如下代码所示:
// Set up FSMC NOR/SRAM bank 4 for LCD CYG_ADDRESS base = CYGHWR_HAL_STM32_FSMC; HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FSMC_BCR4, 0x00001059 ); // HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FSMC_BTR4, 0x10000201 ); HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FSMC_BTR4, 0x10000502 );
如果在初始化了FSMC Bank时序参数后还不能读取到DM9000的ID,则可以尝试设置下FSMC所用的所有引脚(数据线、地址线、控制线等)。一般情况下,如果LCD驱动正常的话,DM9000的寄存器访问也不会有问题。
MAC地址
上面说了,我们不从EEPROM中读取MAC地址,而是使用配置项定义的MAC地址。因此,需要屏蔽DM9000驱动中相关代码:
#if 0 // Disabled by gyr 2013.05.10 for (i = 0; i < 64; i++) u16tab[i] = eeprom_read(priv, i); u16tab[3] &= ~0xc; u16tab[3] |= 4; u16tab[6] &= 0xfe00; u16tab[6] |= 6; eeprom_write(priv, 6, u16tab[6]); eeprom_write(priv, 3, u16tab[3]); eeprom_reload(priv); do { for (i = 0; i < 64; i++) u16tab[i] = eeprom_read(priv, i); } while ((u16tab[0] | u16tab[1] | u16tab[2]) == 0); priv->mac_address[0] = u16tab[0]; priv->mac_address[1] = u16tab[0] >> 8; priv->mac_address[2] = u16tab[1]; priv->mac_address[3] = u16tab[1] >> 8; priv->mac_address[4] = u16tab[2]; priv->mac_address[5] = u16tab[2] >> 8; #endif #ifdef DEBUG diag_printf("MAC Addr = %02X:%02X:%02X:%02X:%02X:%02X\n", priv->mac_address[0], priv->mac_address[1], priv->mac_address[2], priv->mac_address[3], priv->mac_address[4], priv->mac_address[5]); #endif
修改ecos.db文件
打开ecos.db文件,在其中加上stm32的网卡定义组件。
# Added by reille 2013.05.10 package CYGPKG_DEVS_ETH_CORTEXM_STM32_STM32F10XXX { alias { "STM32F10XXX board with DM9000 ethernet driver" devs_eth_cortexm_stm32f10xxx stm32f10xxx_eth_driver } hardware directory devs/eth/cortexm/stm32f10xxx script stm32f10xxx_eth_driver.cdl description "Ethernet driver for STM32F10XXX card with Davicom DM9000 ethernet interface." }
在目标板上添加上CYGPKG_IO_ETH_DRIVERS软件包、DM9000驱动组件和上面定义的stm32网卡定义组件(最后3个包):
target stm32f10xxx { alias { "ST STM32F10XXX platform board" stm32f10xxx } packages { CYGPKG_HAL_CORTEXM CYGPKG_HAL_CORTEXM_STM32 CYGPKG_HAL_CORTEXM_STM32_STM32F10XXX CYGPKG_DEVS_FLASH_AMD_AM29XXXXX_V2 CYGPKG_DEVS_FLASH_STM32 CYGPKG_DEVS_FLASH_SPI_M25PXX CYGPKG_IO_SERIAL_CORTEXM_STM32 CYGPKG_DEVS_WALLCLOCK_STM32 CYGPKG_IO_SPI CYGPKG_DEVS_SPI_CORTEXM_STM32 CYGPKG_IO_ADC CYGPKG_DEVS_ADC_CORTEXM_STM32 CYGPKG_IO_USB CYGPKG_IO_USB_SLAVE CYGPKG_DEVS_USB_CORTEXM_STM32 CYGPKG_IO_FLASH CYGPKG_IO_FRAMEBUF CYGPKG_DEVS_FRAMEBUF_STM32 CYGPKG_DEVS_TOUCH_SPI_TSC2046 CYGPKG_DEVS_TOUCH_CORTEXM_STM32F10XXX CYGPKG_IO_ETH_DRIVERS CYGPKG_DEVS_ETH_CORTEXM_STM32_STM32F10XXX CYGPKG_DEVS_ETH_DAVICOM_DM9000 } description "The stm32f10xxx target provides the packages needed to run eCos on the STM32F10XXX platform board." }
通过这样的操作后,在图形配置工具中就可以看到DM9000驱动和stm32网卡的配置了。
下节将说明如何在redboot中实现网络。
推荐阅读相关文章:
- stm32移植ecos #23,ecos ethernet driver,DM9000A驱动移植(中)
- stm32移植ecos #24,ecos ethernet driver,DM9000A驱动移植(下)
- stm32移植ecos #34,ecos sd driver,SD卡驱动(4)
- stm32移植ecos #33,ecos sd driver,SD卡驱动(3)
- stm32移植ecos #31,ecos sd driver,SD卡驱动(1)
- stm32移植ecos #30,ecos i2s driver,音频驱动(下)
- stm32移植ecos #29,ecos i2s driver,音频驱动(中)
- stm32移植ecos #28,ecos i2s driver,音频驱动(上)
如你所说,我换了IE流览器就好了,原来之前不能发贴是我换用搜狗流览器造成的
我自己用搜狗测试了下,在这我里也可以用(高速模式和兼容模式),我的版本是:4.1.1.7536。有一段时间用搜狗,但觉得还是没google的好用,所以又切换回google浏览器,呵呵
兄弟,你的论坛出问题了,不能发贴了,这有一个星期了,我登录,返回继续操作,就再叫我登录,反复登录,就是不能发贴子。
奇怪,我自己试可以哦。你可不可以换个浏览器试下或者清除下缓存,如果还有问题,得分析下了!谢谢你的反馈!