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 cacheablefor 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 throughfor 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속도로 이더넷 성능도 좋아 졌을거라 기대를 하고 테스트 했는데...
결론적으로는 이더넷에 문제가 있는것 같다. 좀 더 들여달 볼 필요가 있을것 같다.
최신 버전 STM32CubeIDE 에서 iperf를 이용한 STM32H7 내장 이더넷 전송률 테스트(iperf Throughput) 업데이트된 라이브러리에서는 깨지는 현상 없이 정상적으로 동작 하는것을 확인 했다.