STM32F746G-DISCO 보드용으로 제공되는 lwIP 예제가 적어서 STM32756G_EVAL에서 제공되는 예제를 살펴보니 다양한 lwIP 예제가 제공되고 있었고 이를 참고하여 HTTP server 테스트를 해 보았습니다.
(참고 예제 : TM32Cube_FW_F7_V1.16.1/Projects/STM32756G_EVAL/Applications/LwIP/LwIP_HTTP_Server_Netconn_RTOS)
새 프로젝트를 생성 후 DMA2D/ETH/FMC/FREERTOS/GPIO/LTDC/LWIP/NVIC/RCC/SYS/USART1을 설정하였습니다.
이더넷은 STM32의 이전게시물에서 사용된 것과 동일하게 설정을 하였습니다.
HTTP 서버로 동작되기 위해 lwip의 HTTPD 설정을 enable 시켰습니다.
제공되는 예제를 참고하여 새 프로젝트를 작성합니다.
저는 HTTP 서버 테스트를 위해 간단한 데모 웹페이지에 2개의 버튼을 생성 후 각 각의 버튼을 클릭 시 해당 이벤트를 STM32F746G-DISCO 보드에서 수신하여 개별 처리되는 테스트를 해 보려고 합니다.
테스트에 사용될 데모 웹페이지인 index.html을 아래와 같이 작성하였습니다.
<!DOCTYPE html>
<html>
<head>
<title>STM32F746G-DISCO LWIP 테스트</title>
<meta charset="utf-8" />
<style>
html body {
font-family:Verdana,sans-serif;
font-size:15px
}
.center {
margin: auto;
width: 50%;
border: 1px solid green;
padding: 10px;
}
.title {
background-color: #b2fd9f;
width: 450px;
padding: 20px 30px;
text-align: center;
}
.main {
background-color: #a6f5e5;
width: 450px;
padding: 20px 30px;
text-align: center;
}
.button {
border: none;
color: white;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
cursor: pointer;
width: 130px;
border-radius: 5px;
}
.button1 {
background-color: #065fa8;
}
</style>
</head>
<body>
<h1 class="title center">LWIP를 사용한 HTTP 테스트</h1>
<br/>
<div class="main center">
<form method="GET">
<h2>LED ON/OFF 테스트</h2>
<input class="button button1" type="submit" name="led" value="OFF" />
<input class="button button1" type="submit" name="led" value="ON" />
</form>
</div>
</body>
</html>
위 HTML 소스코드는 바로 사용하지 못하고 아래 perl 스크립트 소스를 사용하여 예제 디렉터리에 있는 fsdata_custom.c 파일과 같이 변환해 주는 작업이 필요합니다. 아래 스크립트 소스를 makefsdata로 저장합니다.
#!/usr/bin/perl
open(OUTPUT, "> fsdata.c");
chdir("fs");
open(FILES, "find . -type f |");
while($file = <FILES>) {
# Do not include files in CVS directories nor backup files.
if($file =~ /(CVS|~)/) {
next;
}
chop($file);
open(HEADER, "> /tmp/header") || die $!;
if($file =~ /404/) {
print(HEADER "HTTP/1.0 404 File not found\r\n");
} else {
print(HEADER "HTTP/1.0 200 OK\r\n");
}
print(HEADER "Server: lwIP/pre-0.6 (http://www.sics.se/~adam/lwip/)\r\n");
if($file =~ /\.html$/) {
print(HEADER "Content-type: text/html\r\n");
} elsif($file =~ /\.gif$/) {
print(HEADER "Content-type: image/gif\r\n");
} elsif($file =~ /\.png$/) {
print(HEADER "Content-type: image/png\r\n");
} elsif($file =~ /\.jpg$/) {
print(HEADER "Content-type: image/jpeg\r\n");
} elsif($file =~ /\.class$/) {
print(HEADER "Content-type: application/octet-stream\r\n");
} elsif($file =~ /\.ram$/) {
print(HEADER "Content-type: audio/x-pn-realaudio\r\n");
} else {
print(HEADER "Content-type: text/plain\r\n");
}
print(HEADER "\r\n");
close(HEADER);
unless($file =~ /\.plain$/ || $file =~ /cgi/) {
system("cat /tmp/header $file > /tmp/file");
} else {
system("cp $file /tmp/file");
}
open(FILE, "/tmp/file");
unlink("/tmp/file");
unlink("/tmp/header");
$file =~ s/\.//;
$fvar = $file;
$fvar =~ s-/-_-g;
$fvar =~ s-\.-_-g;
print(OUTPUT "static const unsigned char data".$fvar."[] = {\n");
print(OUTPUT "\t/* $file */\n\t");
for($j = 0; $j < length($file); $j++) {
printf(OUTPUT "%#02x, ", unpack("C", substr($file, $j, 1)));
}
printf(OUTPUT "0,\n");
$i = 0;
while(read(FILE, $data, 1)) {
if($i == 0) {
print(OUTPUT "\t");
}
printf(OUTPUT "%#02x, ", unpack("C", $data));
$i++;
if($i == 10) {
print(OUTPUT "\n");
$i = 0;
}
}
print(OUTPUT "};\n\n");
close(FILE);
push(@fvars, $fvar);
push(@files, $file);
}
for($i = 0; $i < @fvars; $i++) {
$file = $files[$i];
$fvar = $fvars[$i];
if($i == 0) {
$prevfile = "NULL";
} else {
$prevfile = "file" . $fvars[$i - 1];
}
print(OUTPUT "const struct fsdata_file file".$fvar."[] = {{$prevfile, data$fvar, ");
print(OUTPUT "data$fvar + ". (length($file) + 1) .", ");
print(OUTPUT "sizeof(data$fvar) - ". (length($file) + 1) ."}};\n\n");
}
print(OUTPUT "#define FS_ROOT file$fvars[$i - 1]\n\n");
print(OUTPUT "#define FS_NUMFILES $i\n");
위 perl 스크립트를 저장한 디렉토리에 fs 디렉터리를 생성합니다.
예제 프로젝트의 fs 디렉터리의 404.html 파일과 위에서 작성한 index.html 파일을 새로 생성한 fs 디렉터리로 복사해 넣습니다. 위 perl 스크립트 파일이 리눅스 명령어가 사용되어 윈도우 PC 사용자인 경우 cygwin이나 msys 환경에서 실행해야 합니다.
리눅스 환경에서 ./makefsdata 명령어로 실행시키면 같은 디렉터리에 fsdata.c 파일이 생성됩니다.
이 파일의 내용이 예제 프로젝트의 fsdata_custom.c 파일과 동일한 구조로 변경된 파일입니다.
이 파일을 새 프로젝트에 추가하여 적용시키면 됩니다.
데모 웹페이지의 버튼 클릭 시 해당 이벤트를 처리하기 위해 httpserver-netconn.c의 http_server_serve 함수를 아래와 같이 수정하였습니다.
if((strncmp(buf, "GET /index.html", 15) == 0)||(strncmp(buf, "GET / ", 6) == 0)) {
/* Load STM32F7xx page */
fs_open(&file, "/index.html");
netconn_write(conn, (const unsigned char*)(file.data), (size_t)file.len, NETCONN_NOCOPY);
fs_close(&file);
}else if((strncmp(buf, "GET /?led=OFF", 13) == 0)||(strncmp(buf, "GET / ", 6) == 0)) {
printf("--> led off\r\n");
fs_open(&file, "/index.html");
netconn_write(conn, (const unsigned char*)(file.data), (size_t)file.len, NETCONN_NOCOPY);
fs_close(&file);
}else if((strncmp(buf, "GET /?led=ON", 12) == 0)||(strncmp(buf, "GET / ", 6) == 0)) {
printf("===> led on\r\n");
fs_open(&file, "/index.html");
netconn_write(conn, (const unsigned char*)(file.data), (size_t)file.len, NETCONN_NOCOPY);
fs_close(&file);
}
프로젝트를 빌드 후 실행시켜 보면 아래와 같은 화면이 나옵니다.
PC의 웹브라우저를 사용하여 데모 보드의 IP로 접속해 봅니다. 위 index.html 파일이 정상적으로 보입니다.
OFF/ON 버튼을 클릭해 봅니다. led의 파라미터 값이 변경되어 각 각 전송됩니다.
STM32F746G-DISCO 보드에서 해당 이벤트를 수신하여 ON/OFF를 로그를 보여줍니다.
로그를 처리하는 부분에서 다른 센서나 모터등의 주변장치를 제어하는 기능을 추가하여 기능을 확장시킬 수 있을것으로 보입니다. 인터넷으로 데모 보드에 접속하여 사용자 이벤트를 수신하는 기본 테스트를 해 보았습니다.
'Hardware > STM32' 카테고리의 다른 글
[STM32F746G-DISCO] TCP & UDP echo server (0) | 2024.07.22 |
---|---|
[STM32F746G-DISCO] UDP echo server 테스트 (0) | 2024.07.21 |
[STM32F746G-DISCO] UDP echo client 테스트 (0) | 2024.07.21 |
[STM32F746G-DISCO] TCP echo server 테스트 (0) | 2024.07.20 |
[STM32F746G-DISCO] TCP echo client 테스트 (0) | 2024.07.20 |
댓글