第一个测试程序中跑了个COREMARK,不尽与人意。
今天来跑个DHCP网络测试。
MCU内置ETH设备,同是开发板上配备 PHY LAN8742A-CZ-TR (U9) 及RJ45 connector (CN14),所以网络功能是妥妥的。官方连接原理图
在STM32CUBEMX上的PIN设置应该参考这个图,不要使用默认的配置,因为很多PIN都是可以复用的。
接下就是简单的配置,基本不需要修改,不过要注意,PHY的默认地址,在CUBEMX中配置为1,实际上需要修改为0。
程序基本框架如果是用CUBEMX来生成的话,基本不需要修改。只是本人测试的时候,不知道是不是路由器的原因,使用DHCP来获取IP地址的时候,基本上不能一次性获取成功,需要反复尝试几次才能获取成功。所以最佳的使用方式还是结合RTOS来多试几次,一般不超过5次为宜。
void MX_LWIP_Init(void)
{
/* Initilialize the LwIP stack with RTOS */
tcpip_init( NULL, NULL );
/* IP addresses initialization with DHCP (IPv4) */
ipaddr.addr = 0;
netmask.addr = 0;
gw.addr = 0;
/* add the network interface (IPv4/IPv6) with RTOS */
netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, &tcpip_input);
/* Registers the default network interface */
netif_set_default(&gnetif);
if (netif_is_link_up(&gnetif))
{
/* When the netif is fully configured this function must be called */
netif_set_up(&gnetif);
}
else
{
/* When the netif link is down this function must be called */
netif_set_down(&gnetif);
}
/* Start DHCP negotiation for a network interface (IPv4) */
dhcp_start(&gnetif);
/* USER CODE BEGIN 3 */
/* USER CODE END 3 */
}
/* USER CODE BEGIN 4 */
这里是从初始化ETH硬件到获取DHCP地址的完整代码,只是如果仅仅是这样的话,很难一次性获取代码成功。参考官方例程中,也是使用了一个专门的任务来获取IP地址,所以没办法,还是结合RTOS一起来使用吧。再者LWIP如果要使用高级API如NETCONN及SOCKET来使用网络的话,由于这些API都是顺序类型的API,所以要实现非阻塞效果,也是必须要使用RTOS来支持的。
下面是获取DHCP的线程代码
/**
* [url=home.php?mod=space&uid=247401]@brief[/url] DHCP Process
* @param argument: network interface
* @retval None
*/
void StartDHCPTask(void const * argument)
{
struct netif *netif = (struct netif *) argument;
ip_addr_t ipaddr;
ip_addr_t netmask;
ip_addr_t gw;
uint32_t IPaddress;
for (;;)
{
switch (DHCP_state)
{
case DHCP_START:
{
netif->ip_addr.addr = 0;
netif->netmask.addr = 0;
netif->gw.addr = 0;
IPaddress = 0;
dhcp_start(netif);
DHCP_state = DHCP_WAIT_ADDRESS;
}
break;
case DHCP_WAIT_ADDRESS:
{
/* Read the new IP address */
IPaddress = netif->ip_addr.addr;
if (IPaddress!=0)
{
DHCP_state = DHCP_ADDRESS_ASSIGNED;
/* Stop DHCP */
dhcp_stop(netif);
}
else
{
/* DHCP timeout */
if (netif->dhcp->tries > 3)
{
DHCP_state = DHCP_TIMEOUT;
/* Stop DHCP */
dhcp_stop(netif);
/* Static address used */
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);
netif_set_addr(netif, &ipaddr , &netmask, &gw);
}
else
{
}
}
}
break;
default: break;
}
/* wait 250 ms */
osDelay(250);
}
}
这里将最大尝试次数设为5,如果DHCP获取不成功,则按指定的STATIC IP地址来设置,如果STATIC IP的指定如下
/*Static IP ADDRESS*/
#define IP_ADDR0 192
#define IP_ADDR1 168
#define IP_ADDR2 99
#define IP_ADDR3 10
/*NETMASK*/
#define NETMASK_ADDR0 255
#define NETMASK_ADDR1 255
#define NETMASK_ADDR2 255
#define NETMASK_ADDR3 0
/*Gateway Address*/
#define GW_ADDR0 192
#define GW_ADDR1 168
#define GW_ADDR2 99
#define GW_ADDR3 1
具体在使用的时候,根据连接的路由器设置不同。下面是调试的结果
DHCP尝试的次数
从这里可以看到,一次性获取IP地址成功。
另外如果要监测网络的状态变化,最好另外准备一个线程,当网络接口状态发生改变时,自行调整IP地址设备等。
下一个任务准备测试WEB SERVER,以实现RESTFULL WEB服务。
|