W5500을 이용하여 소형의 STM32-48 SSM EVM에서 TCP 루프백 전송율 테스트를 진행 해 보자.
먼저 STM32CubeIDE를 이용하여 SPI 설정을 한다.
Wiznet ioLibrary Driver 를 다운받아 Ethernet 폴더에 복사 한다.
wizet_test.c 파일에 드라이버 포팅 및 테스트 함수를 작성 하였다.
wiznet_test.c
void Net_Conf()
{
wiz_NetInfo gWIZNETINFO = {
{ 0x00, 0xdc, 0x08, 0x00, 0x00, 0x00 }, // Mac address
{ 192, 168, 1, 140 }, // IP address
{ 255, 255, 240, 0}, // Subnet mask
{ 192, 168, 1, 1}, // Gateway
{ 8, 8, 8, 0}, // DNS Server
};
ctlnetwork(CN_SET_NETINFO, (void*) &gWIZNETINFO);
}
void W5500_Init(void)
{
IINCHIP_RSToff();
Delay(400);
IINCHIP_RSTon();
/*!< Deselect the FLASH: Chip Select high */
wizchip_deselect();
// Wiznet
reg_wizchip_cs_cbfunc(wizchip_select, wizchip_deselect);
reg_wizchip_spi_cbfunc(wizchip_read, wizchip_write);
reg_wizchip_spiburst_cbfunc(SPI_ReadBuf, SPI_WriteBuf);
reg_wizchip_spiburst_cbfunc(HAL_SPI_Receive, HAL_SPI_Transmit);
/* wizchip initialize*/
uint8_t tmp;
uint8_t memsize[2][8] = { {2,2,2,2,2,2,2,2},{2,2,2,2,2,2,2,2}};
if(ctlwizchip(CW_INIT_WIZCHIP,(void*)memsize) == -1)
{
return;
}
#if 0
/* PHY link status check */
do {
if(ctlwizchip(CW_GET_PHYLINK, (void*)&tmp) == -1)
{
return;
}
} while (tmp == PHY_LINK_OFF);
#endif
Net_Conf();
}
static void wizchip_select(void)
{
IINCHIP_CSoff() ;
}
static void wizchip_deselect(void)
{
IINCHIP_CSon();
}
unsigned char SPI_WriteReadByte(unsigned char Data)
{
uint8_t receivedbyte = 0;
if(HAL_SPI_TransmitReceive(&hSPIHandle, (uint8_t*) &Data, (uint8_t*) &receivedbyte, 1, SPIx_TIMEOUT_MAX) != HAL_OK)
{
}
return receivedbyte;
}
unsigned char SPI_WriteBuf(unsigned char *pDataBuf, unsigned int Size)
{
uint8_t receivedbyte = 0;
HAL_SPI_Transmit(&hSPIHandle, pDataBuf, Size, SPIx_TIMEOUT_MAX);
return receivedbyte;
}
unsigned char SPI_ReadBuf(unsigned char *pDataBuf, unsigned int Size)
{
uint8_t receivedbyte = 0;
HAL_SPI_Receive(&hSPIHandle, pDataBuf, Size, SPIx_TIMEOUT_MAX);
return receivedbyte;
}
네트웍 전송율 테스트를 위해 PC에서는 iperf 프로그램을 사용하고 STM32에서는 W5500 TCP loopback 테스트 코를 조금 수정해 iperf 클라이언트 코드로 작성했다.
int32_t iperf_tcps(uint8_t sn, uint8_t* buf, uint16_t port)
{
int32_t ret;
uint16_t size = 0, sentsize=0;
switch(getSn_SR(sn))
{
case SOCK_ESTABLISHED :
if(getSn_IR(sn) & Sn_IR_CON)
{
setSn_IR(sn,Sn_IR_CON);
}
if((size = getSn_RX_RSR(sn)) > 0)
{
if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE;
#if _USE_DELAY
_delay(_TX_DELAY_TIME);
#endif
ret = recv(sn,buf,size);
if(ret <= 0) return ret;
#if _USE_LOOP_BACK
sentsize = 0;
while(size != sentsize)
{
ret = send(sn,buf+sentsize,size-sentsize);
if(ret < 0)
{
close(sn);
return ret;
}
sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
}
#endif
}
break;
case SOCK_CLOSE_WAIT :
if((ret=disconnect(sn)) != SOCK_OK) return ret;
break;
case SOCK_INIT :
if( (ret = listen(sn)) != SOCK_OK) return ret;
break;
case SOCK_CLOSED:
if((ret=socket(sn,Sn_MR_TCP,port,0x00)) != sn)
cnt = 0;
return ret;
break;
default:
break;
}
return 1;
}
기본 동작테스트로 2Mbps 정도로 측정이 된다.
[1] iInChip Send: 2.1609 Mbps(4737098 bytes, 16.7250 sec)
iInChip Recv: 2.1193 Mbps(4737098 bytes, 17.0530 sec)
------------------------------------------------------------
옵티마이즈 를 -Ofast로 변경하면..
3.5Mbps 정도로 측정이 된다.
STM32F103 SPI DMA 예제를 이용하여 DMA를 적용하면 Iperf로 W5500의 TCP Throughput 은 14Mbps 정도로 측정이 된다.
반응형