이번 포스트에서는 Linux 기반의 Eclipse에서 W7500용 프로젝트의 생성부터 바이너리 파일 작성까지의 과정을 설명한다.

사전 준비물

하드웨어 준비

소프트웨어

  • ARM GCC tool chain 설치
  • Eclipse 설치

https://javakys.wordpress.com/2016/05/18/w7500-setting-up-arm-gcc-toolchain-and-eclipse-ide-for-w7500-on-ubuntu/

  • W7500 library 설치

최신 W7500 library의 github link

https://github.com/Wiznet/W7500P

local system에 github repository의 clone을 만들기 위해서는 다음 링크를 참조하라.

http://machiine.com/2013/pulling-a-git-repo-from-github-to-your-ubuntu-server/

 

시작하기

새 프로젝트 생성

메뉴에서 File -> New -> C Project 를 선택한다.

  1. 아래와 같은 창이 나타나면 “Project name“에 원하는 프로젝트 명을 입력하고, “Project type“에서는 Executable -> Hello World ARM Cortex-M C/C++ Project를 선택한 후, “Next” 버튼을 클릭한다.

Screenshot from 2016-05-23 17-58-59

  1. 다음 화면에서와 같이 각 항목의 값을 지정한다.

Screenshot from 2016-05-23 17-59-08

  1. Vendor CMSIS name에 “W7500x“를 입력한다.

step3

  1. 아무 변경없이 “Next“를 선택한다.

step4

1. toolchain을 선택하고 toolchain의 위치를 지정한다.

step5

  1.  Finish를 선택하면 표준 ARM Cortex-M0 프로젝트가 하나 생성된다.

W7500에 맞도록 변경하기

W7500 library header files 위치 지정

다운로드한 W7500 library를 새로 생성한 프로젝트에서 참조할 수 있도록 path를 지정한다.

메뉴에서 Project -> Properties 를 선택하여 아래와 같은 창이 표시되면 C/C++ Build -> Setting -> Cross ARM C Compiler -> Includes 를 선택한다.

우측에서 “Add” icon Screenshot from 2016-05-24 14-27-42을 눌러서, W7500 library내의 CMSIS/Include, CMSIS/Device/WIZnet/W7500/Include, W7500x_StdPeriph_Driver/inc 등 3개 폴더를 차례로 추가한다.

includepath

system_W7500x.c 수정

system_W7500x.c에 “system_W7500x.h“를 include 한다.

#include “system_W7500x.h”

SystemCoreClockUpdate(), SystemInit()을 WIZwiki-W7500ECO의 Clock source에 맞게 수정하고, W7500x Libraries에서 호출하는 GetSystemClock() 함수를 추가한다.

/*—————————————————————————-
Clock Variable definitions
*—————————————————————————-*/
/* ToDo: initialize SystemCoreClock with the system core clock frequency value
achieved after system intitialization.
This means system core clock frequency after call to SystemInit()    */
uint32_t SystemFrequency = 0;  /*!< System Clock Frequency (Core Clock)       */
uint32_t SystemCoreClock = 0;  /*!< Processor Clock Frequency                  */

/*—————————————————————————-
Clock functions
*—————————————————————————-*/
void SystemCoreClockUpdate (void)            /* Get Core Clock Frequency      */
{
/* ToDo: add code to calculate the system frequency based upon the current
register settings.
This function can be used to retrieve the system core clock frequeny
after user changed register sittings.                                 */
uint8_t M, N, OD;

#ifdef SYSCLK_EXTERN_OSC
CRG->PLL_IFSR = CRG_PLL_IFSR_OCLK;
#else
CRG->PLL_IFSR = CRG_PLL_IFSR_RCLK;
#endif
OD = (1 << (CRG->PLL_FCR & 0x01)) * (1 << ((CRG->PLL_FCR & 0x02) >> 1));
N = (CRG->PLL_FCR >>  8 ) & 0x3F;
M = (CRG->PLL_FCR >> 16) & 0x3F;

#ifdef SYSCLK_EXTERN_OSC
SystemCoreClock = EXTERN_XTAL * M / N * 1 / OD;
#else
SystemCoreClock = INTERN_XTAL * M / N * 1 / OD;
#endif
}

uint32_t GetSystemClock()
{
return SystemFrequency;
}

/**
* Initialize the system
*
* @param  none
* @return none
*
* @brief  Setup the microcontroller system.
*         Initialize the System.
*/
void SystemInit (void)
{
/* ToDo: add code to initialize the system
do not use global variables because this function is called before
reaching pre-main. RW section maybe overwritten afterwards.          */
uint8_t M,N,OD;

(*((volatile uint32_t *)(W7500x_TRIM_BGT))) = (*((volatile uint32_t *)(W7500x_INFO_BGT)));
(*((volatile uint32_t *)(W7500x_TRIM_OSC))) = (*((volatile uint32_t *)(W7500x_INFO_OSC)));

// Set PLL input frequency
#ifdef SYSCLK_EXTERN_OSC
CRG->PLL_IFSR = CRG_PLL_IFSR_OCLK;
#else
CRG->PLL_IFSR = CRG_PLL_IFSR_RCLK;
#endif
OD = (1 << (CRG->PLL_FCR & 0x01)) * (1 << ((CRG->PLL_FCR & 0x02) >> 1));
N = (CRG->PLL_FCR >>  8 ) & 0x3F;
M = (CRG->PLL_FCR >> 16) & 0x3F;

#ifdef SYSCLK_EXTERN_OSC
SystemFrequency = EXTERN_XTAL * M / N * 1 / OD;
#else
SystemFrequency = INTERN_XTAL * M / N * 1 / OD;
#endif

}

중복 파일 제거하기

system/include/cmsis 폴더내에 있는 system_W7500x.hW7500x.h 는 W7500x Libraries 내에 필요한 내용을 포함해서 정의되어 있으므로 Eclipse가 자동 생성한 이 두 파일은 삭제한다.

Debug 메시지 출력 하기

본 프로젝트에서 생성한 바이너리가 target board(여기서는 WIZwiki-W7500ECO)에서 정상동작하는 지를 확인하는 가장 심플한 방법은 debug message를 출력하게 하는 것이다.

이를 위해서 W7500이 Peripheral 중 UART를 사용하는데 W7500 Peripheral을 사용하기 위해서는 W7500 library중 해당 peripheral의 .c 파일을 system/src/W7500x 에 가져오는 과정이 필요하다.

W7500x_uart.c 가져오기

Project explorer에서 Project name -> system -> src -> W7500x 를 선택한 후, mouse 오른쪽 버튼을 클릭해서 메뉴를 표시한다. 메뉴에서 “import“를 선택하면 다음과 같은 창이 나타난다.

General->File System을 선택한다.

import_step1

다운로드한 W7500 Libraries 폴더에서 W7500x_stdPeriph_Driver/src 폴더를 선택한다.

import_step2

W7500x_uart.c를 선택한다.

import_step3

trace_impl.c 수정하기

다음은 system/src/diag/trace_impl.c 파일을 다음과 같이 수정한다.

trace_impl_update

먼저, W7500x의 UART2를 debug port로 지정한다. (WIZwiki-W7500ECO 보드에서는  USB port 와 연결되어져 있다. 즉, UART2를 지정하면 USB port를 통해서 message를 확인할 수 있다.)

#include “W7500x_uart.h”

#define USING_UART2

#if defined (USING_UART0)
    #define UART_SEND_BYTE(ch)  UartPutc(UART0,ch)
    #define UART_RECV_BYTE()    UartGetc(UART0)
#elif defined (USING_UART1)
    #define UART_SEND_BYTE(ch)  UartPutc(UART1,ch)
    #define UART_RECV_BYTE()    UartGetc(UART1)
#elif defined (USING_UART2)
    #define UART_SEND_BYTE(ch)  S_UartPutc(ch)
    #define UART_RECV_BYTE()    S_UartGetc()
#endif

다음은 trace_write() 함수에 다음과 같은 코드를 추가한다.

ssize_t
trace_write (const char* buf __attribute__((unused)),
size_t nbyte __attribute__((unused)))
{
#if defined(OS_USE_TRACE_ITM)
return _trace_write_itm (buf, nbyte);
#elif defined(OS_USE_TRACE_SEMIHOSTING_STDOUT)
return _trace_write_semihosting_stdout(buf, nbyte);
#elif defined(OS_USE_TRACE_SEMIHOSTING_DEBUG)
return _trace_write_semihosting_debug(buf, nbyte);
#endif

  size_t i;
  for (i=0; i<nbyte;i++) {
    UART_SEND_BYTE(buf[i]); // call character output function
  }

return -1;
}

Timer.c 수정

SysTick_Hanlder() 내의 HAL_IncTick()은 주석처리한다.

void
SysTick_Handler (void)
{
#if defined(USE_HAL_DRIVER)
  ;//HAL_IncTick();
#endif
timer_tick ();
}

main.c 수정

System을 초기화 한 후, 1초에 한번씩 경과 시간을 “Second xx”의 형식으로 출력하는 동작을 한다.

  1. W7500x_uart.h를 추가한다.

#include “W7500x_uart.h”

  1. main 함수 내에 다음 코드를 추가한다.

    SystemInit();

/* UART2 Configuration */
S_UART_Init(115200);

// Infinite loop
while (1)
{
delay_ms(1000);

second++;

// Count seconds on the trace device.
trace_printf (“Second %d\r\n”, second);
}
// Infinite loop, never return.

  1. 시간 경과를 체크하기 위해서 다음 함수를 추가한다.

/**
* @brief  Delay Function
*/
void delay_ms(__IO uint32_t nCount)
{
volatile uint32_t delay = nCount * 2500; // approximate loops per ms at 24 MHz, Debug config
for(; delay != 0; delay–)
__NOP();
}

 

bin 파일 생성을 위한 설정 변경

디폴트로 생성되는 output file의 형식은 Intel HEX 파일이다. 그러나 WIZwiki-W7500ECO에 Mbed drag and drop으로 flashing 하기위해서는 RAW binary 파일이 필요하다. Hex2bin을 사용해서 변환할 수 도 있지만 Properties에서 설정을 바꾸어주면 자동으로 bin 파일을 만들 수 있다.

Properties 창에서 C/C++ Build -> Settins -> Cross ARM GNU Create Flash Image -> General을 선택한 후, “Output file format”에서 “Raw binary“를 선택한다.

selectRawBinary

 

Build 하기

메뉴에서 Project -> Build Project를 선택하면 해당 Project 폴더내에 Debug 폴더에 bin 파일이 생성된 것을 확인할 수 있다.

Screenshot from 2016-05-23 20-46-38

 

실행하기

먼저 Debug 메시지 출력을 확인하기 위해서 UART port를 오픈한다.

현재 내 시스템에서는 /dev/ttyACM0로 되어있다. PuTTY 창에 다음과 같이 지정하고 “Open”한다.

Screenshot from 2016-05-23 20-52-04

W7500firstproject.bin 파일을 MBED 폴더로 복사한다.

그러면, PuTTY 창에 메시지가 출력되는 것을 확인할 수 있다.

Screenshot from 2016-05-23 20-54-29

 

Source Code

https://github.com/javakys/W7500firstproject

Advertisements