[ST_MICRO]/STM32H72018. 12. 4. 02:01

STM32H7 EVM - 이더넷 테스트 (TCP/IP전송 속도 테스트)

STM32H7 EVM - 이더넷 테스트 (TCP/IP전송 속도 테스트)




STM32H743의 경우 100핀 페키지에 이더넷을 지원하고 480Mhz로 동작 하기 때문에 작은 사이즈에 고성능 이더넷이 필요한 어플리케이션에 사용하기에 좋을것 같다.





STM32H7 EVM 보드에는 Ethernet PHY 모듈을 연결할 수 있어 STM32H7 의 Ethernet을 연결을 할 수 있다.





Ethernet PHY 모듈 핀맵





먼저 STM32CubeMx 로  Connectivity -> ETH 탭에서 RMII 모드로 설정해 준다. 




Middleware -> LWIP 탭에서 TCP/IP stack 를 설정해야 하는데... 

활성화가 안되어 있다. SYS탭에서 DCache를 Enable 해야 활성화가 된다.






DCashe 도 설정 해 주어야 한다고 한다.




이렇게 CubeMx로 Ethernet 설정을 하면 자동 생성 코드로 코드가 생성되지만 STM32F7 EVM 보드에서 테스트 한 동일한 코드가 정상 동작을 하지 않는다.


int main(void)
{
  /* USER CODE BEGIN 1 */
  /* USER CODE END 1 */
 
  /* MPU Configuration--------------------------------------------------------*/
  MPU_Config();
  /* Enable I-Cache---------------------------------------------------------*/
  SCB_EnableICache();
  /* Enable D-Cache---------------------------------------------------------*/
  //SCB_EnableDCache();
  /* MCU Configuration--------------------------------------------------------*/
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
  /* USER CODE BEGIN Init */
  /* USER CODE END Init */
  /* Configure the system clock */
  SystemClock_Config();
  /* USER CODE BEGIN SysInit */
  /* USER CODE END SysInit */
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  //MX_SDMMC1_SD_Init();
  MX_LWIP_Init();
  /* USER CODE BEGIN 2 */
  /* USER CODE END 2 */
  printf("SysClk (System Clock) = %lu Hz\r\n", HAL_RCC_GetSysClockFreq());
  while((gnetif.ip_addr.addr) == 0)
  {
         MX_LWIP_Process();
  }
  print_ip_settings(&gnetif.ip_addr.addr, &gnetif.netmask.addr, &gnetif.gw.addr);
  tcp_echoserver_init();
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
           MX_LWIP_Process();
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}





CubeMx에서 생성한 다른 코드들은 STM32F7 과 동일하게 동작하는데... 왜 이더넷 코드는 정상 동작을 하지 않을까?

ST제공 예제를 좀 찾아 보니 MCU_Config() 함수에 Ehernet 영역을 설정을 해 주어야 한다고 한다. 그리고 링크스크립트 파일도 수정이 필요 하다.


void MPU_Config(void)

{
         MPU_Region_InitTypeDef MPU_InitStruct;
         /* Disable the MPU */
         HAL_MPU_Disable();
         /* Configure the MPU attributes as Device not cacheable
            for ETH DMA descriptors */
         MPU_InitStruct.Enable = MPU_REGION_ENABLE;
         MPU_InitStruct.BaseAddress = 0x30040000;
         MPU_InitStruct.Size = MPU_REGION_SIZE_256B;
         MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
         MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
         MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
         MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
         MPU_InitStruct.Number = MPU_REGION_NUMBER0;
         MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
         MPU_InitStruct.SubRegionDisable = 0x00;
         MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
         HAL_MPU_ConfigRegion(&MPU_InitStruct);
         /* Configure the MPU attributes as Cacheable write through
            for LwIP RAM heap which contains the Tx buffers */
         MPU_InitStruct.Enable = MPU_REGION_ENABLE;
         MPU_InitStruct.BaseAddress = 0x30044000;
         MPU_InitStruct.Size = MPU_REGION_SIZE_16KB;
         MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
         MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
         MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
         MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
         MPU_InitStruct.Number = MPU_REGION_NUMBER1;
         MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
         MPU_InitStruct.SubRegionDisable = 0x00;
         MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
         HAL_MPU_ConfigRegion(&MPU_InitStruct);
         /* Enable the MPU */
         HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}




우여곡절 끝에 STM32H7에서 이더넷 동작이 정상적으로 된다. DHCP로 IP도 잘 받아오고 TCP 전송도 잘 동작한다.


하지만 고속으로 TCP 루프백 테스트를 해 보면 오류가 발생한다. 






여러가지 설정도 바꿔 보고 메모리 메모리도 키워보고 해도 동일한 현상이 반복된다.

STM32CubeIDE를 이용하면 좀 달라 질까 싶어 테스트 해 보았지만... 에러 빈도가 줄어 들긴 하지만 여전히 전송 에러가 발생하고 있다. 동일한 Ehternet PHY 모듈을 STM32F7 보드에서 구동 시키면 문제 없이 잘 동작하는것으로 보아 하드웨어는 문제 없어 보인다.


STM32F7 EVM 보드에서 TCP전송 속도 테스트 결과와 비교 해 보면 비슷한 수준이지만 에러가 자주 발생해서 이문제를 해결해야 할것 같다.



STM32H7의 향상된 CPU속도로 이더넷 성능도 좋아 졌을거라 기대를 하고 테스트 했는데... 

결론적으로는 이더넷에 문제가 있는것 같다. 좀 더 들여달 볼 필요가 있을것 같다.

Posted by nexp

댓글을 달아 주세요

[ST_MICRO]/STM32F72018. 5. 9. 04:24

[STM32F7 EVM] STM32F767 Ethernet 테스트 - TCP 전송속도 측정

[STM32F7 EVM] STM32F767 Ethernet 테스트 - TCP 전송속도 측정


STM32F7 EVM 보드에는 Ehternet을 테스트 할수 있는 Ethernet Phy 모듈 연결 커넥터가 있어 Ethernet을 연결 할 수 있다.  STM32F7의 경우 클럭속도가 216Mhz로 향상 되었기 때문에 좀더 빠른 이더넷 전송 속도가 나오지 않을까 기대 하면서 TCP 전송 속도 테스트를 해 보았다. STM32F4 Ethernet TCP 전송 속도 테스트 결과 참고




STM32F7 EVM Ethernet 하드웨어 연결 설정

STM32F7의 Ethernet 테스트는 기존에 제작 해 두었던 Ethernet Phy모듈을 이용하였다.




CubeMX 환경설정

CubeMX 를 이용하여 STM32F7 프로젝트를 생성하고 Connectivity -> ETH 탭에서  RMII 모드로 설정하면 기본 핀맵이 할당된다.





STM32F7 Ethernet 핀맵 확인




LWIP 설정

ST에서 제공하는 TCP/IP 스텍인 LWIP 를 Enable로 체크 하면 기본 설정으로 TCP/IP 통신을 할 수 있는 코드가 생성된다.






STM32F7 TCP/IP 전송 속도 테스트 코드



print_ip(char *msg, ip_addr_t *ip)

{

printf(msg);

printf("%d.%d.%d.%d\n\r", ip4_addr1(ip), ip4_addr2(ip), ip4_addr3(ip), ip4_addr4(ip));

}


print_ip_settings(ip_addr_t *ip, ip_addr_t *mask, ip_addr_t *gw)

{


print_ip("Board IP: ", ip);

print_ip("Netmask : ", mask);

print_ip("Gateway : ", gw);

}


int main(void)

{

  /* USER CODE BEGIN 1 */


  /* USER CODE END 1 */


  /* Enable D-Cache-------------------------------------------------------------*/

  SCB_EnableDCache();

  //SCB_EnableICache();

  /* MCU Configuration----------------------------------------------------------*/


  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */

  HAL_Init();


  /* USER CODE BEGIN Init */


  /* USER CODE END Init */


  /* Configure the system clock */

  SystemClock_Config();


  /* USER CODE BEGIN SysInit */


  /* USER CODE END SysInit */


  /* Initialize all configured peripherals */

  MX_GPIO_Init();

  MX_USART1_UART_Init();


  /* USER CODE BEGIN 2 */

  sprintf(buf, "STM32 ETHERNET TEST: Clk=%d\r\n", HAL_RCC_GetHCLKFreq()/1000);

  HAL_UART_Transmit(&huart1, buf, strlen(buf), 10);

  /* USER CODE END 2 */

  MX_LWIP_Init();

  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  while((gnetif.ip_addr.addr) == 0)

  {

  MX_LWIP_Process();

  }


  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);



  /* USER CODE BEGIN 2 */

  print_ip_settings(&gnetif.ip_addr.addr, &gnetif.netmask.addr, &gnetif.gw.addr);

  /* Infinite loop */

  /* USER CODE BEGIN WHILE */


  tcp_echoserver_init();


  while (1)

  {

    ethernetif_input(&gnetif);

    sys_check_timeouts();

  }

}





STM32F7 Ethernet 전송 속도 테스트 결과

STM32F7으로 TCP 루프백 테스트 결과 35Mbps 정도로 출력된다. Hardware 스텍을 가진 W5300 테스트 결과와 같은 전송 속도 이다. 소프트웨어 스텍으로도 저렴한 가격에 Ethernet 통신을 구현 할수 있어 좋은것 같다. STM32F439 + W5300 이더넷 전송 속도 테스트결과와 비교



Posted by nexp

댓글을 달아 주세요

[FPGA]/Zynq(MPSOC)2018. 4. 23. 03:54

Zynq UltraScale+ MPSoC 보드 초기화 테스트 - Giga Etherent 전송 속도 테스트

Zynq UltraScale+ MPSoC 보드 테스트 - Giga Etherent TCP 전송 속도 테스트

 

 

Zynq UltraScale+ MPSoC 보드는 ZU2EG 가 적용되어 있고 Quad-core Cortex-A53 @1.5GHz CPU로 AP를 구동한다. Giga Ethernet을 이용한 EtherCAT 사용 검토가 필요해 Giga Ethernet 통신을 테스트 해보았다.

 

우선 TCP/IP 통신 테스트를 해보자.

기본 예제로 제공되는 lwIP 스택 TCP예제로 루프백 테스트를 해보면 좋을것 같다.

 

 

기본 제공 예제를 좀 수정해서 TCP루프백 테스트 해보니 96Mbps 정도가 나온다.

예전 EtherCAT 테스트용으로 제작했던 STM32F429 보드와 TCP속도 비교를 해보면 좋을것 같다.

(너무 예전이고 코어 자체가 비교가 안되지만..)

 

 

 


Zynq UltraScale+ MPSoC TCP/IP TCP 수정코드

 

 

err_t recv_callback(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{
/* do not read the packet if we are not in ESTABLISHED state */
if (!p) {
tcp_close(tpcb);
tcp_recv(tpcb, NULL);
return ERR_OK;
}

/* indicate that the packet has been received */
tcp_recved(tpcb, p->len);

/* echo back the payload */
/* in this case, we assume that the payload is < TCP_SND_BUF */
if (tcp_sndbuf(tpcb) > p->len) {
err = tcp_write(tpcb, p->payload, p->len, 1);
} else
xil_printf("no space in tcp_sndbuf\n\r");

/* free the received pbuf */
pbuf_free(p);

return ERR_OK;
}

 

 

dhcp_start(echo_netif);
dhcp_timoutcntr = 24;

while(((echo_netif->ip_addr.addr) == 0) && (dhcp_timoutcntr > 0))
xemacif_input(echo_netif);

if (dhcp_timoutcntr <= 0) {
if ((echo_netif->ip_addr.addr) == 0) {
xil_printf("DHCP Timeout\r\n");
xil_printf("Configuring default IP of 192.168.1.10\r\n");
IP4_ADDR(&(echo_netif->ip_addr),  192, 168,   1, 10);
IP4_ADDR(&(echo_netif->netmask), 255, 255, 255,  0);
IP4_ADDR(&(echo_netif->gw),      192, 168,   1,  1);
}
} print_ip_settings(&ipaddr, &netmask, &gw);

#endif
/* start the application (web server, rxtest, txtest, etc..) */
start_application();

/* receive and process packets */
while (1) {
if (TcpFastTmrFlag) {
tcp_fasttmr();
TcpFastTmrFlag = 0;
}
if (TcpSlowTmrFlag) {
tcp_slowtmr();
TcpSlowTmrFlag = 0;
}
xemacif_input(echo_netif);
transfer_data();
}

 

 

Posted by nexp

댓글을 달아 주세요

[ST_MICRO]/STM32F43x2014. 9. 7. 22:11

STM32F429 - W5300 을 이용한 TCP/IP 전송 속도 테스트

STM32F429 - W5300 을 이용한 TCP/IP 전송 속도 테스트



STM32F429 는 최대 180Mhz로 구동된다. W5300을 이용하여 TCP/IP 전송 속도 테스트 결과 37Mbps 정도로 측정된다.





STM32F4의 FMC 타이밍을 좀더 짧게 설정하니 속도가 2.5배 이상 상승한다.

90Mbs로 거의 최대 속도가 나오는것같다.





STM32F439 W5300 FMC초기화 코드


void InitFMC_W5300(void)

{


  GPIO_InitTypeDef GPIO_Init_Structure;

  

  hsram.Instance  = FMC_NORSRAM_DEVICE;

  hsram.Extended  = FMC_NORSRAM_EXTENDED_DEVICE;

  


  SRAM_Timing.AddressSetupTime       = 2;

  SRAM_Timing.AddressHoldTime        = 2;

  SRAM_Timing.DataSetupTime          = 4;

  SRAM_Timing.BusTurnAroundDuration  = 3;

  SRAM_Timing.CLKDivision            = 2;

  SRAM_Timing.DataLatency            = 2;


/*

  SRAM_Timing.AddressSetupTime       = 10;

  SRAM_Timing.AddressHoldTime        = 10;

  SRAM_Timing.DataSetupTime          = 25;

  SRAM_Timing.BusTurnAroundDuration  = 8;

  SRAM_Timing.CLKDivision            = 2;

  SRAM_Timing.DataLatency            = 4;

*/

  SRAM_Timing.AccessMode             = FMC_ACCESS_MODE_A;

  

  hsram.Init.NSBank             = FMC_NORSRAM_BANK3;

  hsram.Init.DataAddressMux     = FMC_DATA_ADDRESS_MUX_DISABLE;

  hsram.Init.MemoryType         = FMC_MEMORY_TYPE_SRAM;

  hsram.Init.MemoryDataWidth    = SRAM_MEMORY_WIDTH;

  hsram.Init.BurstAccessMode    = FMC_BURST_ACCESS_MODE_DISABLE;

  hsram.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW;

  hsram.Init.WrapMode           = FMC_WRAP_MODE_DISABLE;

  hsram.Init.WaitSignalActive   = FMC_WAIT_TIMING_BEFORE_WS;

  hsram.Init.WriteOperation     = FMC_WRITE_OPERATION_ENABLE;

  hsram.Init.WaitSignal         = FMC_WAIT_SIGNAL_DISABLE;

  hsram.Init.ExtendedMode       = FMC_EXTENDED_MODE_DISABLE;

  hsram.Init.AsynchronousWait   = FMC_ASYNCHRONOUS_WAIT_DISABLE;

  hsram.Init.WriteBurst         = FMC_WRITE_BURST_DISABLE;

  hsram.Init.ContinuousClock    = SRAM_CONTINUOUS_CLOCK;

  

  /* Initialize the SRAM controller */

  if(HAL_SRAM_Init(&hsram, &SRAM_Timing, &SRAM_Timing) != HAL_OK)

  {

    /* Initialization Error */

    Error_Handler(); 

  }


}





STM32F429 W5300 드라이버 코드

//-----------------------------------------------------------------------------

#define W5300_BANK_ADDR                 ((uint32_t)0x64000000)

#define W5300_DATA_ADDR                 (*(uint16_t *) (W5300_BANK_ADDR))

                                        

#define _W5300_DATA(p)                    (*(__IO uint16_t*) (W5300_BANK_ADDR + (p<<1)))


#define W5300_RST_PORT GPIOA

#define W5300_RST_BIT BIT9


#define IINCHIP_RSToff() cbi(W5300_RST_PORT, W5300_RST_BIT)

#define IINCHIP_RSTon() sbi(W5300_RST_PORT, W5300_RST_BIT)



#define W5300_IO_INIT()

//-----------------------------------------------------------------------------




Posted by nexp

댓글을 달아 주세요