花了两周时间(实际上就是一个周末加两三个晚上时间), 终于把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包:

image

打印信息

我是采用串口打印信息来跟踪调试的。DM9000驱动里面有两个宏:DEBUG和DEBUG_DUMP,可以打开这两个宏来跟踪调试信息,当然你也可以增加其它跟踪调试信息。

调试方法与步骤

  1. 把网卡驱动移植到eCos中并展开调试信息;
  2. 确定DM9000的访问总线(寄存器读写)没问题,一般能正确读取到DM9000的ID,就说明读写DM9000寄存器正常;
  3. 把网卡驱动移植到redboot中并展开调试信息;
  4. 在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中实现网络。

» 文章出处: reille博客—http://velep.com , 如果没有特别声明,文章均为reille博客原创作品
» 郑重声明: 原创作品未经允许不得转载,如需转载请联系reille#qq.com(#换成@)
分享到:

  4 Responses to “stm32移植ecos #22,ecos ethernet driver,DM9000A驱动移植(上)”

  1. 如你所说,我换了IE流览器就好了,原来之前不能发贴是我换用搜狗流览器造成的

    • 我自己用搜狗测试了下,在这我里也可以用(高速模式和兼容模式),我的版本是:4.1.1.7536。有一段时间用搜狗,但觉得还是没google的好用,所以又切换回google浏览器,呵呵

  2. 兄弟,你的论坛出问题了,不能发贴了,这有一个星期了,我登录,返回继续操作,就再叫我登录,反复登录,就是不能发贴子。

    • 奇怪,我自己试可以哦。你可不可以换个浏览器试下或者清除下缓存,如果还有问题,得分析下了!谢谢你的反馈!

Leave a Reply to reille Cancel reply

(必须)

(我会替您保密的)(必须)

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.

   
© 2012 velep.com | reille blog | 管理| 粤ICP备15065318号-2| 谷歌地图| 百度地图| Suffusion theme|Sayontan Sinha

无觅相关文章插件,快速提升流量