ThreadX NetXDUO上电未插入网线的解决办法
在底层驱动这里先初始化PHY芯片即可,然后等待网线插入。F4和H7的ETH的HAL版驱动略有不同,但处理方法是一样的。
关键部分:
/* Initialize the DM9162 ETH PHY */
DM9162_Init(&DM9162);
PHYLinkState = DM9162_GetLinkState(&DM9162);
while(PHYLinkState <= DM9162_STATUS_LINK_DOWN)
{
PHYLinkState = DM9162_GetLinkState(&DM9162);
tx_thread_sleep(100);
}
完整:
/* 这里直接将相对变量和头文件都放在这里 */
#include "dm9162.h"
dm9162_Object_t DM9162;
TX_THREAD *netx_thread_ptr;
static UINT_nx_driver_hardware_initialize(NX_IP_DRIVER *driver_req_ptr)
{
INT PHYLinkState;
UINT duplex, speed = 0;
dm9162_IOCtx_tDM9162_IOCtx = {ETH_PHY_IO_Init,
ETH_PHY_IO_DeInit,
ETH_PHY_IO_WriteReg,
ETH_PHY_IO_ReadReg,
ETH_PHY_IO_GetTick};
NX_PACKET *packet_ptr;
UINT i;
ETH_DMADescTypeDef*DMATxDesc;
ETH_DMADescTypeDef*DMARxDesc = nx_driver_information.nx_driver_information_dma_rx_descriptors;
HAL_ETH_MspInit(NULL);
/* Default to successful return.*/
driver_req_ptr -> nx_ip_driver_status =NX_SUCCESS;
/* Setup indices.*/
nx_driver_information.nx_driver_information_receive_current_index = 0;
nx_driver_information.nx_driver_information_transmit_current_index = 0;
nx_driver_information.nx_driver_information_transmit_release_index = 0;
/* Clear the number of buffers in use counter.*/
nx_driver_information.nx_driver_information_number_of_transmit_buffers_in_use = 0;
/* Make sure there are receive packets... otherwise, return an error.*/
if (nx_driver_information.nx_driver_information_packet_pool_ptr == NULL)
{
/* There must be receive packets. If not, return an error!*/
return(NX_DRIVER_ERROR);
}
EthHandle.Instance = ETH;
EthHandle.Init.MACAddr = _nx_driver_hardware_address;
EthHandle.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;
EthHandle.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;
EthHandle.Init.RxMode = ETH_RXINTERRUPT_MODE;
EthHandle.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;
EthHandle.Init.PhyAddress = DM9162_PHY_ADDR;
/* Set PHY IO functions */
DM9162_RegisterBusIO(&DM9162, &DM9162_IOCtx);
/* Initialize the DM9162 ETH PHY */
DM9162_Init(&DM9162);
PHYLinkState = DM9162_GetLinkState(&DM9162);
while(PHYLinkState <= DM9162_STATUS_LINK_DOWN)
{
PHYLinkState = DM9162_GetLinkState(&DM9162);
tx_thread_sleep(100);
}
switch (PHYLinkState)
{
case DM9162_STATUS_100MBITS_FULLDUPLEX:
duplex = ETH_MODE_FULLDUPLEX;
speed = ETH_SPEED_100M;
break;
case DM9162_STATUS_100MBITS_HALFDUPLEX:
duplex = ETH_MODE_HALFDUPLEX;
speed = ETH_SPEED_100M;
break;
case DM9162_STATUS_10MBITS_FULLDUPLEX:
duplex = ETH_MODE_FULLDUPLEX;
speed = ETH_SPEED_10M;
break;
case DM9162_STATUS_10MBITS_HALFDUPLEX:
duplex = ETH_MODE_HALFDUPLEX;
speed = ETH_SPEED_10M;
break;
default:
duplex = ETH_MODE_FULLDUPLEX;
speed = ETH_SPEED_100M;
break;
}
EthHandle.Init.Speed = speed;
EthHandle.Init.DuplexMode = duplex;
/* Configure Ethernet peripheral (GPIOs, clocks, MAC, DMA) */
if (HAL_ETH_Init(&EthHandle) != HAL_OK)
{
/* Return error.*/
return(NX_DRIVER_ERROR);
}
/* Initialize TX Descriptors list: Ring Mode.*/
/* Fill each DMATxDesc descriptor with the right values.*/
for(i = 0; i < NX_DRIVER_TX_DESCRIPTORS; i++)
{
/* Get the pointer on the ith member of the Tx Desc list.*/
DMATxDesc = &nx_driver_information.nx_driver_information_dma_tx_descriptors;
#ifdef HARDWARE_CHECKSUM_ENABLE
/* Set Second Address Chained bit and checksum offload options.*/
DMATxDesc -> Status = ETH_DMATXDESC_TCH | ETH_DMATXDESC_IC | ETH_DMATXDESC_CIC_TCPUDPICMP_FULL | ETH_DMATXDESC_CIC_IPV4HEADER;
#else
/* Set Second Address Chained bit.*/
DMATxDesc -> Status = ETH_DMATXDESC_TCH | ETH_DMATXDESC_IC;
#endif
/* Initialize the next descriptor with the Next Descriptor Polling Enable */
if(i < (NX_DRIVER_TX_DESCRIPTORS - 1))
{
/* Set next descriptor address register with next descriptor base address */
DMATxDesc -> Buffer2NextDescAddr = (ULONG)(nx_driver_information.nx_driver_information_dma_tx_descriptors + i + 1);
}
else
{
/* For last descriptor, set next descriptor address register equal to the first descriptor base address */
DMATxDesc -> Buffer2NextDescAddr = (ULONG) nx_driver_information.nx_driver_information_dma_tx_descriptors;
}
}
/* Set Transmit Descriptor List Address Register */
ETH -> DMATDLAR = (ULONG) nx_driver_information.nx_driver_information_dma_tx_descriptors;
/* Initialize RX Descriptors list: Ring Mode*/
/* Fill each DMARxDesc descriptor with the right values */
for(i = 0; i < NX_DRIVER_RX_DESCRIPTORS; i++)
{
/* Allocate a packet for the receive buffers.*/
if (nx_packet_allocate(nx_driver_information.nx_driver_information_packet_pool_ptr, &packet_ptr,
NX_RECEIVE_PACKET, NX_NO_WAIT) == NX_SUCCESS)
{
/* Adjust the packet.*/
packet_ptr -> nx_packet_prepend_ptr += 2;
DMARxDesc.Buffer1Addr = (uint32_t) packet_ptr -> nx_packet_prepend_ptr;
DMARxDesc.ControlBufferSize = ETH_DMARXDESC_RCH | (packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_data_start);
/* Remember the receive packet poitner.*/
nx_driver_information.nx_driver_information_receive_packets =packet_ptr;
/* Set Own bit of the RX descriptor Status.*/
DMARxDesc.Status =ETH_DMARXDESC_OWN;
}
else
{
/* Cannot allocate packets from the packet pool. */
return(NX_DRIVER_ERROR);
}
/* Initialize the next descriptor with the Next Descriptor Polling Enable.*/
if(i < (NX_DRIVER_RX_DESCRIPTORS - 1))
{
/* Set next descriptor address register with next descriptor base address.*/
DMARxDesc.Buffer2NextDescAddr = (ULONG)(nx_driver_information.nx_driver_information_dma_rx_descriptors + i + 1);
}
else
{
/* For last descriptor, set next descriptor address register equal to the first descriptor base address.*/
DMARxDesc.Buffer2NextDescAddr = (uint32_t)(nx_driver_information.nx_driver_information_dma_rx_descriptors);
}
}
/* Save the size of one rx buffer.*/
nx_driver_information.nx_driver_information_rx_buffer_size = packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_data_start;
/* Clear the number of buffers in use counter.*/
nx_driver_information.nx_driver_information_multicast_count = 0;
/* Set Receive Descriptor List Address Register */
ETH -> DMARDLAR = (ULONG) nx_driver_information.nx_driver_information_dma_rx_descriptors;
/* Return success!*/
return(NX_SUCCESS);
}
如果中途吧网线拔掉 或者断电了,有什么好的解决方法 啊 ? hpdell 发表于 2021-3-24 15:07
如果中途吧网线拔掉 或者断电了,有什么好的解决方法 啊 ?
中途插拔,我准备采用我此贴的方案:
【实战经验分享】一劳永逸的解决网线随意热插拔问题
http://www.armbbs.cn/forum.php?mod=viewthread&tid=95386&fromuid=58
(出处: 硬汉嵌入式论坛)
eric2013 发表于 2021-3-24 15:21
中途插拔,我准备采用我此贴的方案:
【实战经验分享】一劳永逸的解决网线随意热插拔问题
好哇,期待大神的完整作品啊,辛苦大神了 好像NetX没发现类似的函数来notify,是不是需要自己创建任务调用LAN8742_GetLinkState(&lan8742);来获取网线插拔状态啊 jacksimcom 发表于 2021-7-20 17:25
好像NetX没发现类似的函数来notify,是不是需要自己创建任务调用LAN8742_GetLinkState(&lan8742);来获取网 ...
对,我是这么玩的。
NetX的原装玩法,我还没有研究。 用NETX DUO做网络功能,PHY 芯片是 LAN8720。现在遇到个问题,上电之后 网口的两个灯都是暗亮,插不插网线都是暗亮,连不上网络,大家有遇到过吗? 是什么原因呢? ihavedone 发表于 2021-7-23 10:17
用NETX DUO做网络功能,PHY 芯片是 LAN8720。现在遇到个问题,上电之后 网口的两个灯都是暗亮,插不插网线 ...
你的意思是用其它网络协议栈正常? ihavedone 发表于 2021-7-23 10:17
用NETX DUO做网络功能,PHY 芯片是 LAN8720。现在遇到个问题,上电之后 网口的两个灯都是暗亮,插不插网线 ...
估计硬件有问题吧 ?? 楼主,请问现在有NETXDUO的网线插拔解决方案吗?求 Jarm 发表于 2023-12-6 11:52
楼主,请问现在有NETXDUO的网线插拔解决方案吗?求
现在还没有一劳永逸的方案。
现在的机制式定期查询网线插拔状态,来对程序做处理 要重新初始化的话,必须要把所有的端口释放才可以,不知道有什么办法更便捷呢?
页:
[1]