위즈네트 아카데미

TUTORIAL

튜토리얼

Home  > 튜토리얼

W5500 W5500 Linux 드라이버

WIZnet Academy 2015.01.09 16:35 조회 수 : 75

W5500 및 위즈네트의 모든 칩셋은 TCP/IP Offload Engine, 즉 하드웨어 로직으로 구현된 TCP/IP protocol stack을 내장하고 있습니다. 따라서 임베디드 디바이스에 인터넷 기능을 추가 할때 Software Stack이나 각종 임베디드 OS를 사용해야하는 번거로움 없이 위즈네트 칩 사용만으로 펌웨어 레벨에서 이더넷 구현이 가능하다는 장점이 있습니다.
그렇다면 Linux 등 OS가 구동되고 있거나 Software Stack 을 사용중인 시스템에서는 위즈네트 칩을 사용할 수 없을까요? 그렇지 않습니다. 아래의 3가지 방법으로 위즈네트 칩을 사용하실 수 있습니다.

  • W5500의 MACRAW mode를 이용하여 W5500을 MAC/PHY Chip과 같이 사용할 수 있다. 즉 W5500내 하드웨어 TCP/IP 엔진 대신에 Software TCP/IP 를 사용하는 것입니다.

  • Software TCP/IP를 Disable 시키고 W5500 내 TCP/IP Engine로 대처해서 사용할 수 있습니다.

  • 첫번째와 두번째 경우를 함께 사용하는 Hybrid Mode로 구현이 가능합니다. 즉 W5500의 소켓 0을 MAC/RAW 모드로 하여 software engine을 통하여 통신하며, 나머지 소켓은 하드웨어 엔진을 사용할 수 있습니다. 즉 TCP/IP offload Ehgine의 강력하지만 제한적인 기능과 Software Stack의 유연성을 함께 사용할 수 있습니다.


이번 포스팅에서는 위의 첫번째 방법을 활용, W5500을 리눅스 시스템에서 사용하기 위하여 리눅스 드라이버를 포팅하고 테스트하는 방법에 대해서 설명합니다.





Development Environement


1. Preparation Material

2. Install Toolchain
arm-toolchain-3.4.3.tar.gz을 다운받은 뒤 아래의 순서대로 설치한다. 경우에 따라서는 사용자 환경에 맞게 변경하여 설치한다.

  • make directory /usr/local/arm



[sourcecode languange="plain"]
mkdir /usr/local/arm
[/sourcecode]


  • Install toochain



[sourcecode language="plain"]
# tar zxvf arm-toolchain-3.4.3.tar.gz
# cp -rf usr/ /usr/local/arm/arm-gcc-W5300
[/sourcecode]


  • Setting toochain path:



[sourcecode language="plain"]
//Add below path in **.bashrc**
export PATH=/usr/local/arm/arm-gcc-W5300/bin::$PATH
//then sourcing the bashrc file
# source .bashrc
[/sourcecode]


  • Verify: type arm and press TAB


~$ arm
arm2hpdl arm-linux-gcc arm-linux-objdump
arm-linux-addr2line arm-linux-gcc-3.4.3 arm-linux-ranlib
arm-linux-ar arm-linux-gccbug arm-linux-readelf
arm-linux-as arm-linux-gcov arm-linux-run
arm-linux-c++ arm-linux-gdb arm-linux-size
arm-linux-c++filt arm-linux-ld arm-linux-strings
arm-linux-cpp arm-linux-nm arm-linux-strip
arm-linux-g++ arm-linux-objcopy


  • Compile Linux Kernel


# tar zxvf linux-2.6.24.4-w5300e01.tar.gz
# cd linux-2.6.24.4
# cp ../w5300e01-config-v01 .config
# make wizImage
# or make ARCH=arm CROSS_COMPILE=arm-linux- wizImage -j8

 




Hardware Connections


1. W5300E01-ARM Layout 

아래는 W5300E01-ARM Board의 Layout이며, WIZ550io와의 연결을 위해 J4 Connector를 사용하였다.

linux_w5300e01-arm

2. J4 Connector

J4 Connector에는 SPI0가 연결되어 있고, 이를 WIZ550io와 연결한다.

linux_j4

WIZ550io와 J4의 커넥션 정보는 아래와 같다.









































Pin Name Pin No. Dir. WIZ550io
SPICLK0 24 –> SPI Clock
SPIMOSI0 26 –> SPI MOSI
SPIMISO0 28 <– SPI MISO
EINT10 30 RESETn
ENT1 37 –> SPI SELECT

아래는 WIZ550io 의 핀맵 정보이다.

linux_wiz550io_pinmap




Porting Guide


1. Hardware Configuration in mach-w5300e-1.c
아래 경로의 Target board 설정파일인 mach-w5300e01.c를 이용하여 W5500관련한 Hardware관련 Configuration을 한다.
linux/arch/arm/mach-s3c2410/

  • SPI pin configuration



[sourcecode language="plain"]
//static void __init w5300e01_init(void)

/* W5500 SPI pin */
s3c2410_gpio_cfgpin(S3C2410_GPF1, S3C2410_GPF1_OUTP); //SCS
s3c2410_gpio_setpin(S3C2410_GPF1, 1); //low active
s3c2410_gpio_cfgpin(S3C2410_GPE13, S3C2410_GPE13_SPICLK0); //SCLK
s3c2410_gpio_setpin(S3C2410_GPE13, 1);
s3c2410_gpio_cfgpin(S3C2410_GPE12, S3C2410_GPE12_SPIMOSI0); //MOSI
s3c2410_gpio_setpin(S3C2410_GPE12, 1);
s3c2410_gpio_cfgpin(S3C2410_GPE11, S3C2410_GPE11_SPIMISO0); //MISO
s3c2410_gpio_setpin(S3C2410_GPE11, 1);
[/sourcecode]


  • Interrupt Reauest (IRQ) pin Configaration



[sourcecode language="plain"]
//static void __init w5300e01_init(void)

/* W5500 interrupt pin */
s3c2410_gpio_cfgpin(S3C2410_GPG2, S3C2410_GPG2_EINT10); //GPG2 Interrupt
s3c2410_gpio_setpin(S3C2410_GPG2, 1); //low active
[/sourcecode]


  • Reset pin configration



[sourcecode language="plain"]
//static void __init w5300e01_init(void)

/* W5500 Reset pin */
s3c2410_gpio_cfgpin(S3C2410_GPF6, S3C2410_GPF6_OUTP);
s3c2410_gpio_setpin(S3C2410_GPF6, 1);
[/sourcecode]


  • Virtual Base address configration



[sourcecode language="plain"]
static struct map_desc w5300e01_iodesc[] __initdata = {
{ 0xf0000000, __phys_to_pfn(S3C2410_CS2), SZ_1M, MT_DEVICE },
{ 0xf8000000, __phys_to_pfn(S3C2410_CS3), SZ_1M, MT_DEVICE },
{ 0xe8000000, __phys_to_pfn(S3C2410_PA_SPI), SZ_1M, MT_DEVICE }
};
[/sourcecode]

2. Linux Driver Porting 하기
이부분은 Target MCU와 Target MCU의 SPI에 의존적인 부분으로 Target MCU와 SPI의 특성을 이해하고 설정하여야 한다.

  • Enable PCLK into SPI block



[sourcecode language="plain"]
//dev.c
void iinchip_spiclock_init(void)
{
...
reg = ioremap((unsigned long)rCLKCON, 4);
*reg |= 0x40000;
...
}
[/sourcecode]


  • Control: polling mode / SPI Clock enable / master select / CPOL =0 / CPHA =0 /etc…



[sourcecode language="plain"]
//spi.h
(*(volatile unsigned char *)(_rSPCON0) = (0x18))
[/sourcecode]


  • baudrate: PCLK / 2 / ((SPPRE0) + 1)



[sourcecode language="plain"]
//spi.h
(*(volatile unsigned char *)(_rSPPRE0) = (0x02));
[/sourcecode]


  • IRQ



[sourcecode language="plain"]
//module.c
wiz_module_init(void)
{
...
gDrvInfo.irq = IRQ_EINT10;
...
}
[/sourcecode]


  • Chip Select



[sourcecode language="plain"]
//spi.h
#define IINCHIP_CSon(Cs) (*_rGPFDAT) |= 0x2
#define IINCHIP_CSoff(Cs) (*_rGPFDAT) &= 0xfffffffd
[/sourcecode]


  • Default MAC address
    W5500에 Default MAC address를 Write하는 부분이며, kernel에서 ifconfig를 이용하여 MAC Address를 변경할 수 도 있다.



[sourcecode language="plain"]
//module.c
static unsigned char defmac[] = { 0x00, 0x08, 0xDC, 0x91, 0x97, 0x98 };

static int __init
wiz_module_init(void)
{
...
/* mac address */
memcpy(gDrvInfo.macaddr, defmac, 6);
...
}
[/sourcecode]


  • Socket buffer size 설정
    W5500에는 8개의 Socket이 존재하나, MACRAW type으로 W5500을 MAC/PHY로 사용할 것이기 때문에 Socket 0번에만 TX/RX buffer를 각각 8KBytes로 설정한다. (MACRAW mode는 Socket 0번 사용가능하다.)



[sourcecode language="plain"]
//dev.cstatic unsigned char txsize[MAX_SOCK_NUM] = {
8, 0, 0, 0, 0, 0, 0, 0
};
static unsigned char rxsize[MAX_SOCK_NUM] = {
8, 0, 0, 0, 0, 0, 0, 0
};

void iinchip_sysinit(void)
{
...
for (i = 0 ; i < MAX_SOCK_NUM; i++) {

/* Set Buffer Size */
iinchip_outb(TX_BUF_SIZE_PTR(i), txsize[i]);
iinchip_outb(RX_BUF_SIZE_PTR(i), rxsize[i]);

...
}
[/sourcecode]


  • SPI READ / WRITE Functions
    Target MCU가 변경시 아래의 #define부분 들을 수정하여 SPI Read/Write를 구현할 수 있다



[sourcecode language="plain"]
//spi.h
#define SPI0_RxData() (*(volatile unsigned char *)(_rSPRDAT0)) //(ioread8(_rSPRDAT0))

#define SPI0_TxData(Data) (*(volatile unsigned char *)(_rSPTDAT0) = (Data)) //(iowrite8(Data, _rSPTDAT0
#define SPI0_WaitForSend() while(!((*(volatile unsigned char *)(_rSPSTA0)) & 0x01)) //while(!(ioread8(_rSPSTA0) & 0x01))

#define SPI0_SendByte(Data) SPI0_TxData(Data);SPI0_WaitForSend()
#define SPI0_RecvBute() SPI0_RxData()
[/sourcecode]


  • Hardware Reset for W5500



[sourcecode language="plain"]
//dev.c
void iinchip_hwreset(void)
{
s3c2410_gpio_setpin(S3C2410_GPF6, 0);
mdelay(1);
s3c2410_gpio_setpin(S3C2410_GPF6, 1);
mdelay(2);
mdelay(3000);// WIZ550IO Need for MCU which is embedded on Board.
}
[/sourcecode]






Linux Driver 테스트하기


linux_w5300_l4

 

위의 사진은 W5300E01-ARM보드의 L4 커넥터에 WIZ550io를 연결한 모습을 보여주고 있다.

  • Serial Port는 PC와 연결되어 있으며, 이를 통해 Log를 볼 수 있으며, Zmodem를 통해 Linux dirver module인 w5500.ko를 다운받을 수 있다.

  • Bootloader시 WIZ830mj(W5300기반의 모듈, 3번이라고 쓰이진 Ethernet Port)를 통해 kernel를 다운 받을 수 있다.

  • Kernel이 구동된 이후에는 WIZ550io의 Ethernet port를 통해 packet의 송수신을 한다.


1. Kernel download on target board
W5300E01-ARM와 PC의 Serial terminal과 연결한 상태에서 보드의 전원을 인가한 뒤 3초이내에 bootloader로 진입하기 위해 serial terminal에 Enter를 입력한다. bootloader로 진입 후에는 아래의 순서대로 kernel를 target board로 다운받을 수 있다.
#tftp 31000000 wizImage //target board로 wizImage(커널이미지) 다운로드
#nand erase 40000 3c0000 //remove nand flash kernel area
#nand write 31000000 40000 2eb958 // write kernel image to nand flash kernel area
#reset //re-start
#login ID : root

2. Driver module download
Serial terminal에서 zmodem을 통해 w5500.ko를 다운받은 뒤 아래의 순으로 module을 kernel에 적재 시킬 수 있다.
#rmmod wiznet              //remove W5300 linux driver(default) module
#lsmod //verify
#insmod w5500.ko // insert w5500.ko module
#ifconfig wiz0 192.168.0.3 //setting network IP address

3. Ping Test

  • on board side
    #ping 192.168.0.223 // PC address


linux_ping_1

  • on PC side
    #ping 192.168.0.3 // Target board address


linux_ping_2

4. netloop in App
driver 코드 안에 포함되어 있는 network loopback program 사용법은 아래와 같다.

  • Compile
    #arm-linux-gcc netloop.c -o netloop



  • Download netloop by using Zmodem
    사용하는 Serial Terminal에 맞게 Zmodem을 이용하여 netloop를 Target board에 다운로드한다.



  • netloop 주요 옵션들



























Option Descriptions
-u UDP loopback mode
-t TCP loopback mode
-p Port number (Default 5001)
-b Socket buffer size (Default 2048)


  • 실행 예

    • TCP loopback: port number 5003, socket buffer size : 4096$netloop -t -p 5003 -b 4096




 

포스팅 출처 : 김수환 마스터의 Embeddist 블로그