임베디드 레시피

Egloos | Log-in





시리얼 포트(Serial port)가 뭐죠?

뭘 알아야 이해를 하지

시리얼(Serial), 유아트(UART), 컴포트(COM) 등등 다양한 이름으로 불리는데 주로 디버깅용이나 바이너리 전송용으로 많이 활용된답니다.
디버깅용은 개발 타겟 보드의 시리얼포트에서 호스트 피시(Host PC)의 시리얼포트로 메시지를 보내서 현재 타겟이 어떻게 동작하고 있는지를 파악 해주므로 매우 편리하게 쓰이는 방법이랍니다. 이런 디버깅 메시지를 출력시키기 위해서는 프린터에프(printf)함수를 사용하면 되요. 이러한 디버깅 방법을 소프트웨어 디버깅이라고 합니다. 흔히 지하철에서 다음 정거장 역을 안내해 줄 때 볼 수 있는 안내 전광판 처럼 개발자가 출력하고자하는 메시지 내용을 씨언어로 만든 소스상에 넣고 타겟 플래시 메모리에 넣은 후 타겟을 동작시키면 호스트 피시의 터미널 프로그램으로 메시지가 출력 된답니다.
다음으로 바이너리 전송용으로도 사용된답니다. 일반적으로 개발자가 개발한 소스 파일을(*.c)  컴파일을 하면 호스트 피시의 하드디스크에 바이너리가 만들어지고, 이 바이너리는 타겟의 플래시 메모리에 넣게 되면 타겟이 동작해요. 플래시 메모리에 넣기 위해서는 컴파일된 바이너리를 호스트 피시에서 타겟으로 전송해야 하는데, 타겟의 시리얼포트와 호스트 피시의 시리얼 포트에 연결시킨 후 호스트 피시에서 타겟 보드 쪽으로 바이너리를 전송하고 그 이후 플래시 메모리에 다운로드가 된답니다.
 그럼 시리얼포트의 하드웨어와 소프트웨어 구성이 어떻게 되는지 알아보아요.

첫 번째, 하드웨어 구성이에요.


 엠시유의 RX, TX 핀과 시리얼포트를 제어해 주는 시리얼 전용칩(IC)에 연결을 해 주고 시리얼 포트를 만들면 됩니다. 이 타겟의 시리얼포트는 호스트 피시의 시리얼포트에 연결 해 주고 호스트 피시에서는 하이퍼터미널과 같은 통신 프로그램을 실행한 후 몇 가지 통신 비트를 설정해 주면 되요.
 
두 번째, 소프트웨어 구성이에요.
시리얼포트로는 입력과 출력 모두 가능해요. 디버깅용으로 사용할 때는 메시지가 타겟에서 호스트 피시로 출력을 시켜 주는 것이고 바이너리를 전송할 때는 호스트 피시에서 타겟으로 입력이 되는 것이랍니다. 우선 메시지를 출력하거나 바이너리를 다운로더하는 프로그램을 만들기 전에 반드시 시리얼 컨트롤러 레지스터에 통신속도나 정지비트 등 몇 가지를 지정을 해야 해요. 여기서 시리얼 컨트롤러 레지스터라고 함은 엠시유에 있는 RX, TX 레지스터를 말해요. 개발자가 지정한 통신 비트대로 하이퍼터미널에서도 똑같이 설정만하면 돼요.
 
씨 언어 프로그램을 살펴볼까요?
우선 시리얼 컨트롤러 값을 설정해 주세요.
그리고 소스에서 메시지를 출력하고 싶은 곳에 메시지를 넣어주세요.



▶코드

int main(void) {
rULCON0=(0<<6)|(0<<3)|(0<<2)|(3); // Normal,No parity,One stop bit, 8bit
rUCON0 &= 0x400; // For the PCLK <-> UCLK fuction
rUCON0 |= (TX_INTTYPE<<9)|(RX_INTTYPE<<8)|(0<<7)|(0<<6)|(0<<5)|(0<<4)|(1<<2)|(1);
//Clock,Tx:Def,Rx:Def,Rx timeout:x,Rx error int:x,Loop-back:x,Send break:x,Tx:int,Rx:int

printf("Have a nice day~~!");

return 0;
}


실제 데이터를 처리하는 소스 중에 출력 부분을 살펴보면, 아래와 같이 최종 tx레지스터에 데이터를 실어 보낸답니다.


▶코드

void UART_Putc(char data) {
u32 temp;
if(data=='\n') {
while(1) {
temp = Inp32(&g_pUartDebugRegs->rUtrStat);
temp&=0x2;
if(temp)
break;
}
Outp8(&g_pUartDebugRegs->rUtxh,'\r');
}
while(1) {
temp = Inp32(&g_pUartDebugRegs->rUtrStat);
temp&=0x02;
if(temp)
break;
}
Outp8(&g_pUartDebugRegs->rUtxh,data);
return;
}



이번에는 데이터를 입력 받는 소스를 살펴보면,



▶코드

vs8 UART_Getc( void) {
u32 temp32;
char temp8;
while(1) {
temp32 = Inp32(&g_pUartDebugRegs->rUtrStat);
temp32&=0x01;
if(temp32)
break;
}
temp8 = Inp8(&g_pUartDebugRegs->rUrxh);
return temp8;
}

어렵지 않죠? 그런데 만약 시리얼 포트가 없다면 어떻게 될까요? 가끔 개발보드 특성상 시리얼 포트 자체가 아예 없다면요? 메시지 없이 개발을 한다면요? 많이 답답하죠. 다른 방법이라도 있을까요? 물론 있지요. ㅎㅎ
 코프로세서를 이용하여 시리얼 포트 대신 시리얼 메시지를 출력 시켜 주는 방법이 있답니다. 이 방법을 사용한다면 위의 그림처럼 시리얼 전용칩과 시리얼 포트, 시리얼 케이블이 필요 없답니다. 대신 하드웨어 디버거가 필요하답니다. 코프로세서를 이용하여 시리얼 메시지를 출력 시키는 원리는 시리얼 포트를 이용할 경우, 시리얼 컨트롤러에서 RX, TX에다 데이터만 넣어 주면 메시지가 나오듯이 코프로세서 14번 레지스터에다 RX, TX 신호 넣어 주게 된답니다. 코프로세서 14번은 하드웨어 디버거용으로 사용되는 레지스터랍니다.

코프로세서 CP14 레지스터에 출력 메시지 보내는 소스랍니다.



▶코드

void CONSOL_SendChar(char bData)
{
register int i,k;
unsigned int ch;
/* Wait for input byte */
do {
__asm__ __volatile__ (
"MRC p14, 0, %0, c0, c0"
: "=r" (k)
);
}while (!(k&0x20000000));
ch = (unsigned int)bData;
__asm__ __volatile__ (
"MCR p14, 0, %0, c1, c0"
: "=r" (ch)
);

for(i = 0; i < 500; i++);

}


코프로세서 CP14 레지스터에 입력을 하는 소스랍니다.



▶코드

char CONSOL_GetChar(char * pbData) {
register int k;
int cnt;
cnt = 0;
do {
__asm__ __volatile__ (
"MRC p14, 0, %0, c0, c0"
: "=r" (k)
);
if (k & 0x00000001) {
__asm__ __volatile__ (
"MRC p14, 0, %0, c1, c0"
: "=r" (k)
);
*pbData = (char)k;
return True;
}
cnt++;
}while(cnt<30);
return False;
}

 

 


간만에 히언 등장. 코드가 나오기 시작하니, 실무적이어서 좋습니다만, html은 귀찮은 작업이로군요. 예쁘지 않아도 이해해 주세요. -라고 말해놓고 보니 너무 무책임하잖아! -
코프로세서 명령어가 나오네요. 그건 Seanson 1의 "Coprocessor Assembly" 편을 읽으시면 자세히 나온다구요.

by 히언 | 2010/04/27 23:04 | SOTO Story | 트랙백 | 핑백(1) | 덧글(3)

Linked at 친절한 임베디드 시스템 개발자.. at 2010/04/27 23:24

... t)가 뭐죠? 207 제이텍(JTAG)이 뭐죠? 208 시리얼 포트(Serial Port)가 뭐죠? 209 엘시디(LCD)에 그림을 보려주려면? 3장 임베디드 시스템 Software 구성 요 ... more

Commented by 성수현 at 2010/04/28 09:03
serial port를 app단에서만 했었는데.. 이렇게 h/w register를 직접 control 해서 하니 정말 좋은 거 같습니다. 그리고 추가적으로 data sheet 내용도 함께 보여줄수 있다면 좋을 듯합니다.
Commented by soto at 2010/04/28 19:20
아...그것까지는 생각을 못 했군요.
감사합니다. ^^;
Commented by han at 2010/05/03 10:19
항상 잘 보고 있습니다.
고맙습니다.
※ 이 포스트는 더 이상 덧글을 남길 수 없습니다.

◀ 이전 페이지          다음 페이지 ▶