[AT90USB1287-EX] 이더넷 테스트 - 초간단 웹서버 만들기
AVR와 W5100을 이용하여 아주 간단한 웹서버를 만들어 보도록 하자.
웹서버는 TCP서버의 일종으로 웹브라우저에서 80번 포트로 접속하면 HTTP프로토콜에 따라 데이터를 송수신 하면 된다.
AVR 초간단 웹서버 테스트 동영상
[AT90USB1287-EX] 보드가 임베디드 웹서버로 동작하고 접속하여 보드의 LED제어하는 간단한 예제를 작성해 보았다.
먼저 접속하면 보여줄 웹페이지를 HTML 코드로 작성해서 변수로 저장해 둔다. 추후 좀더 복잡한 페이지는 USB메모리 스틱이나 SD Card에 저장할 수 있다.
TCP서버 처리를 위한 함수는 기존과 동일한데 HTTP프로토콜은 디폴트 80번 포트 이므로 80번포트로 소켓을 생성하고 데이터 수신되면 웹페이지를 전송해 주면 된다. 아래 코드와 같이 아주 간단하다.
이제 웹페이지에서 특정한 응답을 받아서 처리 하는 부분을 작성해 보자. 이번 예제에서는 웹페이지에 있는 버튼에 따라 LED를 On/Off할 수 있도록 해 보았다.
아래 코드와 같이 브라우저에서 웹페이지를 요청하면 "HTTP/1.0 200 OK" 메세지와 HTML페이지를 전송하면 된다.
send(sock, str_http_ok, strlen(str_http_ok));
send(sock, str_msg, strlen(str_msg));
AVR와 W5100을 이용하여 아주 간단한 웹서버를 만들어 보도록 하자.
웹서버는 TCP서버의 일종으로 웹브라우저에서 80번 포트로 접속하면 HTTP프로토콜에 따라 데이터를 송수신 하면 된다.
AVR 초간단 웹서버 테스트 동영상
[AT90USB1287-EX] 보드가 임베디드 웹서버로 동작하고 접속하여 보드의 LED제어하는 간단한 예제를 작성해 보았다.
먼저 접속하면 보여줄 웹페이지를 HTML 코드로 작성해서 변수로 저장해 둔다. 추후 좀더 복잡한 페이지는 USB메모리 스틱이나 SD Card에 저장할 수 있다.
const unsigned char str_http_ok[] = {"HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n"};
const unsigned char str_msg[] = {"HTTP/1.0 200 OK\r\nContent-Type: text/html\r\nPragma: no-cache\r\n\r\n\
<html><head></head><body ><DIV><p align=\"center\"><b><size=\"8\"><br>[AT90USB1287-EX] WebServer - LED Test</font></b></DIV>\
<HR style=\"COLOR: #3366FF; BACKGROUND-COLOR: #EB9243\"></DIV><div align=\"center\"><p align=\"center\"></p></div>\
<form name=\"form1\" method=\"get\" action=\"$LED_ON\"><p align=\"center\"><input type=\"submit\" value=\"LED ON\" name=\"ledo\"></p></form>\
<p><p></td></tr><tr><td><form name=\"form2\" method=\"get\" action=\"$LED_OF\"><p align=\"center\">\
<input type=\"submit\" value=\"LED OFF\" name=\"ledn\"></p></form><p></td></tr></table></div></body></html>"};
const unsigned char str_msg[] = {"HTTP/1.0 200 OK\r\nContent-Type: text/html\r\nPragma: no-cache\r\n\r\n\
<html><head></head><body ><DIV><p align=\"center\"><b><size=\"8\"><br>[AT90USB1287-EX] WebServer - LED Test</font></b></DIV>\
<HR style=\"COLOR: #3366FF; BACKGROUND-COLOR: #EB9243\"></DIV><div align=\"center\"><p align=\"center\"></p></div>\
<form name=\"form1\" method=\"get\" action=\"$LED_ON\"><p align=\"center\"><input type=\"submit\" value=\"LED ON\" name=\"ledo\"></p></form>\
<p><p></td></tr><tr><td><form name=\"form2\" method=\"get\" action=\"$LED_OF\"><p align=\"center\">\
<input type=\"submit\" value=\"LED OFF\" name=\"ledn\"></p></form><p></td></tr></table></div></body></html>"};
TCP서버 처리를 위한 함수는 기존과 동일한데 HTTP프로토콜은 디폴트 80번 포트 이므로 80번포트로 소켓을 생성하고 데이터 수신되면 웹페이지를 전송해 주면 된다. 아래 코드와 같이 아주 간단하다.
void ProcessTCPS(unsigned int sock)
{
unsigned int len;
unsigned int port = MY_LISTEN_PORT;
switch (getSn_SR(sock))
{
// Socket CLOSED일 경우
case SOCK_CLOSED:
if(!m_SokStatus1)
{
DebugPrint("[%d] : Web Server Started.",sock);
m_SokStatus1 = 1;
}
if(socket(sock, Sn_MR_TCP, DEFAULT_HTTP_PORT, 0x00) == 0)
{
DebugPrint("\a%d : Fail to create socket.",sock);
m_SokStatus1 = 0;
}
else listen(sock);
break;
case SOCK_ESTABLISHED:
//수신데이터가 있으면
if((len = getSn_RX_RSR(sock)) > 0)
{
if (len > TX_RX_MAX_BUF_SIZE) len = TX_RX_MAX_BUF_SIZE;
//데이터 수신
len = recv(sock, data_buf, len);
//수신데이터 처리 -> 웹 쿼리 응답
ProcessWebpage(sock, data_buf);
}
break;
case SOCK_CLOSE_WAIT:
//If the client request to close
disconnect(sock);
m_SokStatus1 = 0;
break;
}
}
{
unsigned int len;
unsigned int port = MY_LISTEN_PORT;
switch (getSn_SR(sock))
{
// Socket CLOSED일 경우
case SOCK_CLOSED:
if(!m_SokStatus1)
{
DebugPrint("[%d] : Web Server Started.",sock);
m_SokStatus1 = 1;
}
if(socket(sock, Sn_MR_TCP, DEFAULT_HTTP_PORT, 0x00) == 0)
{
DebugPrint("\a%d : Fail to create socket.",sock);
m_SokStatus1 = 0;
}
else listen(sock);
break;
case SOCK_ESTABLISHED:
//수신데이터가 있으면
if((len = getSn_RX_RSR(sock)) > 0)
{
if (len > TX_RX_MAX_BUF_SIZE) len = TX_RX_MAX_BUF_SIZE;
//데이터 수신
len = recv(sock, data_buf, len);
//수신데이터 처리 -> 웹 쿼리 응답
ProcessWebpage(sock, data_buf);
}
break;
case SOCK_CLOSE_WAIT:
//If the client request to close
disconnect(sock);
m_SokStatus1 = 0;
break;
}
}
이제 웹페이지에서 특정한 응답을 받아서 처리 하는 부분을 작성해 보자. 이번 예제에서는 웹페이지에 있는 버튼에 따라 LED를 On/Off할 수 있도록 해 보았다.
아래 코드와 같이 브라우저에서 웹페이지를 요청하면 "HTTP/1.0 200 OK" 메세지와 HTML페이지를 전송하면 된다.
send(sock, str_http_ok, strlen(str_http_ok));
send(sock, str_msg, strlen(str_msg));
void ProcessWebpage(unsigned sock, unsigned char *data_buf)
{
int wait_send=0;
//LED 제어 처리
if(strncmp("$LED_ON", (char *)&(data_buf[5]), 7)==0)
{
Led1On();
send(sock, str_http_ok, strlen(str_http_ok));
send(sock, str_msg, strlen(str_msg));
DebugPrint("led on\r\n");
}
else if(strncmp("$LED_OF", (char *)&(data_buf[5]), 7)==0)
{
Led1Off();
PORTF = 0xFF;
send(sock, str_http_ok, strlen(str_http_ok));
send(sock, str_msg, strlen(str_msg));
DebugPrint("led off\r\n");
}
else
{
send(sock, str_msg, strlen(str_msg));
}
while(getSn_TX_FSR(sock)!= getIINCHIP_TxMAX(sock))
{
if(wait_send++ > 1500)
{
DebugPrint( "HTTP Response send fail");
break;
}
Delay(1);
}
disconnect(sock);
DebugPrint("closed\r\n");
}
{
int wait_send=0;
//LED 제어 처리
if(strncmp("$LED_ON", (char *)&(data_buf[5]), 7)==0)
{
Led1On();
send(sock, str_http_ok, strlen(str_http_ok));
send(sock, str_msg, strlen(str_msg));
DebugPrint("led on\r\n");
}
else if(strncmp("$LED_OF", (char *)&(data_buf[5]), 7)==0)
{
Led1Off();
PORTF = 0xFF;
send(sock, str_http_ok, strlen(str_http_ok));
send(sock, str_msg, strlen(str_msg));
DebugPrint("led off\r\n");
}
else
{
send(sock, str_msg, strlen(str_msg));
}
while(getSn_TX_FSR(sock)!= getIINCHIP_TxMAX(sock))
{
if(wait_send++ > 1500)
{
DebugPrint( "HTTP Response send fail");
break;
}
Delay(1);
}
disconnect(sock);
DebugPrint("closed\r\n");
}
반응형