[ST_MICRO]/STM32H72018. 11. 29. 02:36

STM32H7 EVM 보드 개발 환경 설정 및 STM32 H7성능 테스트


STM32H7 EVM 보드 개발 환경 설정 및 STM32 H7성능 테스트



STM32CubeMX 를 이용하여 STM32H7 EVM 보드의 동작 테스트를 진행해 보았다.

우선 STM32H743 을 선택하고 기본 핀맵 세팅을 해 준다.



STM32H7의 클럭은 내부 64Mhz RC로 하고 400Mhz로 구동 할수 있도록 했다.










가장 기본이 되는 포트 제어 레지스터를 토글해 보니 80ns가 측정된다.

좀 이상하네..


  while (1)
  {
         GPIO_TEST_PORT->ODR ^= GPIO_TEST_PIN;
  }

      GPIO_TEST_PORT->ODR ^= GPIO_TEST_PIN;
 8003d76: 4a04      ldr r2, [pc, #16] ; (8003d88 <main+0x10c>)
 8003d78: 6953      ldr r3, [r2, #20]
 8003d7a: f083 0320 eor.w r3, r3, #32
 8003d7e: 6153      str r3, [r2, #20]
 8003d80: e7fa      b.n 8003d78 <main+0xfc>
 8003d82: bf00      nop




클럭을 외부클럭으로 하고 480Mhz로 구동 되도록 설정해 보았다. 그래도 58ns로 느리다.








그러면 비트제어 레지스터로 제어 해 보자


  while (1)
  {
         //GPIO_TEST_PORT->ODR ^= GPIO_TEST_PIN;
         GPIO_TEST_PORT->BSRR = GPIO_TEST_PIN;
         GPIO_TEST_PORT->BSRR = (uint32_t)GPIO_TEST_PIN << GPIO_NUMBER;
  }

       GPIO_TEST_PORT->BSRR = GPIO_TEST_PIN;
 8003df6: 4b05      ldr r3, [pc, #20] ; (8003e0c <main+0x190>)
      GPIO_TEST_PORT->BSRR = (uint32_t)GPIO_TEST_PIN << GPIO_NUMBER;
 8003df8: f44f 1100 mov.w r1, #2097152 ; 0x200000
      GPIO_TEST_PORT->BSRR = GPIO_TEST_PIN;
 8003dfc: 619c      str r4, [r3, #24]
      GPIO_TEST_PORT->BSRR = (uint32_t)GPIO_TEST_PIN << GPIO_NUMBER;
 8003dfe: 6199      str r1, [r3, #24]
 8003e00: e7fc      b.n 8003dfc <main+0x180>
 8003e02: bf00      nop


480Mhz 구동시에 25ns로 STM32F4 보다 느린 속도가 측정된다




메인 루프에서  GPIO를 On/Off 했을때 시간을 측정 해보면..

  while (1)
  {
      //GPIO_TEST_PORT->ODR ^= GPIO_TEST_PIN;
         HAL_Delay(1);
      GPIO_TEST_PORT->BSRR = GPIO_TEST_PIN;
      GPIO_TEST_PORT->BSRR = (uint32_t)GPIO_TEST_PIN << GPIO_NUMBER;
  }


역시 25ns 로 측정된다.



STM32F7 EVM 보드의 GPIO 성능테스트 결과에서 8ns와 비교하면 3~4배 정도 느리다. 왜 이럴까?
분명 클럭이 480Mhz로 2배 이상 빠른데...



D캐시  I캐시를 사용으로 설정해도 결과는 동일한다.

  /* Enable I-Cache---------------------------------------------------------*/
  SCB_EnableICache();
  /* Enable D-Cache---------------------------------------------------------*/
  SCB_EnableDCache();



데이터시트를 좀더 찾아 보자
GPIO 최대 클럭주파수를 보면 220Mhz까지 사용 가능한데...




시스템 클럭을 확인해 보면 480Mhz로 출력된다. 클럭 설정에는 문제가 없는데...

  SysClk = HAL_RCC_GetSysClockFreq();

  HClk = HAL_RCC_GetHCLKFreq();

  PClk1 = HAL_RCC_GetPCLK1Freq();

  PClk2 = HAL_RCC_GetPCLK2Freq();



  printf("SysClk (System Clock) = %lu Hz\r\n", SysClk);

  printf("HClk (AHB / Main CPU Clock) = %lu Hz\r\n", HClk);

  printf("PClk1 (Peripherals Clock 1) = %lu Hz\r\n", PClk1);

  printf("PClk2 (Peripherals Clock 2) = %lu Hz\r\n", PClk2);



Clk1=480000000

SysClk (System Clock) = 480000000 Hz

HClk (AHB / Main CPU Clock) = 240000000 Hz

PClk1 (Peripherals Clock 1) = 120000000 Hz

PClk2 (Peripherals Clock 2) = 120000000 Hz




MCO 핀으로 출력 클럭을 확인해 보면 480Mhz을 4분주한 120Mhz가 출력이 된다.
그런데 왜 GPIO 토글 속도가 느릴까? 

뭔가 설정에 문제가 있을것 같은데..
28ns면 STM32F1 GPIO 속도 테스트 결과 와 비슷하다. 너무 느리다.


무엇이 문제 일까?



[최종 결론] STM32H7 vs STM32F7 GPIO 속도 테스트2 - 문제 해결 참고





//HSI 64Mhz - >480Mhz
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
  /** Supply configuration update enable
  */
  HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
  /** Configure the main internal regulator output voltage
  */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
  /** Initializes the CPU, AHB and APB busses clocks
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_DIV1;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = 4;
  RCC_OscInitStruct.PLL.PLLN = 60;
  RCC_OscInitStruct.PLL.PLLP = 2;
  RCC_OscInitStruct.PLL.PLLQ = 2;
  RCC_OscInitStruct.PLL.PLLR = 2;
  RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;
  RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
  RCC_OscInitStruct.PLL.PLLFRACN = 0;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB busses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
                              |RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
  RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
  PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USART1;
  PeriphClkInitStruct.Usart16ClockSelection = RCC_USART16CLKSOURCE_D2PCLK2;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_PLL1QCLK, RCC_MCODIV_8);
}








//HSE 25Mhz -> 400Mhz
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
  /** Supply configuration update enable
  */
  HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
  /** Configure the main internal regulator output voltage
  */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
  /** Initializes the CPU, AHB and APB busses clocks
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 5;
  RCC_OscInitStruct.PLL.PLLN = 160; //192 -> 480Mhz
  RCC_OscInitStruct.PLL.PLLP = 2;
  RCC_OscInitStruct.PLL.PLLQ = 2;
  RCC_OscInitStruct.PLL.PLLR = 2;
  RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2;
  RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
  RCC_OscInitStruct.PLL.PLLFRACN = 0;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB busses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
                              |RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
  RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
  PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_HRTIM1|RCC_PERIPHCLK_USART1;
  PeriphClkInitStruct.Usart16ClockSelection = RCC_USART16CLKSOURCE_D2PCLK2;
  PeriphClkInitStruct.Hrtim1ClockSelection = RCC_HRTIM1CLK_TIMCLK;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_PLL1QCLK, RCC_MCODIV_4);
}






Posted by nexp

댓글을 달아 주세요

[ST_MICRO]/STM32G2018. 11. 14. 03:27

#STM32G STM32CubeIDE 를 이용한 개발환경 설정 및 성능 테스트

#STM32G STM32CubeIDE 를 이용한 개발환경 설정 및 성능 테스트






[STM32G031-SSM] 보드를 이용하여 개발 환경 설정 및 STM32G0의 성능 테스트를 해 보았다.


처음에 STM32CubeMx를 이용하여 코드를 생성하려고 진행 했는데.. 설정 다 하고 코드 생성하려는 순간 STM32G  시리즈는 CubeMx에서 지원을 하지 않는다고 한다.


알아보니 STM32CubeIDE를 이용하라고 한다.




STM32CubeIDE로 STM32G시리즈 선택해서 새로운 프로젝트를 생성











핀맵 설정

CubeMx와 거의 동일하게 동작하는것 같다.






STM32CubeIDE 클럭 설정

최대 64Mhz까지 설정 가능하다.






기본 설정 완료후 STM32CubeIDE에서 저장 하면 기본 코드가 생성된다.





[STM32G031-SSM] 보드에는 PA5에 LED가 연결되어 있으므로 GPIO토글 속도 측정을 해 보자





  while (1)
  {
    /* USER CODE END WHILE */
        GPIOA->BSRR = GPIO_PIN_5;
        GPIOA->BRR = GPIO_PIN_5;
    /* USER CODE BEGIN 3 */

  }



25ns(16Mhz) 정도 출력 된다.










Delay를 주어 STM32G0의 GPIO 토글 시간만 측정해 보았다.

68ns 가 나온다.



  while (1)
  {
    /* USER CODE END WHILE */
        
        GPIOA->BSRR = GPIO_PIN_5;
        GPIOA->BRR = GPIO_PIN_5;
        HAL_Delay(1);
    /* USER CODE BEGIN 3 */
  }





이상한데... 어샘코드를 보니 HAL_Delay가 두번 들어가 있다. 컴파일러 오류 인가?

     GPIOA->BSRR = GPIO_PIN_5;
800030c:    341f          adds    r4, #31
800030e:    61ac          str    r4, [r5, #24]
     HAL_Delay(1);
8000310:    2001          movs    r0, #1
     GPIOA->BRR = GPIO_PIN_5;
8000312:    62ac          str    r4, [r5, #40]    ; 0x28
     HAL_Delay(1);
8000314:    f000 f8a8     bl    8000468 <HAL_Delay>
8000318:    e7f9          b.n    800030e <main+0x62>
800031a:    46c0          nop            ; (mov r8, r8)
800031c:    40021000     .word    0x40021000





HAL_Delay()를 앞쪽으로 해서 실행 하면 23ns가 정상 출력된다.


while (1)
  {
    /* USER CODE END WHILE */
        HAL_Delay(1);
        GPIOA->BSRR = GPIO_PIN_5;
        GPIOA->BRR = GPIO_PIN_5;
    /* USER CODE BEGIN 3 */
  }




어샘 코드도 정상이다.

800030c:    341f          adds    r4, #31
      HAL_Delay(1);
800030e:    2001          movs    r0, #1
8000310:    f000 f8aa     bl    8000468 <HAL_Delay>
     GPIOA->BSRR = GPIO_PIN_5;
8000314:    61ac          str    r4, [r5, #24]
     GPIOA->BRR = GPIO_PIN_5;
8000316:    62ac          str    r4, [r5, #40]    ; 0x28
8000318:    e7f9          b.n    800030e <main+0x62>
800031a:    46c0          nop            ; (mov r8, r8)

800031c:    40021000     .word    0x40021000




결론적으로 STM32G0 의 GPIO토글 속도는 23ns 정도 된다. 비슷한 클럭의 STM32F103 의 GPIO토글 속도와 비교해서 더 좋은것 같다. 가격도 저렴하고 성능도 나쁘지 않은것 같다.


1$대 MCU에서 크기도 작고 성능 면에서 최고 인것 같다.




혹시해서 설정을 다시 보니 SPEED가 GPIO_SPEED_FREQ_LOW로 되어 있다.

GPIO_SPEED_FREQ_VERY_HIGH로 설정하니 정상적으로 출력디 된다.


/*Configure GPIO pin : PA5 */

GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);


결국 STM32G0의 GPIO 토글 속도는 15ns(16Mhz) 로 빨라졌다. 




속도가 빨라진 것은  옵티마이즈 옵션을 -Os 로 설정한 것 때문인것 같다.










Posted by nexp

댓글을 달아 주세요

[ATMEL]/SAMD212018. 6. 28. 01:17

[SAMD21E-S EVM] ATSAMD21 MCU 성능 측정 - ATSAMD21 48Mhz 클럭 설정 문제 발생 및 해결

[SAMD21E-S EVM] ATSAMD21 MCU 성능 측정 - ATSAMD21 48Mhz 클럭 설정 문제 발생 및 해결





SAMD21은 저렴한 가격에 소형이고 적당한 성능(48Mhz Cortex-M0)에 USB까지 있어 사용할 곳이 많을것 같은 MCU이다.

실제 성능을 한번 측정 해 보자.


우선 단순하게 GPIO 토글 속도를 측정해 봐야 할것 같다.


    // Set pin direction to output
    gpio_set_pin_direction(PA14, GPIO_DIRECTION_OUT);
    gpio_set_pin_function(PA14, GPIO_PIN_FUNCTION_OFF);

    /* Replace with your application code */
    while (1)
    {
        delay_ms(1);        
        PORT->Group[0].OUTSET.reg = 0x4000;
        PORT->Group[0].OUTCLR.reg = 0x4000;
    }


Atmel START에서 생성된 기본 코드로 동작 시켰더니 500ns 가 걸린다.
기본 설정이라 그런가... 
비슷한 코어의 STM32F0 EVM 보드와 비교해 보면 너려도 너무 느리다






우선 클럭 쪽을 좀 들여다 보자.
1Mhz 로 구동되도록 되어 있다.

아래와 같이 DFLL48M으로 설정하고 동작 시켰더니 CPU가 멈춰버린다.




디버깅 해 보면 외부 32khz 클럭을 사용하고 아래 코드에서 멈추는 현상이 있다. 
32khz 클럭 소스 자체가 잘못 되었나?


#if CONF_OSC32K_CONFIG == 1
#if CONF_OSC32K_ENABLE == 1
       while (!hri_sysctrl_get_PCLKSR_OSC32KRDY_bit(hw))
              ;
#endif


내부 32khz를 사용해 보자. 잘 동작한다.



외부 클럭만으로 사용해 보자. 잘 동작 한다.



클럭은 문제 없는것 같고...
클럭이 너무 높아서 그런가?

다시 한번 DFPLL48M 을 클럭 소스로 해서 동작 시키면 




아래와 같은 에러로 빠져 버린다.

FFFFFFFE  ???         Memory out of bounds or read error








DFPLL48M 설정에 문제가 있나?

FDPLL96M 을 사용해 보자. 여전히 같은 증상이다.





클럭을 clock Precalar를 이용하여 8Mhz 이하로 낮추면 정상 동작한다.
Atmel 홈페이지에서는 자료를 아무리 찾아도 설정 관련 내용이 없었는데...




문제 발생
클럭을 8Mhz 이상으로 설정하면 MCU(SAMD21)가 멈추는 현상 발생

항상 새로운 MCU를 사용할때는 문제가 발생 하는것 같다. 이런 문제들이 발생할때 해되면 그 행복감에 또 이런 일 하는 것 아닐까...




문제 해결
48Mhz로 구동시 NVM Wait States 항목을 1로 변경해 주어야 한다.

이것때문에 한참을 고생을 했네...









문제 발생

외부 32.768khz X-tal사용하니 또 멈춰 있는 현상이 발생한다.




문제 해결
X-Tal 사용하려면 "Enable 32KHz output" and "Enable XTAL" 옵션을 체크 해 주어야 한다.

디폴트로 설정되면 좋겠구만... 왜 이렇게 어렵게 해 놓은거야..





컴파일러의 옵티마이즈 옵션에도 성능 차이가 있다.


O-1
       while (1)
       {
              delay_ms(1);         
 6c2:  4e07          ldr    r6, [pc, #28] ; (6e0 <main+0x44>)
              PORT->Group[0].OUTSET.reg = 0x4000;
 6c4:  001d          movs   r5, r3
 6c6:  2480          movs   r4, #128      ; 0x80
 6c8:  01e4          lsls   r4, r4, #7
              delay_ms(1);         
 6ca:  2001          movs   r0, #1
 6cc:  47b0          blx    r6
              PORT->Group[0].OUTSET.reg = 0x4000;
 6ce:  61ac          str    r4, [r5, #24]
              PORT->Group[0].OUTCLR.reg = 0x4000;
 6d0:  616c          str    r4, [r5, #20]
 6d2:  e7fa          b.n    6ca <main+0x2e>
 6d4:  00000115      .word  0x00000115
 6d8:  41004400      .word  0x41004400
 6dc:  40004000      .word  0x40004000
 6e0:  000002d5      .word  0x000002d5



-O3
       while (1)
       {
              delay_ms(1);         
 65c:  2001          movs   r0, #1
 65e:  47b0          blx    r6
              PORT->Group[0].OUTSET.reg = 0x4000;
 660:  61a5          str    r5, [r4, #24]
              PORT->Group[0].OUTCLR.reg = 0x4000;
 662:  6165          str    r5, [r4, #20]
 664:  e7fa          b.n    65c <main+0x28>
 666:  46c0          nop                  ; (mov r8, r8)
 668:  00000115      .word  0x00000115
 66c:  41004400      .word  0x41004400
 670:  40004000      .word  0x40004000
 674:  00000295      .word  0x00000295




ATMEL Studio 에서 옵티마이즈 옵션 설정






ATSAMD21을 48Mhz로 구동하고 최종적으로 GPIO토글 속도를 측정해 보면 86ns로 측정 된다.



       atmel_start_init();
              
       gpio_set_pin_level(LED1, true);
       /* Replace with your application code */
       while (1) 
       {
              PORT->Group[0].OUTSET.reg = (0x1<<27);
              PORT->Group[0].OUTCLR.reg = (0x1<<27);
              delay_ms(1);
       }



Posted by nexp

댓글을 달아 주세요

[ST_MICRO]/STM32F0x2017. 6. 1. 03:44

STM32F0 성능 테스트 - STM32CubeMX HAL Code


STM32F0 성능 테스트 - STM32CubeMX HAL Code




STM32F0는 Cortex-M0코어 1$이하의 저렴한 MCU로 가격에 민감한 제품에 사용하기 좋은 제품이다.

GPIO On/Off 주기를 측정해 MCU 성능 체크 해 보고 있는데 [STM32F0-SS EVM] 보드를 이용해서 테스트 해 보았다.


[참고]STM32 MCU 성능 측정 테스트



우선 최대 클럭 48Mh로 설정하고 STM32CubeMX 기본 초기화 코드 생성하고 PB1 을 토글했다. 


static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct;
  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);

  /*Configure GPIO pin : PB1 */
  GPIO_InitStruct.Pin = GPIO_PIN_1;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}




포트 토글 함수 수행 해 보면 476ns(1Mhz) 정도 측정된다. HAL_Code를 사용하면 좀 느린것 같다.

  while (1)
  {
         HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_1);
  }






함수를 사용하지 않고 레지스터를 접근해서 포트 토글 해 보면 186ns(2.6Mhz) 정도 측정이 된다.

  while (1)
  {
         GPIOB->ODR ^= GPIO_PIN_1;
  }






비트 제어 명령으로 제어 해 보면 40ns(6Mhz) 로 측정된다.
  while (1)
  {
         //HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_1);
         GPIOB->BSRR = GPIO_PIN_1;
         GPIOB->BRR = GPIO_PIN_1;
  }







좀더 보기 편하게 하기위해 Delay를 주었다.

  while (1)
  {
         //HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_1);
         GPIOB->BSRR = GPIO_PIN_1;
         GPIOB->BRR = GPIO_PIN_1;
         HAL_Delay(1);
  }



그런데 속도가 40ns에서 60ns 로 느려졌다.

왜 그렇지?
어셈 코드를 확인 해 보니 HAL_Delay() 가 두번 호출 되는듯 한데...
개발환경의 설정 문제인가?

      GPIOB->BSRR = GPIO_PIN_1;
80011f4:    2402          movs    r4, #2
80011f6:    4d04          ldr    r5, [pc, #16]    ; (8001208 <main+0xb0>)
80011f8:    61ac          str    r4, [r5, #24]
      HAL_Delay(1);
80011fa:    2001          movs    r0, #1
      GPIOB->BRR = GPIO_PIN_1;
80011fc:    62ac          str    r4, [r5, #40]    ; 0x28
      HAL_Delay(1);
80011fe:    f7ff f869     bl    80002d4 <HAL_Delay>

8001202:    e7f9          b.n    80011f8 <main+0xa0>





HAL_Delay를 위쪽에 넣으니 어셈코드도 정상적으로 나오고 속도도 40ns로 측정이 된다.

  while (1)
  {
         //HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_1);
         HAL_Delay(1);
         GPIOB->BSRR = GPIO_PIN_1;
         GPIOB->BRR = GPIO_PIN_1;
  }


      HAL_Delay(1);
80011f8:    2001          movs    r0, #1
80011fa:    f7ff f86b     bl    80002d4 <HAL_Delay>
      GPIOB->BSRR = GPIO_PIN_1;
80011fe:    61ac          str    r4, [r5, #24]
      GPIOB->BRR = GPIO_PIN_1;
8001200:    62ac          str    r4, [r5, #40]    ; 0x28

8001202:    e7f9          b.n    80011f8 <main+0xa0>






Posted by nexp

댓글을 달아 주세요

[MSP430]/MSP4322016. 5. 6. 18:06

MSP432 성능 테스트 - GPIO토글

MSP432 성능 테스트 - GPIO토글



MSP432는 Cortex-M4 코어의 최대 48Mhz로 동작하는 저전력 MCU이다. 단순 비교는 의미 없기는 하지만 간단히 GPIO토글 속도로 성능 테스트를 진행 해 보았다.



MSP432의 CPU성능 테스트를 위해 TI에서 제공하는 기본 MSP432 GPIO 토글 예제를 구동해 보았다.


MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P7, GPIO_PIN6);


GPIO토글 속도는 16khz로 측정 된다.

너무 느리다.

MSP432 클럭 설정을 좀 들여다 볼 필요가 있을것 같다.



MSP432는 10kHz ~ 48Mhz로 구동 가능하고 2개의 외부 클럭과, 5개의 내부 클럭 소스로 구성된다.



MSP432의 클럭 소스

LFXTCLK 외부 클럭 Low-frequency oscillator (LFXT)에서 32768Hz 등을 이용 가능 (32kHz 이하 주파수)

VLOCLK 내부 클럭 : 10KHz 정도의 VLO (Very low power low frequency oscillator) 시계

REFOCLK 내부 클럭 : 32k 또는 128KHz의 REFO (low-power low-frequency oscillator) 시계

DCOCLK 내부 클럭 : DCO (digitally controlled oscillator) 클럭 주파수 선택 가능

MODCLK 내부 클럭 : 24MHz의 low-power oscillator

HFXTCLK 외부 클럭 : 고속 클럭 HFXT (High-frequency oscillator) 1MHz ~ 48MHz 범위

SYSOSC 내부 클럭 : 5MHz






물론 클럭 별로 파워 선택이 필요하고 제약사항도 따른다. 최대한의 저전력 구동을 위해 이런 구조가 된것 같지만 개발자는 신경 써야 할 부분이 많아 져서 부담으로 다가올것 같다.







우선 클럭 속도를 좀더 올리기 위해 코드 수정이 필요한데

system_msp432p401r.c

파일에서 설정 가능하다.


48Mhz로 설정해서 구동해 보자.

//  CPU Frequency

//     <1500000> 1.5 MHz

//     <3000000> 3 MHz

//     <12000000> 12 MHz

//     <24000000> 24 MHz

//     <48000000> 48 MHz


//#define  __SYSTEM_CLOCK    1500000


#define  __SYSTEM_CLOCK    48000000



48Mhz 설정하고 GPIO 토글 속도를 측정해 보면

1Mhz

로 측정된다.


   127                  MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P7, GPIO_PIN6);

   \                     ??main_1: (+1)

   \   00000014   0x2140             MOVS     R1,#+64

   \   00000016   0x2007             MOVS     R0,#+7

   \   00000018   0x.... 0x....      BL       GPIO_toggleOutputOnPin

   \   0000001C   0xE7FA             B.N      ??main_1

   \   0000001E   0xBF00             Nop      

   \                     ??main_0:

   \   00000020   0x02000864         DC32     0x2000864




TI제공 함수를 이용하지 않고 레제스터 직접 제어 해 보았다.

2Mhz

로 측정된다.

다른 회사의 Cortex-M4 코어에 있는 GPIO토글 레지스터가 있으면 좋을것 같은데... 

#define OFS_LIB_PAOUT   ((uint32_t)&P1->OUT - (uint32_t)P1)

#define PORT7           ((uint32_t)P7 + OFS_LIB_PAOUT)  



       98                  HWREG16(PORT7) ^= GPIO_PIN6;


   \                     ??main_1: (+1)

   \   00000016   0x8801             LDRH     R1,[R0, #+0]

   \   00000018   0xF081 0x0140      EOR      R1,R1,#0x40

   \   0000001C   0x8001             STRH     R1,[R0, #+0]

   \   0000001E   0xE7FA             B.N      ??main_1

   \                     ??main_0:

   \   00000020   0x02000864         DC32     0x2000864

   \   00000024   0x40004C62         DC32     0x40004c62



토글 하지 않고 직접 On/Off를 반복해서 측정 해 보니 

12Mhz로 측정이 된다.


와 비교해 보면 비슷한것 같은데... 저전력 기능을 감안하면 성능면에서는 나쁘지 않은것 같다.


Posted by nexp

댓글을 달아 주세요