46
Hanbat National University Prof. Lee Jaeheung UART 디바이스 드라이버

UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

  • Upload
    vongoc

  • View
    257

  • Download
    0

Embed Size (px)

Citation preview

Page 1: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

UART 디바이스 드라이버

Page 2: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

목차? SA1110 Peripheral Control Module

? UART 제어 레지스터 종류

? Blocking I/O

? S5N8946 UART Device Driver

? SA1110 UART Device Driver

? UART Device Driver Program

? Test 응용 프로그램 (Host / SA1110)

Page 3: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

SA1110 Peripheral Control Module Block Diagram

DMAController

Serial Port 2ICP

Serial Port 3UART

Serial Port 4MCP / SSP

LCDController

Serial Port 0UDC

Serial Port 1GPCLK/UART

ARM System Bus

L_PCLK L_BIAS UDC+ UDC- TXD1 RXD1 TXD2 RXD2 TXD3 RXD3 TXD4 SCLK

… …

ARM Peripheral Bus

Page 4: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

SA1110 PeripheralControl Module

Peripheral

LCD Controller

Serial port 0 :

Serial port 1 :

Serial port 2 : ICP

Serial port 3 : UART

Serial port 4 :

Peripheral pin controller (PPC)

UART

HSSP

MPC

SSP

Register Width /DMA port Size

32

8

8

8

8

8

16

16

32

Base Address

0h B010 0000

0h 8000 0000

0h 8001 0000

0h 8003 0000

0h 8004 0000

0h 8005 0000

0h 8006 0000

0h 8007 0000

0h 9006 0000

Interrupt Number

12

13

15

16

17

18

19

8 0h 8002 0000

UART

GPCLK

Serial Protocol

USB

Page 5: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

UART 제어 레지스터 종류

상태 레지스터 1UART State Register 1읽기 전용UTSR10x 8001 0020

상태 레지스터 0UART State Register 0읽기/쓰기UTSR00x 8001 001C

데이터 레지스터UART Data Register읽기/쓰기UTDR0x 8001 0010

제어 레지스터 3UART Control Register 3읽기/쓰기UTCR30x 8001 000C

제어 레지스터 2UART Control Register 2읽기/쓰기UTCR20x 8001 0008

제어 레지스터 1UART Control Register 1읽기/쓰기UTCR10x 8001 0004

제어 레지스터 0UART Control Register 0읽기/쓰기UTCR00x 8001 0000

설명핀 설명접근이름레지스터 주소

Page 6: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

UART 레지스터? UTCR (UART Control Register 0)

– PE (Parity Enable) (0:패리티X / 1:패리티 비트 사용)

– OES (Odd / Even parity Select) (0:홀수 / 1:짝수)

– SBS : Stop Bit Select (0:1비트 / 1:2비트)

– DSS : Data Size Select (0:7비트 / 1:8비트)

– SCE : Sample Clock Enable (0:내부클럭 / 1:외부클럭(GPIO20))

– RCE : Receive Clock Edge Select (0:상승에지 / 1:하강에지)

– TCE : Transmit Clock Edge Select (0:상승에지 / 1:하강에지)

TCE RCE SCE DSS SBS OES PERESERVED

7 6 5 4 3 2 1 0

0 ? ? ? ? ? ? ?

Page 7: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

UART 레지스터? UTCR 1, 2 통신 속도를 설정하는 레지스터UTCR 1

UTCR 2

*내부클럭 사용시… .BaudRate = (3.6864 X 10^6) / (16 X (BRD + 1))BRD = (3.6864 X 10^6) / (16 X (BaudRate ) - 1*만약 9600baud 이면 …

BRD = (3.6864 X 10^6) / (16 X (9600 ) – 1 = 23

BRD 11 BRD 10 BRD 9 BRD 8RESERVED

7 6 5 4 3 2 1 0

BRD 6 BRD 5 BRD 4 BRD 3 BRD 2 BRD 1 BRD 0BRD 7

7 6 5 4 3 2 1 0

0 0 0 0 ? ? ? ?

0 ? ? ? ? ? ? ?

Page 8: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

UART 레지스터? UTCR (UART Control Register 3)

– RXE : Receiver Enable ( 0:수신불가 / 1:수신가능)

– TXE : Transmitter Enable ( 0:송신불가 / 1:송신가능)

– BRK : Break ( 0:정상처리 / 1:송신핀 LOW처리)

– RIE : Receive FIFO Interrupt Enable

( 0:수신 큐가 찼을 때 인터럽트X / 1:수신 큐가 찼을 때 인터럽트 발생)

– TIE : Transmit FIFO Interrupt Enable

( 0:송신 큐가 비었을 때 인터럽트X / 1:송신 큐가 비었을 때 인터럽트 발생)

– LBM : Loopback Mode ( 0:정상 처리 / 1:루프백 모드)

LBM TIE RIE BRK TXE RXERESERVED

7 6 5 4 3 2 1 0

0 0 ? ? ? ? ? ?

Page 9: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

UART 레지스터? UTDR (UART Data Register)

* ROR, FRE, PRE가 1이면 에러 발생

– ROR (Receive Over Run Error) : 수신처리가 되기 전에 다음 데이터가

수신 되었을 때 High 표시

– FRE (Framing Error) : 수신 신호 파형이 비정상일 때 High 표시

– PRE (Parity Error) : 패리티 에러 발생시 High 표시

ROR

7 6 5 4 3 2 1 0

FRE PRE 송 수신 DATA

8910

? ? ? ? ? ? ? ????

Page 10: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

UART 레지스터? UTSR0(UART State Register)

– TFS (Transmit FIFO Service Request Flag) : 송신 FIFO에 Write 가능 시 High

– RFS (Receiver FIFO Service Request Flag) : 수신 FIFO에 데이터 있을 때 High

– RID (Receiver Idle Status) : 수신 FIFO처리 데이터가 없을 때 High

– RBB (Receiver Begin of Break Status) : Break신호 검지 시 High

– REB (Receiver End of Break Status) : Break 신호 끝 검지 시 High

– EIF (Error in FIFO Flag) : 처음 수신된 4개 데이터 중 에러 시 High

EIF REB RBB RID RFS TFSRESERVED

7 6 5 4 3 2 1 0

0 0 ? ? ? ? ? ?

Page 11: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

UART 레지스터? UTSR1(UART State Register)

– TBY (Transmitter Busy Flag) : 데이터를 전송 시 High

– RNE (Receive FIFO Not Empty Flag) : 수신 FIFO가 비어 있으면 High

– TNF (Transmit FIFO Not Full Flag) : 송신 FIFO가 꽉 찼을 때 High

– PRE (Parity Error) : 패리티 에러 검출 시 High

– FRE (Framing Error) : 파형 에러 검출 시 High

– ROR (Receive Over Run Error) : 오버런 에러 검출 시 High

ROR FRE PRE TNF RNE TBYRESERVED

7 6 5 4 3 2 1 0

0 0 ? ? ? ? ? ?

Page 12: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

Blocking I/O

? Blocking, Nonblocking

- Blocking 동작

-프로세스가 read를 호출했을 때, 데이터가 아직 없으면, 프로세스는 블록

데이터가 도착하면 프로세스 활성화

-프로세스가 write를 호출했을 때, 버퍼에 여유가 없으면, 프로세스는 블록

출력버퍼에 여유공간이 생기면 프로세스 활성화

-Nonblocking

-Read / write 호출시 read / write가 불가능하면 기다리지 않고 바로

–EAGIN값을 반환

-Nonblock 모드로 열기

-open(“/dev/serial”, O_RDWR | O_NONBOCK);

Page 13: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

Blocking I/O? sleep_on / wake_up

#include <linux/sched.h>

void interruptible_sleep_on(struct wait_queue **q)

void sleep_on(struct wait_queue **q)

void wake_up_interruptible(struct wait_queue **q)

void wake_up(struct wait_queue **q)

? Waiting queue

- 프로세스를 sleep 상태로 만들 수 있는 각 사건마다 struct wait_queue*

변수를 선언

- 이 변수의 포인터를 sleep_on과 wake_up 함수에 인자로 전달

Page 14: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

Blocking I/Ostruct wait_queue *wq = NULL;

read_write_t sleepy_read(struct inode *inode, struct file *filp, char *buf,

count_t count)

{

if ( filp -> f_flags & O_NONBLOCK){

printk(KERN_DEBUG”procesor %i is nonblocking mode \n”, current -> pid_;

return –EAGAIN;

}else{

printk(KERN_DEBUG “process %i (%s) going to sleep\n”,urrent_pid, courrent -> comm);

interruptible_sleep_on(&wq);

}

return 0;

}

read_write_t sleepy_write(struct inode *inode, struct file *filp, const char *buf, count_t cout)

{

printk(KERN_DEBUG “ process %i (%s) (&commn);

wake_up_interrupt (&wq);

return count;

}

Page 15: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

UART Device Driver

processInput ring buffer

Output ring buffer

read()

write()

UART

rx_isr

tx_isr

inq

outq

sleep_on() wake_up()

wake_up()sleep_on()

rp wp

rpwp

xmit

Page 16: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

S5N8946 Device driver 초기화#define UART_BASE(BASE_ADDR+0xd000)

struct uart_regs{

u_32 ulcon; /* line control register */

u_32 ucon; /* control register */

u_32 ustat; /* status register */

u_32 utxbuf; /* transmit buffer register */

u_32 urxvuf; /* receive buffer register */

u_32 ubrdiv; /* baud rate divisor register */

u_32 brdcnt; /* baud rate count register */

u_32 brdclk; /* baud rate clock monitor */

};

Page 17: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

S5N8946 Device driver 초기화/* UART line control register */

#define UART_WL(x) ((x) & 0x3) /* 00:5bit, 01:6bit, 10:7bit, 11:8bit */

#define UART_STB (1<<2) /* stop bit, 0:one, 1:two */

#define UART_PMD(x) ((x)<<3 & 0x38) /* parity,0xx:no, 100:odd, 101:even */

#define UART_SC (1<<6) /* serial clock, 0:internal 1:external */

#define UART_IR (1<<7) /* infra-red mode */

/* UART control register */

#define UART_RxM(x) ((x) & 0x3) /*receive mode, 00:disable, 01: interrupt, 10:GDMA ch0,

11:GDMA ch1*/

#define UART_RXSI (1<<2) /* receive status interrupt enable */

#define UART_TxM(x) ((x)<<3 & 0x18) /* transmit mode, same as UART_RxM(x) */

#define UART_DSR (1<<5) /* data set ready */

#define UART_SBK (1<<6) /* send break */

#define UART_LPM (1<<7) /* look-back mode */

Page 18: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

S5N8946 Device driver 초기화

/* UART status register */

#define UART_OV (1) /* overrun error */

#define UART_PE (1<<1) /* parity error */

#define UART_FE (1<<2) /* frame error */

#define UART_BKD (1<<3) /* break interrupt */

#define UART_DTR (1<<4) /* data terminal ready */

#define UART_RDR (1<<5) /* receive data ready */

#define UART_TBE (1<<6) /* Tx buffer register empty */

#define UART_TC (1<<7) /* transmit complete */

Page 19: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

S5N8946 Device driver 초기화SERIAL_MAJOR = 150;

struct file_operations sserial_fops = {

read: sserial_read, write:sserial_write, open: sserial_open,

release : sserial_release};

int sserial_init(void)

{

int result;

result=register_chrdev(SERIAL_MAJOR , "serial",&sserial_fops);

if(result<0){

printk(“sserial:can't get major %d\n", SERIAL_MAJOR );

return result;

}

return 0;

}

Page 20: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

S5N8946 Data structure? Data structure for device

#define MAX_SIZE 48

typedef struct sserial_dev_t {

struct wait_queue *inq, *outq;

char inbuf[MAX_SIZE];

char outbuf[MAX_SIZE];

int inrp, inwp;

int outrp, outwp;

int buf_empty;

}sserial_dev_t;

sserial_dev_t sserial_dev;

Page 21: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

S5N8946 Open function ? sserial_open

– Device data structure 초기화– Device 초기화– Register interrupt service routines

int sserial_open(struct inode *inode, struct file *filp)

{

sserial_dev_t *dev;

dev = &sserial_dev;

memset(dev, 0, sizeof(serial_dev_t));

dev->buf_empty = 1; filp->private_data = dev;

s5n8946_sserial_init();

request_irq(5, sserial_rx_isr, 0, “sserial_dev_rx", NULL);

request_irq(4, sserial_tx_isr, 0, “sserial_dev_tx", NULL);

return 0;

}

Page 22: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

S5N8946 Release function? sserial_release

– Flush data in write buffer– Unregister interrupt

void sserial_release ( struct inode *inode, struct file *filp)

{

sserial_dev_t *dev;

dev = filp->private_data;

while(dev->outwp != dev->outrp) {

interruptible_sleep_on(&(dev->outq));

}

free_irq(5, NULL);

free_irq(4, NULL);

}

Page 23: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

S5N8946 Read functionint sserial_read(struct inode *inode, struct file *filp, char *buf, int count){

sserial_dev_t *dev;char *b2;int i;

dev = filp->private_data;b2 = kmalloc(count, GFP_ATOMIC);

for(i=0; i<count;) {if(dev->inwp!=dev->inrp) {

b2[i] = dev->inbuf[dev->inrp];dev->inrp = (dev->inrp+1)%MAX_SIZE;i++;}

else{interruptible_sleep_on(&(dev->inq));

}}memcpy_tofs(buf, b2, count);kfree(b2);return count;

}

Page 24: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

S5N8946 Write function(1)

int sserial_write(struct inode *inode, struct file *filp, const char *buf, int count){

volatile struct uart_regs *uart = (volatile struct uart_regs*)UART_BASE;sserial_dev_t *dev;char *b2;int i;register unsigned long flags;

if(count == 0) return 0;

dev = filp->private_data;b2 = kmalloc(count, GFP_ATOMIC);memcpy_fromfs(b2, buf, count);

Page 25: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

S5N8946 Write function(2)

for(i=0; i<count;) {if(((dev->outwp+1)%MAX_SIZE) == dev->outrp) {

sserial_tx_go(dev);interruptible_sleep_on(&(dev->outq));

}else{

dev->outbuf[dev->outwp]=b2[i];dev->outwp=(dev->outwp+1) %MAX_SIZE;i++;

}}kfree(b2);sserial_tx_go(dev);

return count;}

Page 26: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

S5N8946 sserial_tx_go functionvoid sserial_tx_go(sserial_dev_t *dev)

{

volatile struct uart_regs *uart = (volatile struct uart_regs *)UART_BASE;

register unsigned long flags;

if(dev->buf_empty) {

save_flags(flags);

cli();

dev->buf_empty = 0;

if(uart->ustat & UART_TBE) {

uart->utxbuf = dev->outbuf[dev->outrp];

dev->outrp = (dev->outrp + 1) % MAX_SIZE;

}

restore_flags(flags);

}

}

Page 27: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

S5N8946 sserial_rx_isr functionvoid sserial_rx_isr(int irq, void *data, struct pt_regs *reg)

{

volatile struct uart_regs *uart = (volatile struct uart_regs )UART_BASE;

sserial_dev_t *dev;

dev = &sserial_dev;

if(uart->ustat & UART_RDR) {

if( ((dev->inwp+1)%MAX_SIZE) == dev->inrp) {}

else {

dev->inbuf[dev->inwp] = uart->urxbuf;

dev->inwp = (dev->inwp +1) % MAX_SIZE;

}

}

wake_up_interruptible(&(dev->inq));

}

Page 28: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

S5N8946 sserial_tx_isr functionvoid sserial_tx_isr(int irq, void *data, struct pt_regs *reg){

volatile struct uart_regs *uart = (volatile struct uart_regs *)UART_BASE;sserial_dev_t *dev;register unsigned long flags;

dev = &sserial_dev;if(dev->outwp == dev->outrp) {

save_flags(flags);cli();dev->buf_empty = 1;restore_flags(flags);

}else {

if(uart->ustat & UART_TBE) {uart->utxbuf = dev->outbuf[dev->outrp];dev->outrp = (dev->outrp + 1) % MAX_SIZE;

}}wake_up_interruptible(&(dev->outq));

}

Page 29: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

Kernel에 등록

% cp sserial.c ~/linux/drivers/char/

int char_dev_init(void){

… … …#ifdef CONFIG_SSERIAL

sserial_init();#endif

… … …}

? Source file 복사

? Kernel에 등록– vi ~/linux/drivers/char/mem.c

? vi ~/linux/drivers/char/Makefile

? vi ~/linux/drivers/char/Config.inv

ifeq ($(CONFIG_SSERIAL),y)L_OBJS += sserial.o

endif

bool ‘Sserial device support’CONFIG_SSERIAL

Page 30: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

Module 형태의 등록

init_module(void){

sserial_init();}

cleanup_module(void){

sserial_release ();}

? Module의 초기 호출함수 추가

Page 31: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

SA1110 레지스터 정의? Source에서의 레지스터 정의(include/asm/arch/SA-1100.h)

#define _UTCR0(Nb) __REG(0x80010000 + ((Nb) -1)*0x00020000) /* UART Control Reg. 0 [1..3] */#define _UTCR1(Nb) __REG(0x80010004 + ((Nb) - 1)*0x00020000) /* UART Control Reg. 1 [1..3] */#define _UTCR2(Nb) __REG(0x80010008 + ((Nb) - 1)*0x00020000) /* UART Control Reg. 2 [1..3] */#define _UTCR3(Nb) __REG(0x8001000C + ((Nb) - 1)*0x00020000) /* UART Control Reg. 3 [1..3] */#define _UTCR4(Nb) __REG(0x80010010 + ((Nb) - 1)*0x00020000) /* UART Control Reg. 4 [2] */#define _UTDR(Nb) __REG(0x80010014 + ((Nb) - 1)*0x00020000) /* UART Data Reg. [1..3] */#define _UTSR0(Nb) __REG(0x8001001C + ((Nb) - 1)*0x00020000) /* UART Status Reg. 0 [1..3] */#define _UTSR1(Nb) __REG(0x80010020 + ((Nb) - 1)*0x00020000) /* UART Status Reg. 1 [1..3] */

#define Ser1UTCR0 _UTCR0 (1) /* Ser. port 1 UART Control Reg. 0 */#define Ser1UTCR1 _UTCR1 (1) /* Ser. port 1 UART Control Reg. 1 */#define Ser1UTCR2 _UTCR2 (1) /* Ser. port 1 UART Control Reg. 2 */#define Ser1UTCR3 _UTCR3 (1) /* Ser. port 1 UART Control Reg. 3 */#define Ser1UTDR _UTDR (1) /* Ser. port 1 UART Data Reg. */#define Ser1UTSR0 _UTSR0 (1) /* Ser. port 1 UART Status Reg. 0 */#define Ser1UTSR1 _UTSR1 (1) /* Ser. port 1 UART Status Reg. 1 */

#define Ser2UTCR0 _UTCR0 (2) /* Ser. port 2 UART Control Reg. 0 */#define Ser2UTCR1 _UTCR1 (2) /* Ser. port 2 UART Control Reg. 1 */#define Ser2UTCR2 _UTCR2 (2) /* Ser. port 2 UART Control Reg. 2 */#define Ser2UTCR3 _UTCR3 (2) /* Ser. port 2 UART Control Reg. 3 */#define Ser2UTCR4 _UTCR4 (2) /* Ser. port 2 UART Control Reg. 4 */#define Ser2UTDR _UTDR (2) /* Ser. port 2 UART Data Reg. */#define Ser2UTSR0 _UTSR0 (2) /* Ser. port 2 UART Status Reg. 0 */#define Ser2UTSR1 _UTSR1 (2) /* Ser. port 2 UART Status Reg. 1 */

. . .

. . .

Page 32: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

SA1110 Data Structure

struct uart_port {

u_int iobase; /* in/out[bwl] */

void *membase; /* read/write[bwl] */

u_int irq;

u_int uartclk;

u_char fifosize; /* tx fifo size */

u_char x_char;

u_char regshift ; /* reg offset shift */

u_char iotype; /* io access style */

u_char hub6;

u_char unused[7];

u_int read_status_mask;

u_int ignore_status_mask;

u_int flags;

u_int type; /* port type */

struct uart_ops *ops;

struct uart_icount icount ;

u_int line;

u_long mapbase; /* for ioremap */

};

struct uart_info {

spinlock_t lock;

struct uart_port *port;

struct uart_ops *ops;

struct uart_state *state;

struct tty_struct *tty;

struct circ_buf xmit ;

u_int flags;

u_int event;

u_int timeout;

u_int mctrl;

u_int driver_priv;

int blocked_open;

pid_t session;

pid_t pgrp;

struct tasklet_struct tlet;

wait_queue_head_t open_wait;

wait_queue_head_t close_wait;

wait_queue_head_t delta_msr_wait ;

struct uart_info *next_info;

};

Page 33: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

SA1110 Data Structure

struct uart_ops {

u_int (*tx_empty)(struct uart_port *);

void (*set_mctrl)(struct uart_port *, u_int mctrl);

u_int (*get_mctrl)(struct uart_port *);

void (*stop_tx)(struct uart_port *, u_int from_tty);

void (*start_tx)(struct uart_port *, u_int nonempty, u_int from_tty);

void (*stop_rx)(struct uart_port *);

void (*enable_ms)(struct uart_port *);

void (*break_ctl)(struct uart_port *, int ctl);

int (*startup)(struct uart_port *, struct uart_info *);

void (*shutdown)(struct uart_port *, struct uart_info *);

void (*change_speed)(struct uart_port *, u_int cflag, u_int iflag, u_intquot);

void (*pm)(struct uart_port *, u_int state, u_int oldstate);

int (*set_wake)(struct uart_port *, u_int state);

const char *(*type)(struct uart_port *);

void (*release_port)(struct uart_port *);

int (*request_port)(struct uart_port *);

void (*config_port)(struct uart_port *, int);

int (*verify_port)(struct uart_port *, struct serial_struct *);

int (*ioctl)(struct uart_port *, u_int , u_long);

};

struct uart_driver {

struct module *owner;

int normal_major;const char *normal_name;

struct tty_driver *normal_driver;

int callout_major;const char *callout_name;

struct tty_driver *callout_driver;

struct tty_struct **table;struct termios **termios;

struct termios **termios_locked;

int minor;int nr;

struct uart_state *state; /* driver should pass NULL */

struct uart_port *port; /* array of port information */struct console *cons;

};struct termios {

tcflag_t c_iflag; /* input mode flags */tcflag_t c_oflag; /* output mode flags */tcflag_t c_cflag; /* control mode flags */tcflag_t c_lflag; /* local mode flags */cc_t c_line; /* line discipline */cc_t c_cc[NCCS]; /* control characters */speed_t c_ispeed; /* input speed */speed_t c_ospeed; /* output speed */

};

Page 34: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

serial_sa1100.c

static struct uart_driver sa1100_reg = {

owner: THIS_MODULE,

normal_major: SERIAL_SA1100_MAJOR,

normal_name: "test",

callout_name:"cusa",

normal_driver: &normal,

callout_major: CALLOUT_SA1100_MAJOR,

callout_driver: &callout,

table: sa1100_table,

termios: sa1100_termios,

termios_locked: sa1100_termios_locked,

minor: MINOR_START,

nr: NR_PORTS,

port: sa1100_ports,

};

static int __init sa1100_serial_init(void){

sa1100_init_ports();return uart_register_driver(&sa1100_reg);

}

? Driver Initializationstatic struct uart_ops sa1100_pops = {

tx_empty: sa1100_tx_empty,

set_mctrl: sa1100_set_mctrl,

get_mctrl: sa1100_get_mctrl,

stop_tx: sa1100_stop_tx,

start_tx: sa1100_start_tx,

stop_rx: sa1100_stop_rx,

enable_ms: sa1100_enable_ms,

break_ctl: sa1100_break_ctl,

startup: sa1100_startup,

shutdown: sa1100_shutdown,

change_speed: sa1100_change_speed,

type: sa1100_type,

release_port: sa1100_release_port,

request_port: sa1100_request_port,

config_port: sa1100_config_port,

verify_port: sa1100_verify_port,

};

Page 35: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

serial_sa1100.c? Driver Initialization

static void sa1100_init_ports(void){

static int first = 1;

int i;

if (!first)return;

first = 0;for (i = 0; i < NR_PORTS; i++) {

sa1100_ports[i].uartclk = 3686400; sa1100_ports[i].ops = &sa1100_pops;sa1100_ports[i].fifosize = 8;

}

sa1100_register_uart(0,1); //실질적 등록

Ser1SDCR0 |= SDCR0_UART; //1번 포트를 UART로

Ser2UTCR4 = 0; //2번 포트는 사용하지 않음

Ser2HSCR0 = 0;}

void __init sa1100_register_uart_fns(struct sa1100_port_fns *fns){

if (fns->enable_ms)sa1100_pops.enable_ms = fns->enable_ms;

if (fns->get_mctrl)sa1100_pops.get_mctrl = fns->get_mctrl;

if (fns->set_mctrl)sa1100_pops.set_mctrl = fns->set_mctrl;sa1100_open = fns->open;sa1100_close = fns->close;sa1100_pops.pm = fns->pm;sa1100_pops.set_wake = fns->set_wake;

}

void __init sa1100_register_uart(int idx, int port){

if (idx >= NR_PORTS) {printk(KERN_ERR __FUNCTION__ ": bad index number %d\n",

idx);return;}

sa1100_ports[idx].membase = (void *)&Ser1UTCR0; //UART 1 사용

sa1100_ports[idx].mapbase = _Ser1UTCR0;sa1100_ports[idx].irq = IRQ_Ser1UART;sa1100_ports[idx].iotype = SERIAL_IO_MEM;sa1100_ports[idx].flags = ASYNC_BOOT_AUTOCONF;

}

Page 36: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

serial_sa1100.c

static int sa1100_verify_port(struct uart_port *port, struct serial_struct *ser){

int ret = 0;if (ser->type != PORT_UNKNOWN && ser->type != PORT_SA1100)

ret = -EINVAL;if (port->irq != ser->irq)

ret = -EINVAL;if (ser->io_type != SERIAL_IO_MEM)

ret = -EINVAL;if (port->uartclk / 16 != ser->baud_base)

ret = -EINVAL;if ((void *)port->mapbase != ser->iomem_base)

ret = -EINVAL;if (port->iobase != ser->port)

ret = -EINVAL;if (ser->hub6 != 0)

ret = -EINVAL;return ret;

}

? Port Verification function

Page 37: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

serial_sa1100.c

static int sa1100_startup(struct uart_port *port, struct uart_info *info){

int retval;

retval = request_irq(port->irq, sa1100_int, 0, "serial_test", info);// irq=15, name:serial_test

if (retval)return retval;

if (sa1100_open) {retval = sa1100_open(port, info);if (retval) {

free_irq(port->irq, info);return retval;

}}

/** Finally, clear and enable interrupts*/UART_PUT_UTSR0(port, -1);UART_PUT_UTCR3(port, UTCR3_RXE | UTCR3_TXE | UTCR3_RIE);

return 0;}

? startup function

Page 38: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

serial_sa1100.c

static void sa1100_int(int irq, void *dev_id, struct pt_regs *regs){

struct uart_info *info = dev_id;struct uart_port *port = info->port;unsigned int status, pass_counter = 0;

status = UART_GET_UTSR0(port);status &= (SM_TO_UTSR0(port->read_status_mask) | ~UTSR0_TFS);

do {if (status & (UTSR0_RFS | UTSR0_RID)) {

/* Clear the receiver idle bit, if set */if (status & UTSR0_RID)

UART_PUT_UTSR0(port, UTSR0_RID);sa1100_rx_chars(info, regs);

}/* Clear the relevent break bits */

if (status & (UTSR0_RBB | UTSR0_REB))UART_PUT_UTSR0(port, status & (UTSR0_RBB | UTSR0_REB));

? Interrupt Service Routine

if (status & UTSR0_RBB)port->icount.brk++;

if (status & UTSR0_TFS)sa1100_tx_chars(info);

if (pass_counter++ > SA1100_ISR_PASS_LIMIT)break;

status = UART_GET_UTSR0(port);status &= (SM_TO_UTSR0(port->read_status_mask)

| ~UTSR0_TFS);} while (status & (UTSR0_TFS | UTSR0_RFS | UTSR0_RID));}

Page 39: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

serial_sa1100.c

static void sa1100_start_tx(struct uart_port *port, u_int nonempty, u_int from_tty){

if (nonempty) {unsigned long flags;u32 utcr3;

local_irq_save(flags);utcr3 = UART_GET_UTCR3(port);

port->read_status_mask |= UTSR0_TO_SM(UTSR0_TFS);UART_PUT_UTCR3(port, utcr3 | UTCR3_TIE);local_irq_restore(flags);

}}

static void sa1100_stop_tx(struct uart_port *port, u_int from_tty){

u32 utcr3 = UART_GET_UTCR3(port);UART_PUT_UTCR3(port, utcr3 & ~UTCR3_TIE);port->read_status_mask &= ~UTSR0_TO_SM(UTSR0_TFS);

}

? sa1100_start_tx, sa1100_stop_tx function

Page 40: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

serial_sa1100.c

static void sa1100_tx_chars(struct uart_info *info){

struct uart_port *port = info->port;

if (port->x_char) {UART_PUT_CHAR(port, port->x_char);

port->icount.tx++;port->x_char = 0;return;

}if (info->xmit.head == info->xmit.tail

|| info->tty->stopped

|| info->tty->hw_stopped) {sa1100_stop_tx(info->port, 0);return;

}

/*

* Tried using FIFO (not checking TNF) for fifo fill:* still had the '4 bytes repeated' problem.*/

? sa1100_tx_chars function

while (UART_GET_UTSR1(port) & UTSR1_TNF) {UART_PUT_CHAR(port, info->xmit.buf[info->xmit.tail]);

info->xmit.tail = (info->xmit.tail + 1) & (UART_XMIT_SIZE - 1);port->icount.tx++;if (info->xmit.head == info->xmit.tail)

break;}

if (CIRC_CNT(info->xmit.head, info->xmit.tail, UART_XMIT_SIZE) <WAKEUP_CHARS)

uart_event(info, EVT_WRITE_WAKEUP);

if (info->xmit.head == info->xmit.tail)sa1100_stop_tx(info->port, 0);

}

Page 41: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

serial_sa1100.c

sa1100_rx_chars(struct uart_info *info, struct pt_regs *regs){

struct tty_struct *tty = info->tty;unsigned int status, ch, flg, ignored = 0;struct uart_port *port = info->port;

status = UTSR1_TO_SM(UART_GET_UTSR1(port)) | UTSR0_TO_SM(UART_GET_UTSR0(port));while (status & UTSR1_TO_SM(UTSR1_RNE)) {

ch = UART_GET_CHAR(port);

if (tty->flip.count >= TTY_FLIPBUF_SIZE)

goto ignore_char;port->icount.rx++;flg = TTY_NORMAL;if (status & UTSR1_TO_SM(UTSR1_PRE |

UTSR1_FRE | UTSR1_ROR))goto handle_error;

if (uart_handle_sysrq_char(info, ch, regs))goto ignore_char;

? sa1100_rx_chars function(1)

error_return:*tty->flip.flag_buf_ptr ++ = flg;*tty->flip.char_buf_ptr ++ = ch;tty->flip.count++;ignore_char:

status = UTSR1_TO_SM(UART_GET_UTSR1(port)) | UTSR0_TO_SM(UART_GET_UTSR0(port));

}out:

tty_flip_buffer_push(tty);return;

handle_error:if (status & UTSR1_TO_SM(UTSR1_PRE))

port->icount.parity++;else if (status & UTSR1_TO_SM(UTSR1_FRE))

port->icount.frame++;if (status & UTSR1_TO_SM(UTSR1_ROR))

port->icount.overrun++;if (status & port->ignore_status_mask) {

if (++ignored > 100)goto out;

goto ignore_char;}

Page 42: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

serial_sa1110.c

status &= port->read_status_mask;

if (status & UTSR1_TO_SM(UTSR1_PRE))flg = TTY_PARITY;

else if (status & UTSR1_TO_SM(UTSR1_FRE))flg = TTY_FRAME;

if (status & UTSR1_TO_SM(UTSR1_ROR)) {

/** overrun does *not* affect the character* we read from the FIFO*/*tty->flip.flag_buf_ptr ++ = flg;*tty->flip.char_buf_ptr ++ = ch;

tty->flip.count++;if (tty->flip.count >= TTY_FLIPBUF_SIZE)

goto ignore_char;ch = 0;flg = TTY_OVERRUN;

}

goto error_return;}

? sa1100_rx_chars function(2)

Page 43: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

serial_sa1100.c

static void sa1100_stop_rx(struct uart_port *port)

{

u32 utcr3 = UART_GET_UTCR3(port);

UART_PUT_UTCR3(port, utcr3 & ~UTCR3_RIE);

}

static void __exit sa1100_serial_exit(void)

{

uart_unregister_driver(&sa1100_reg);

}

? sa1100_stop_rx, sa1100_serial_exit function

Page 44: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

Serial_test_host.c#include <stdio.h>#include <stdlib.h>#include <unistd.h>

#include <string.h>#include <fcntl.h>#include <termios.h>#include <sys/ioctl.h>

int main( int argc, char **argv ){

int sd; struct termios oldtio,newtio;

char Buff[255]; int DataCount ;int ending;

sd = open( "/dev/ttyS0", O_RDWR | O_NOCTTY );if(sd < 0 ) {

printf( "Serial Open Fail [/dev/ttyS00]\r\n " );exit(0);

}

tcgetattr(sd, &oldtio );memset( &newtio, 0, sizeof(newtio) );

cfsetispeed(&newtio,B115200);cfsetospeed(&newtio,B115200);

newtio.c_cflag &= ~PARENB; newtio.c_cflag &= ~CSTOPB; newtio.c_cflag &= ~CSIZE ; newtio.c_cflag |= CS8 | CLOCAL | CREAD ; newtio.c_iflag = IGNPAR;newtio.c_oflag &= ~OPOST;newtio.c_lflag = 0; newtio.c_cc[VTIME] = 30; newtio.c_cc[VMIN] = 0;

tcflush(sd, TCIFLUSH );tcsetattr(sd, TCSANOW, &newtio );

ending = 0;while(!ending){scanf("%s",Buff);

write(sd, Buff, strlen( Buff ) ); } tcsetattr(sd, TCSANOW, &oldtio ); close(sd); return 0;

}

Page 45: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

Serial_test_SA1110.c#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <fcntl.h>#include <termios.h>#include <sys/ioctl.h>#define BAUDRATE B115200 //termios.h에 정의

int main( int argc, char **argv ){

int sd; struct termios oldtio,newtio;

char Buff[255];int DataCount ;int ending;

/* 읽기/쓰기 모드로 모뎀 장치를 연다.(O_RDWR) 데이터 전송 시에 <CTRL>-C 문자가 오면 프로그램이 종료되지 않도록 하기 위해 controlling tty가 안되도록 한다.(O_NOCTTY) */

sd = open( "/dev/test0", O_RDWR | O_NOCTTY );if(sd < 0 ) {

//시리얼 장치 열기 실패printf( "Serial Open Fail [/dev/test0]\r\n " );exit(0);

}

tcgetattr( sd, &oldtio ); //설정을 oldtio에 저장memset( &newtio, 0, sizeof(newtio) ); //newtio 만큼 메모리 설정

cfsetispeed(&newtio, BAUDRATE); //시리얼 입력 스피드cfsetospeed(&newtio, BAUDRATE); //시리얼 출력 스피드

newtio.c_cflag &= ~PARENB; //패리티 enablenewtio.c_cflag &= ~CSIZE ; //mask character sizebitnewtio.c_cflag &= ~CSTOPB; //stop bit enablenewtio.c_cflag |= CS8 | CLOCAL | CREAD ;

//8N1 , 포트변경무시, 문자수신 가능 설정newtio.c_iflag = IGNPAR; //parity error 문자 무시newtio.c_oflag &= ~OPOST; //출력 금지 설정newtio.c_lflag = 0; //canonical 입력 가능 설정newtio.c_cc[VTIME] = 30; //time_out 값 설정 : TIME*0.1초newtio.c_cc[VMIN] = 0; //최소문자 설정tcflush( sd, TCIFLUSH ); //설정 종료tcsetattr( sd, TCSANOW, &newtio ); //포트 입력 시작ending = 0;while(!ending){DataCount = read( sd, Buff, 255 );

//datacount는 입력 받은 문자 개수if(DataCount < 0 ) { printf( "Read Error\n" );

break;}if(DataCount != 0 ) { Buff[DataCount] = 0;

printf( "Read Data [%s]\n", Buff );if( Buff[0] == 'x' ) ending = 1; //x입력 시 종료

} tcsetattr( sd, TCSANOW, &oldtio ); //설정 값 복구close( sd ); //장치 종료return 0; }

Page 46: UART 디바이스드라이버 - :::: 국립한밭대학교 반도체설계실 ::::artoa.hanbat.ac.kr/lecture_data/embedded_sw/06_old.pdf · 2012-08-02 · #define UART_SBK (1

Hanbat National University Prof. Lee Jaeheung

실습 방법? serial_sa1100.c 모듈로 컴파일? Serial_test_host.c gcc 컴파일

? Serial_test_SA1110.c arm-linux-gcc 컴파일? 보드에 serial_sa1100.o, Serial_test_SA1110 다운로드

? serial_sa1100.o모듈 추가? 보드에서 Serial_test_SA1110 실행? Host PC에서 Serial_test_host 실행? Host PC에서 데이터 입력

? 보드로 데이터 입력되는지 확인