一、环境说明:
1.硬件环境:正点原子探索者开发板
2.实验目的:实现DHCP自动获取IP地址,能够通过电脑ping通该IP地址;
3.实验过程:探索者F4资料盘(A盘) -> 4程序源码 ->3扩展例程 -> 2LWIP扩展例程 -> 网络实验1LWIP无操作系统移植,将该程序编译下载到开发板,液晶屏显示DHCP成功,并能成功通过电脑去ping通该IP地址;由于自行设计控制板没有外扩RAM,该例程并无法直接用于本人自己设计的控制板,所以想通过官方一个简单的例程进行修改以达到DHCP功能,于是选择了探索者F4 资料盘(A盘)\6,软件资料\4,LWIP学习资料\STM32F4x7_ETH_LwIP_V1.1.0\STM32F4x7_ETH_LwIP_V1.1.0\Project\Standalone\tcp_echo_client,选择该例程进行修改,代码及问题描述如下:
4.程序代码:
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
ETH_BSP_Config();
LwIP_Init();
while (1)
{
LwIP_Periodic_Handle(LocalTime);
}
}
void ETH_BSP_Config(void) { RCC_ClocksTypeDef RCC_Clocks; SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK); RCC_GetClocksFreq(&RCC_Clocks); SysTick_Config(RCC_Clocks.HCLK_Frequency/ 100); NVIC_SetPriority(SysTick_IRQn, 0); ETH_GPIO_Config(); ETH_MACDMA_Config(); if(ETH_ReadPHYRegister(LAN8720A_PHY_ADDRESS,PHY_BSR) & PHY_Linked_Status) { EthStatus|= ETH_LINK_FLAG; } } void ETH_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE); #ifdef MII_MODE /* Mode MII with STM324xx-EVAL */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA |RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC| RCC_AHB1Periph_GPIOI | RCC_AHB1Periph_GPIOG| RCC_AHB1Periph_GPIOH | RCC_AHB1Periph_GPIOF| RCC_AHB1Periph_GPIOD,ENABLE); #ifdef PHY_CLOCK_MCO GPIO_InitStructure.GPIO_Pin =GPIO_Pin_8; GPIO_InitStructure.GPIO_Speed =GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType =GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd =GPIO_PuPd_NOPULL ; GPIO_Init(GPIOA, &GPIO_InitStructure); RCC_MCO1Config(RCC_MCO1Source_HSE,RCC_MCO1Div_1); #endif /* PHY_CLOCK_MCO */ SYSCFG_ETH_MediaInterfaceConfig(SYSCFG_ETH_MediaInterface_MII); #elif defined RMII_MODE /* Mode RMII withSTM324xx-EVAL */ /* Enable GPIOs clocks */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA |RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOG| RCC_AHB1Periph_GPIOD , ENABLE); SYSCFG_ETH_MediaInterfaceConfig(SYSCFG_ETH_MediaInterface_RMII); #endif #ifdef MII_MODE /* Mode MII with STM324xx-EVAL */ /* Configure PA1, PA2 and PA7 */ GPIO_InitStructure.GPIO_Pin =GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Speed =GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType =GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd =GPIO_PuPd_NOPULL ; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOA, GPIO_PinSource1,GPIO_AF_ETH); GPIO_PinAFConfig(GPIOA, GPIO_PinSource2,GPIO_AF_ETH); GPIO_PinAFConfig(GPIOA, GPIO_PinSource7,GPIO_AF_ETH); /* Configure PB5 and PB8 */ GPIO_InitStructure.GPIO_Pin =GPIO_Pin_5 | GPIO_Pin_8; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOB, GPIO_PinSource5,GPIO_AF_ETH); GPIO_PinAFConfig(GPIOB, GPIO_PinSource8,GPIO_AF_ETH); /* Configure PC1, PC2, PC3, PC4 and PC5 */ GPIO_InitStructure.GPIO_Pin =GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5; GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOC, GPIO_PinSource1,GPIO_AF_ETH); GPIO_PinAFConfig(GPIOC, GPIO_PinSource2, GPIO_AF_ETH); GPIO_PinAFConfig(GPIOC, GPIO_PinSource3,GPIO_AF_ETH); GPIO_PinAFConfig(GPIOC, GPIO_PinSource4,GPIO_AF_ETH); GPIO_PinAFConfig(GPIOC, GPIO_PinSource5,GPIO_AF_ETH); /* Configure PG11, PG14 and PG13 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11| GPIO_Pin_13 | GPIO_Pin_14; GPIO_Init(GPIOG, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOG, GPIO_PinSource11,GPIO_AF_ETH); GPIO_PinAFConfig(GPIOG, GPIO_PinSource13,GPIO_AF_ETH); GPIO_PinAFConfig(GPIOG, GPIO_PinSource14,GPIO_AF_ETH); /* Configure PH2, PH3, PH6, PH7 */ GPIO_InitStructure.GPIO_Pin =GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_6 | GPIO_Pin_7; GPIO_Init(GPIOH, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOH, GPIO_PinSource2,GPIO_AF_ETH); GPIO_PinAFConfig(GPIOH, GPIO_PinSource3,GPIO_AF_ETH); GPIO_PinAFConfig(GPIOH, GPIO_PinSource6,GPIO_AF_ETH); GPIO_PinAFConfig(GPIOH, GPIO_PinSource7,GPIO_AF_ETH); /* Configure PI10 */ GPIO_InitStructure.GPIO_Pin =GPIO_Pin_10; GPIO_Init(GPIOI, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOI, GPIO_PinSource10,GPIO_AF_ETH); #elif defined RMII_MODE /* Mode RMII withSTM324xx-EVAL */ /* Configure PA1, PA2 and PA7 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Speed =GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType =GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd =GPIO_PuPd_NOPULL ; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOA, GPIO_PinSource1,GPIO_AF_ETH); GPIO_PinAFConfig(GPIOA, GPIO_PinSource2,GPIO_AF_ETH); GPIO_PinAFConfig(GPIOA, GPIO_PinSource7,GPIO_AF_ETH); /* Configure PC1, PC4 and PC5 */ GPIO_InitStructure.GPIO_Pin =GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5; GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOC, GPIO_PinSource1,GPIO_AF_ETH); GPIO_PinAFConfig(GPIOC, GPIO_PinSource4,GPIO_AF_ETH); GPIO_PinAFConfig(GPIOC, GPIO_PinSource5,GPIO_AF_ETH); /* Configure PG11, PG14 and PG13 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11| GPIO_Pin_13 | GPIO_Pin_14; GPIO_Init(GPIOG, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOG, GPIO_PinSource11,GPIO_AF_ETH); GPIO_PinAFConfig(GPIOG, GPIO_PinSource13,GPIO_AF_ETH); GPIO_PinAFConfig(GPIOG, GPIO_PinSource14,GPIO_AF_ETH); /* Configure PD3 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 ; GPIO_InitStructure.GPIO_Speed =GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_Mode =GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType =GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd =GPIO_PuPd_NOPULL ; GPIO_Init(GPIOD,&GPIO_InitStructure); LAN8720A_RST_PIN_RESET; Delay(50); LAN8720A_RST_PIN_SET; ETHERNET_NVICConfiguration(); #endif } static void ETH_MACDMA_Config(void) { RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_ETH_MAC | RCC_AHB1Periph_ETH_MAC_Tx | RCC_AHB1Periph_ETH_MAC_Rx, ENABLE); ETH_DeInit(); ETH_SoftwareReset(); while(ETH_GetSoftwareResetStatus() == SET); ETH_StructInit(Ð_InitStructure); /*------------------------ MAC -----------------------------------*/ ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Enable; ETH_InitStructure.ETH_LoopbackMode =ETH_LoopbackMode_Disable; ETH_InitStructure.ETH_RetryTransmission =ETH_RetryTransmission_Disable; ETH_InitStructure.ETH_AutomaticPadCRCStrip = ETH_AutomaticPadCRCStrip_Disable; ETH_InitStructure.ETH_ReceiveAll =ETH_ReceiveAll_Disable; ETH_InitStructure.ETH_BroadcastFramesReception = ETH_BroadcastFramesReception_Enable; ETH_InitStructure.ETH_PromiscuousMode =ETH_PromiscuousMode_Disable; ETH_InitStructure.ETH_MulticastFramesFilter= ETH_MulticastFramesFilter_Perfect; ETH_InitStructure.ETH_UnicastFramesFilter =ETH_UnicastFramesFilter_Perfect; #ifdef CHECKSUM_BY_HARDWARE ETH_InitStructure.ETH_ChecksumOffload = ETH_ChecksumOffload_Enable; #endif /*------------------------ DMA -----------------------------------*/ ETH_InitStructure.ETH_DropTCPIPChecksumErrorFrame =ETH_DropTCPIPChecksumErrorFrame_Enable; ETH_InitStructure.ETH_ReceiveStoreForward =ETH_ReceiveStoreForward_Enable; ETH_InitStructure.ETH_TransmitStoreForward = ETH_TransmitStoreForward_Enable; ETH_InitStructure.ETH_ForwardErrorFrames =ETH_ForwardErrorFrames_Disable; ETH_InitStructure.ETH_ForwardUndersizedGoodFrames =ETH_ForwardUndersizedGoodFrames_Disable; ETH_InitStructure.ETH_SecondFrameOperate =ETH_SecondFrameOperate_Enable; ETH_InitStructure.ETH_AddressAlignedBeats = ETH_AddressAlignedBeats_Enable; ETH_InitStructure.ETH_FixedBurst = ETH_FixedBurst_Enable; ETH_InitStructure.ETH_RxDMABurstLength =ETH_RxDMABurstLength_32Beat; ETH_InitStructure.ETH_TxDMABurstLength =ETH_TxDMABurstLength_32Beat; ETH_InitStructure.ETH_DMAArbitration =ETH_DMAArbitration_RoundRobin_RxTx_2_1; EthStatus =ETH_Init(Ð_InitStructure, LAN8720A_PHY_ADDRESS); if(EthStatus==ETH_SUCCESS) { ETH_DMAITConfig(ETH_DMA_IT_NIS|ETH_DMA_IT_R,ENABLE); } } void LwIP_Init(void) { struct ip_addr ipaddr; struct ip_addr netmask; struct ip_addr gw; #ifndef USE_DHCP uint8_t iptab[4] = {0}; uint8_t iptxt[20]; #endif mem_init(); memp_init(); #ifdef USE_DHCP ipaddr.addr = 0; netmask.addr = 0; gw.addr = 0; #else IP4_ADDR(&ipaddr, IP_ADDR0,IP_ADDR1, IP_ADDR2, IP_ADDR3); IP4_ADDR(&netmask,NETMASK_ADDR0, NETMASK_ADDR1 , NETMASK_ADDR2, NETMASK_ADDR3); IP4_ADDR(&gw, GW_ADDR0,GW_ADDR1, GW_ADDR2, GW_ADDR3); #endif netif_add(&gnetif, &ipaddr,&netmask, &gw, NULL, ðernetif_init, ðernet_input); netif_set_default(&gnetif); if (EthStatus == (ETH_INIT_FLAG |ETH_LINK_FLAG)) { gnetif.flags |=NETIF_FLAG_LINK_UP; netif_set_up(&gnetif); #ifdef USE_DHCP DHCP_state = DHCP_START; #else #endif /* USE_DHCP */ } else { netif_set_down(&gnetif); #ifdef USE_DHCP DHCP_state = DHCP_LINK_DOWN; #endif /* USE_DHCP */ } //netif_set_link_callback(&gnetif, ETH_link_callback); } 5.调试过程 a)能正常进行LAN8720A寄存器的读写操作; b)各个功能模块初始化通过,并去到主程序大循环: while (1) { LwIP_Periodic_Handle(LocalTime); } 6.调试问题 a) DHCP_state值为2,即未能完成DHCP功能; b)程序过一段时间进入汇编死循环(如下红色标记): BusFault_Handler: 0x08000188 F8DFD00C LDR.W sp,[pc,#12] ; @0x08000198 _main_scatterload: 0x0800018C F000F866 BL.W __scatterload (0x0800025C) __main_after_scatterload: 0x08000190 4800 LDR r0,[pc,#0] ; @0x08000194 0x08000192 4700 BX r0 0x08000194 32D9 DCW 0x32D9 0x08000196 0800 DCW 0x0800 __rt_final_cpp: 0x08000198 8200 DCW 0x8200 0x0800019A 2000 DCW 0x2000 192: LDR R0, =SystemInit 0x0800019C 4806 LDR r0,[pc,#24] ; @0x080001B8 193: BLX R0 0x0800019E 4780 BLX r0 194: LDR R0, =__main 0x080001A0 4806 LDR r0,[pc,#24] ; @0x080001BC 195: BX R0 196: ENDP 197: 198: ; Dummy Exception Handlers (infiniteloops which can be modified) 199: 200: NMI_Handler PROC 201: EXPORT NMI_Handler [WEAK] 0x080001A2 4700 BX r0 202: B . 203: ENDP 204: HardFault_Handler\ 205: PROC 206: EXPORT HardFault_Handler [WEAK] 0x080001A4 E7FE B NMI_Handler (0x080001A4) 207: B . 208: ENDP 209: MemManage_Handler\ 210: PROC 211: EXPORT MemManage_Handler [WEAK] 0x080001A6 E7FE B HardFault_Handler (0x080001A6) 212: B . 213: ENDP 214: BusFault_Handler\ 215: PROC 216: EXPORT BusFault_Handler [WEAK] 0x080001A8 E7FE B MemManage_Handler (0x080001A8) 217: B . 218: ENDP 219: UsageFault_Handler\ 220: PROC 221: EXPORT UsageFault_Handler [WEAK] 0x080001AA E7FE B BusFault_Handler (0x080001AA) 222: B . 223: ENDP 224: SVC_Handler PROC 225: EXPORT SVC_Handler [WEAK] 0x080001AC E7FE B UsageFault_Handler (0x080001AC) 226: B . 227: ENDP 228: DebugMon_Handler\ 229: PROC 230: EXPORT DebugMon_Handler [WEAK] 0x080001AE E7FE B SVC_Handler (0x080001AE) 231: B . 232: ENDP 233: PendSV_Handler PROC 234: EXPORT PendSV_Handler [WEAK] 0x080001B0 E7FE B DebugMon_Handler (0x080001B0) 235: B . 236: ENDP 237: SysTick_Handler PROC 238: EXPORT SysTick_Handler [WEAK] 0x080001B2 E7FE B PendSV_Handler (0x080001B2) 239: B . 0x080001B4 E7FE B SysTick_Handler (0x080001B4) 410: B . 0x080001B6 E7FE B Default_Handler (0x080001B6) 0x080001B8 1115 DCW 0x1115 0x080001BA 0800 DCW 0x0800 0x080001BC 0189 DCW 0x0189 0x080001BE 0800 DCW 0x0800 0x080001C0 EA400301 ORR r3,r0,r1 0x080001C4 079B LSLS r3,r3,#30 0x080001C6 D003 BEQ 0x080001D0 0x080001C8 E009 B 0x080001DE 0x080001CA C908 LDM r1!,{r3} 0x080001CC 1F12 SUBS r2,r2,#4 0x080001CE C008 STM r0!,{r3} 0x080001D0 2A04 CMP r2,#0x04 0x080001D2 D2FA BCS 0x080001CA 0x080001D4 E003 B 0x080001DE 0x080001D6 F8113B01 LDRB r3,[r1],#0x01 0x080001DA F8003B01 STRB r3,[r0],#0x01 0x080001DE 1E52 SUBS r2,r2,#1 0x080001E0 D2F9 BCS 0x080001D6 0x080001E2 4770 BX lr 0x080001E4 B2D2 UXTB r2,r2 0x080001E6 E001 B 0x080001EC 0x080001E8 F8002B01 STRB r2,[r0],#0x01 0x080001EC 1E49 SUBS r1,r1,#1 0x080001EE D2FB BCS 0x080001E8 0x080001F0 4770 BX lr 0x080001F2 2200 MOVS r2,#0x00 0x080001F4 E7F6 B __aeabi_memset (0x080001E4) 0x080001F6 B510 PUSH {r4,lr} 0x080001F8 4613 MOV r3,r2 0x080001FA 460A MOV r2,r1 0x080001FC 4604 MOV r4,r0 0x080001FE 4619 MOV r1,r3 0x08000200 F7FFFFF0 BL.W __aeabi_memset (0x080001E4) 0x08000204 4620 MOV r0,r4 0x08000206 BD10 POP {r4,pc} 0x08000208 1C42 ADDS r2,r0,#1 0x0800020A F8101B01 LDRB r1,[r0],#0x01 0x0800020E 2900 CMP r1,#0x00 0x08000210 D1FB BNE 0x0800020A 0x08000212 1A80 SUBS r0,r0,r2 0x08000214 4770 BX lr 0x08000216 B530 PUSH {r4-r5,lr} 0x08000218 4604 MOV r4,r0 0x0800021A 2000 MOVS r0,#0x00 0x0800021C 4603 MOV r3,r0 0x0800021E E000 B 0x08000222 0x08000220 1C5B ADDS r3,r3,#1 0x08000222 4293 CMP r3,r2 0x08000224 D203 BCS 0x0800022E 0x08000226 5CE0 LDRB r0,[r4,r3] 0x08000228 5CCD LDRB r5,[r1,r3] 0x0800022A 1B40 SUBS r0,r0,r5 0x0800022C D0F8 BEQ 0x08000220 0x0800022E BD30 POP {r4-r5,pc} 0x08000230 B530 PUSH {r4-r5,lr} 0x08000232 460B MOV r3,r1 0x08000234 4601 MOV r1,r0 0x08000236 2000 MOVS r0,#0x00 0x08000238 2220 MOVS r2,#0x20 0x0800023A 2401 MOVS r4,#0x01 0x0800023C E009 B 0x08000252 0x0800023E FA21F502 LSR r5,r1,r2 0x08000242 429D CMP r5,r3 0x08000244 D305 BCC 0x08000252 0x08000246 FA03F502 LSL r5,r3,r2 0x0800024A 1B49 SUBS r1,r1,r5 0x0800024C FA04F502 LSL r5,r4,r2 0x08000250 4428 ADD r0,r0,r5 0x08000252 1E15 SUBS r5,r2,#0 0x08000254 F1A20201 SUB r2,r2,#0x01 0x08000258 DCF1 BGT 0x0800023E 0x0800025A BD30 POP {r4-r5,pc} 0x0800025C 4C06 LDR r4,[pc,#24] ; @0x08000278 0x0800025E 4D07 LDR r5,[pc,#28] ; @0x0800027C 0x08000260 E006 B 0x08000270 0x08000262 68E0 LDR r0,[r4,#0x0C] 0x08000264 F0400301 ORR r3,r0,#0x01 0x08000268 E8940007 LDM r4,{r0-r2} 0x0800026C 4798 BLX r3 0x0800026E 3410 ADDS r4,r4,#0x10 0x08000270 42AC CMP r4,r5 0x08000272 D3F6 BCC 0x08000262 0x08000274 F7FFFF8C BL.W __main_after_scatterload (0x08000190) 0x08000278 6184 DCW 0x6184 0x0800027A 0800 DCW 0x0800 0x0800027C 61A4 DCW 0x61A4 0x0800027E 0800 DCW 0x0800 90: while (1) 0x08000280 E7FE B BusFault_Handler (0x08000280) 115: } 116: 117: /** 118: * @brief This functionhandles SysTick Handler. 119: * @param None 120: * @retval None 121: */ 122: void SysTick_Handler(void) 123: { 124: /* Update the LocalTime byadding SYSTEMTICK_PERIOD_MS each SysTick interrupt */ 125: Time_Update(); 126: } 7.问题请教 a)从死循环执行代码是否可以判别是何原因造成? b)DHCP有哪些关键的参数需要特别注意? c)第一次接触DHCP,实验数日仍未找出原因,还请大家多多指教,谢谢!(附上源程序) |