STM32H7을 이용한 이더넷 테스트에서 고속전송에서의 에러가 많이 발생 했는데 최근 ST에서 제공하는 라이브러리는 업데이트가 많이 된것 같다.
STM32H7-RP 보드는 STM32H7의 내장 이더넷 컨트롤러를 테스트 할수 있는 PHY커넥터가 있어 간단히 이더넷 테스트를 해 볼 수 있다.
ST에서 제공하는 STM32H7 STM32CubeMX based Ethernet examples 를 참고로해서 새로운 프로젝트를 생성하고 iperf로 TCP전송률 테스트를 진행해 보았다.
우선 STM32CubeIDE를 최신으로 업데이트 하고 프로젝트를 생성한다.
ETH를 RMII 모드로 설정하고 나머지 필요한 페리를 추가 해 준다.
STM32F7 에서 LwIP 추가했던 방식과 달리 디폴트로 활성화 되어 있지 않다. 활성화를 위해서는 RTOS를 초기화 하라고 나온다. 우선 I캐시, D캐시를 Enable 하면 LwIP 항목이 활성화 된다.
이더넷 PYH는 현제 LAN8742만 지원한다. STM32F7에서는 DP83848도 지원 했는데.. PHY 드라이버 파일을 수정해 줄 필요가 있을것 같다.
그리고 STM32F7과 또 다른점으로 이더넷 관련 GPIO 속도가 디폴트로 Low로 되어 있다. 모두 Very High로 수정해 주어야 한다.
가장 큰 차이점으로 MPU Configuration 설정을 해 주어야 한다.
마지막으로 클럭 설정을 480Mhz로 해 주면 끝
코드 생성후 디버깅을 위해 UART에서 printf가 동작 할수 있도록 코드 추가 하고 IP정보를 출력할수 있는 함수를 만들면 된다.
#define hUART huart1
extern struct netif gnetif;
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
int _write( int32_t file , uint8_t *ptr , int32_t len )
{
/* Implement your write code here, this is used by puts and printf for example */
for ( int16_t i = 0 ; i < len ; ++i )
{
HAL_UART_Transmit( &hUART, ptr++, 1, 100);
}
return len;
}
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);
}
자동 생성 코드에서 DHCP로 IP를 할당 받아 오는지 확인해 보면..
int main(void)
{
/* USER CODE BEGIN 1 */
unsigned char test_buf[1024];
int cnt = 0;
struct netif *netif;
netif = &server_netif;
/* USER CODE END 1 */
/* 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();
/* MPU Configuration--------------------------------------------------------*/
MPU_Config();
/* 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_LWIP_Init();
/* USER CODE BEGIN 2 */
printf("SysClk (System Clock) = %lu Hz..\r\n", HAL_RCC_GetSysClockFreq());
Led1Off();
while((gnetif.ip_addr.addr) == 0)
{
MX_LWIP_Process();
}
print_ip_settings(&gnetif.ip_addr.addr, &gnetif.netmask.addr, &gnetif.gw.addr);
iperf_init();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
MX_LWIP_Process();
}
}
iperf 로 TCP전송율 테스트를 해 보면 56Mbps 정도 측정된다. STM32F7의 LwIP TCP 전송율과 비교해 보면 송수신 비슷한 수준이다. 좀 더 빠를 줄 알았는데...
코드 옵티마이즈를 해서 컴파일하면 조금 더 빨라지는 것 같긴하다. 이정도가 STM32H7 내장 이더넷의 한계인것이 아닐까 싶다. F7과 차이점이라면 I캐시, D캐시를 사용하지 않아도 성능에는 그렇게 차이가 없는것 같다.