|
软件环境:Win7,Keil MDK 4.72a, IAR EWARM 7.2, GCC 4.2,Python 2.7 ,SCons 2.3.2
硬件环境:Armfly STM32F103ZE-EK v3.0开发板
参考文章:RT-Thread编程指南
RT-Thread_1.2.0+lwip+rtgui0.8.0 移植心得
【1】修改配置文件rtconfig.h
定位到112行,开启LWIP编译选项并加入RT_USING_LWIP141,我们要使用的LwIP版本是v1.4.1修改如下:
/* SECTION: lwip, a lighwight TCP/IP protocol stack */ #define RT_USING_LWIP
#define RT_USING_LWIP141 ... ... /* the number of simulatenously active TCP connections*/ #define RT_LWIP_TCP_PCB_NUM 5 /* Using DHCP */ /* #define RT_LWIP_DHCP */ /* ip address of target*/ #define RT_LWIP_IPADDR0 192 #define RT_LWIP_IPADDR1 168 #define RT_LWIP_IPADDR2 1 #define RT_LWIP_IPADDR3 133 /* gateway address of target*/ #define RT_LWIP_GWADDR0 192 #define RT_LWIP_GWADDR1 168 #define RT_LWIP_GWADDR2 1 #define RT_LWIP_GWADDR3 1 ... ...
开发板网卡地址,网关地址,开发主机地址在一个网段内即可。
【2】注释掉drivers组的rt_spi_device.c文件不使用的头文件
将drivers目录下dma9000.c文件加入工程的drivers组中,然后打开drivers组的rt_spi_device.c文件,定位到第5行,将#include "stm32_eth.h"注释掉,修改如下:
#ifdef RT_USING_LWIP
//#include "stm32_eth.h"
#endif /* RT_USING_LWIP */
修改完成后保存,并在命令行中使用scons命令编译,应能够编译通过。
【3】修改DM9000A芯片和MCU之间硬件接口
(1) FSMC配置
开发板原理图DM9000A硬件接口电路如下图:

STM32F103参考手册2009年12月中文版第327页给出如下说明:

DM9000地址计算方法:
A,正如上图所示,对于16位宽度的外部存储器,stm32f103的FSMC将在内部使用HADDR[25:1]产生外部存储器的地址FSMC_A[24:0],而HADDR[0]未接;
B,DM9000的CS引脚决定它的起始地址,STM32的CPU仅引出了4个片选信号,也就是CPU硬件最多只能外接4个总线型设备。安富莱开发板(V3)具有5个FSMC外设,所以开发板外扩一个地址译码器电路,如下图:
 
将NE4空间分为4部分,第1份给LCD,第2份给LAN,即当FSMC_A19=1、FSMC_NE4=0时选通DM9000。STM32的NE4的起始地址是0x6c000000,FSMC_A19对应于HADDR[20],所以安富莱开发板(V3)的DM9000的网卡起始地址为0x6c100000;
C,DM9000的基地址计算是由TXD[3:0]和SA4~9组成,安富莱开发板(V3)上这几位都为0;
D,DM9000的CMD引脚决定传送的是地址还是数据,安富莱开发板(V3)上连接的是FSMC_A[2]即HADDR[3],所以安富莱开发板(V3)的IO_ADDR = 0x6c100000,IO_DATA = 0x6c100008。
(1)打开drivers目录下的DM9000a.c,定位到646行开始,逐项检查,可原理图对照。数据线[D15:0]容易检查,关键看地址线,按下图原理图所示,

定位到680行附近,在FSMC_A16 ~ FSMC_A18定义的代码块下面,加入如FSMC_A19 ~ FSMC_A22的定义,代码如下:
/* FSMC_A16 ~ FSMC_A18 PD11 ~ PD13 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13;
GPIO_Init(GPIOD,&GPIO_InitStructure);
/* FSMC_A19 ~ FSMC_A22 PE3~PE6 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;
GPIO_Init(GPIOE,&GPIO_InitStructure);
下面的替换虽然不是必须的,但看起来规范些,
找到
FSMC_Configuration()开始的位置,
定位到633行附近,和709行附近,修改如下:
static void FSMC_Configuration() { FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure; FSMC_NORSRAMTimingInitTypeDef FSMC_NORSRAMTimingInitStructure;
... ...
/*-- FSMC Configuration ------------------------------------------------------*/ /*----------------------- SRAM Bank 4 ----------------------------------------*/ /* FSMC_Bank1_NORSRAM4 configuration */ FSMC_NORSRAMTimingInitStructure.FSMC_AddressSetupTime = 0; FSMC_NORSRAMTimingInitStructure.FSMC_AddressHoldTime = 0; FSMC_NORSRAMTimingInitStructure.FSMC_DataSetupTime = 2; FSMC_NORSRAMTimingInitStructure.FSMC_BusTurnAroundDuration = 0; FSMC_NORSRAMTimingInitStructure.FSMC_CLKDivision = 0; FSMC_NORSRAMTimingInitStructure.FSMC_DataLatency = 0; FSMC_NORSRAMTimingInitStructure.FSMC_AccessMode = FSMC_AccessMode_A;
... ...
FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &FSMC_NORSRAMTimingInitStructure; FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &FSMC_NORSRAMTimingInitStructure;
(2)中断线配置
A,原理图中给出的中断线接口是PA1,而DM9000中配置的中断线是PE4,需要改过来,我们先定位到文件的597行,GPIO_Configuration()函数开头部分,
static void GPIO_Configuration() { GPIO_InitTypeDef GPIO_InitStructure; EXTI_InitTypeDef EXTI_InitStructure; /* configure PE5 as eth RST */ //GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //GPIO_Init(GPIOE,&GPIO_InitStructure); //GPIO_SetBits(GPIOE,GPIO_Pin_5); //RST_1(); /* configure PA1 as external interrupt */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//IO内部上拉 GPIO_Init(GPIOA, &GPIO_InitStructure); /* Connect DM9000 EXTI Line to GPIOE Pin 1 */ GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource1); /* Configure DM9000 EXTI Line to generate an interrupt on falling edge */ EXTI_InitStructure.EXTI_Line = EXTI_Line1; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); /* Clear DM9000A EXTI line pending bit */ EXTI_ClearITPendingBit(EXTI_Line1); }
B,然后再定位到585行附近,配置NVIC,改成EXTI1,代码修改如下:
static void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; /* Enable the EXTI1 Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); }
【4】修改DM9000a.h文件中定义的基地址
<1>根据原理图中给出的IO地址和Data地址,打开DM9000a.h,定位到18行,修改如下: #define DM9000_IO_BASE 0x6C100000 #define DM9000_DATA_BASE 0x6C100008 #define DM9000_IO (*((volatile rt_uint16_t *) 0x6C100000)) // CMD = 0 #define DM9000_DATA (*((volatile rt_uint16_t *) 0x6C100008)) // CMD = 1
修改完后保存。
<2>打开DM9000a.c,定位到742行附近,加入条件编译,代码修改如下:
#ifdef RT_USING_LWIP int rt_hw_dm9000_init(void) {
... ...
return 0; } INIT_DEVICE_EXPORT(rt_hw_dm9000_init); #endif /* RT_USING_LWIP */
... ...
修改完成后保存。
【5】修改中断接口文件
打开drivers目录下的stm32f10x_it.c,定位到130行附近,修改如下:
#ifdef RT_USING_LWIP /******************************************************************************* * Function Name : EXTI1_IRQHandler * Description : This function handles External lines 9 to 5 interrupt request. * Input : None * Output : None * Return : None *******************************************************************************/ void EXTI1_IRQHandler(void) { extern void rt_dm9000_isr(void); /* enter interrupt */ rt_interrupt_enter(); /* Clear the DM9000A EXTI line pending bit */ EXTI_ClearITPendingBit(EXTI_Line1); rt_dm9000_isr(); /* leave interrupt */ rt_interrupt_leave(); } #endif /* RT_USING_LWIP */
修改完成后保存。
【6】编译测试
编译,下载,在终端显示如下:
\ | / - RT - Thread Operating System / | \ 1.2.2 build Apr 2 2015 2006 - 2013 Copyright by rt-thread team found part[0], begin: 219152384, size: 1.690GB dm9000 id: 0x90000a46 finsh />operating at 100M full duplex mode lwIP-1.4.1 initialized! W25Q64BV or W25Q64CV detection flash0 mount to /. sd0 mount to /dev. finsh />
然后再命令终端里ping 开发板地址 192.168.1.133,结果如下:

可以看到,已经可以正常ping通。
|