STM32 F429zi의 데모보드가 만들어져서 납품될 때 회사 ID까지는 다 적혀서 오는데, 시리얼 넘버는 적혀서 오지 않았다. 그러므로 맥주소를 먼저 설정해줘야 한다.
이 작업을 하지 않으면 TCP/IP OS7레이어에서 Physical Layer에서 Network Interface에서 패킷이 가야할 주소를 제대로 찾지 못해서 모튼 패킷을 체크하게되어 통신이 되지 않는다.
ioc파일을 열어서 "Conectivity"탭에서 "ETH" 탭으로 들어간다.
거길 보면 mode가 RMII로 설정되어 있는 것을 볼 수 있다.
"parameter setting"탭을 보면 Ethernet MAC Address가 있는데, 앞에 3바이트는 회사 ID라서 이미 적혀있는 것을 알 수 있다.(00:80:E1 = STM32 회사ID)
뒤에있는 3바이트가 내가 가지고 있는 데모보드의 하드웨어 시리얼 넘버가 되는 것인데, 그게 모든 학생이 전부 00:00:00으로 되어있는 것을 알 수 있다.
내 보드는 지금 "STM32 IP address: 10.10.15.82/24"라는 IP를 쓰도록 되어있는데, 여기서 맨 마지막 "82"를 맥 어드레스에도 적용하는 것으로 우리만의 룰을 설정하도록 하겠다.(그냥 권선일 교수님이 룰을 정한 것.)
최종적으로 내 보드의 MAC Address는 "00:80:E1:00:00:82"가 되는 것이다.
이 값은 RAM에 저장되는게 아니라, 비휘발성 메모리에 저장되게 되어 전원을 껏다 켜도 유지되게 된다.
이렇게 해줌으로써 우리 반 18명 보드의 MAC Address가 충돌하지 않게되어 제대로된 통신이 가능하게 된다.
그리고 마지막으로 잊지 말고, NVIC setting에서 인터럽트를 모두 enable시켜줘야 한다!!! 그래야 패킷 인터럽트가 떠서 제대로 통신이 되게 된다.

그 폴더 안에 APP 폴더가 있고, TARGET 폴더가 있다.
STM32이 배포하는 패키지를 여기서 다운로드 받으면 되는데, 우리의 경우 교수님이 미리 다운받아서 배포해주셨다.
STM32Cube MCU Package for STM32F4 series (HAL, Low-Layer APIs and CMSIS, USB, TCP/IP, File system, RTOS, Graphic - and examples running on ST boards)
툴킷의 풀네임을 보면 대충 무슨 패키지인지 알 수 있겠다.
. >> Projects >> STM324xG_EVAL >> Applications >> LwIP >> LwIP_UDP_Echo_Server >> Inc, Src
위 경로에서 "udp_echoserver.h"와 "udp_echoserver.c"를 복사해다가, 현재 우리가 작업중인 프로젝트 경로에다가 넣어주면 된다. (이 붙여넣기 작업을 윈도우 파일탐색기를 통해 하면 안되고, cubeIDE 상에서 붙여넣기 작업을 해야 제대로 IDE에 파일이 잡힌다.)
/*
* global variables for TCP/IP
*/
ip_addr_t addr1; // client addr
struct pbuf *p1; // send buffer
char temp_str[40]; // temp string buffer
struct udp_pcb *upcb1; // udp control block
extern uint8_t udp_data[100]; // udp data
void StartDefaultTask(void *argument)
{
/* init code for LWIP */
MX_LWIP_Init();
/* USER CODE BEGIN 5 */
/*
* TCP/IP UDP initialize START
*/
udp_echoserver_init();
upcb1 = udp_new(); // 메모리 동적할당
IP4_ADDR(&addr1, 10, 10 , 15, 70); // set client address(kenGwon's local DESKTOP) to STM32F429ZI via ip_addr_t
udp_bind(upcb1, IP_ADDR_ANY, 9999); // bind IP address and port number to UDP socket
/*
* TCP/IP UDP initialize END
*/
/* Infinite loop */
for(;;)
{
ethernetif_input(&gnetif);
sys_check_timeouts();
/*
* TCP/IP UDP communication START
*/
udp_connect(upcb1, &addr1, 9999);
sprintf(temp_str, "Hello, kenGwon");
p1 = pbuf_alloc(PBUF_TRANSPORT, strlen((char*)temp_str), PBUF_POOL);
if (p1 != NULL) // success dynamic memory allocation
{
// 1. copy data to PBuffer
pbuf_take(p1, (char*)temp_str, strlen((char*)temp_str));
// 2. send UDP data
udp_send(upcb1, p1);
// 3. free the UDP connection
udp_disconnect(upcb1);
// 4. free PBuffer
pbuf_free(p1);
}
else
{
HAL_UART_Transmit(&huart3, "pbuf not alloc!!", strlen("pbuf not alloc!!"), 10);
}
/*
* TCP/IP UDP communication END
*/
osDelay(100); // temporary 1 to 100, because of comport master print.. (nomally 1 is )
}
/* USER CODE END 5 */
}
LwIP.h에다가 아래 코드 라인을 Includes for RTOS 주석 부분에 선언했다.
extern struct netif gnetif;
통신으로 말미암아 발생하는 코드라인은 이 파일에 있는 아래 함수 쪽에 주로 작성하게 될 것이다.
void udp_echoserver_receive_callback(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
{
/* Connect to the remote client */
udp_connect(upcb, addr, UDP_CLIENT_PORT);
/* Tell the client that we have accepted it */
udp_send(upcb, p);
/* free the UDP connection, so we can accept new clients */
udp_disconnect(upcb);
/* Free the p buffer */
pbuf_free(p);
}
find / -name "kenGwon" -print
find ./ -name "kenGwon" -print






#include <sys/socket.h>
int socket(int domain, int type, int protocol); // 성공 시 파일 디스크립터(fd, file descripter), 실패 시 -1 반환
...
int bind(int sockfd, struct sockaddr *myaddr, socklen_t addrlen); // 성공 시 0, 실패 시 -1 반환
...
int listen(int sockfd, int backlog0; // 성공 시 0, 실패 시 -1 반환
...
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); // 성공 시 파일 디스크립터(fd, file descripter), 실패 시 -1 반환
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
void error_handling(char *message);
int main(int argc, char *argv[])
{
int serv_sock;
int clnt_sock;
struct sockaddr_in serv_addr;
struct sockaddr_in clnt_addr;
socklen_t clnt_addr_size;
char message[]="Hello World!";
if(argc!=2){
printf("Usage : %s <port>\n", argv[0]);
exit(1);
}
serv_sock=socket(PF_INET, SOCK_STREAM, 0);
if(serv_sock == -1)
error_handling("socket() error");
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family=AF_INET;
serv_addr.sin_addr.s_addr=htonl(INADDR_ANY);
serv_addr.sin_port=htons(atoi(argv[1]));
if(bind(serv_sock, (struct sockaddr*) &serv_addr, sizeof(serv_addr))==-1 )
error_handling("bind() error");
if(listen(serv_sock, 5)==-1)
error_handling("listen() error");
clnt_addr_size=sizeof(clnt_addr);
clnt_sock=accept(serv_sock, (struct sockaddr*)&clnt_addr,&clnt_addr_size);
if(clnt_sock==-1)
error_handling("accept() error");
write(clnt_sock, message, sizeof(message));
close(clnt_sock);
close(serv_sock);
return 0;
}
void error_handling(char *message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
void error_handling(char *message);
int main(int argc, char* argv[])
{
int sock;
struct sockaddr_in serv_addr;
char message[30];
int str_len;
if(argc!=3){
printf("Usage : %s <IP> <port>\n", argv[0]);
exit(1);
}
sock=socket(PF_INET, SOCK_STREAM, 0);
if(sock == -1)
error_handling("socket() error");
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family=AF_INET;
serv_addr.sin_addr.s_addr=inet_addr(argv[1]);
serv_addr.sin_port=htons(atoi(argv[2]));
if(connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr))==-1)
error_handling("connect() error!");
str_len=read(sock, message, sizeof(message)-1);
if(str_len==-1)
error_handling("read() error!");
printf("Message from server: %s \n", message);
close(sock);
return 0;
}
void error_handling(char *message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
listen 하고, connect 요청하고, accept 하는 과정이
있으면 TCP... 없으면 UDP...



https://download.qt.io/archive/qt/5.12/
우리는 5.12.4 버전에서 리눅스용 "qt-opensource-linux-x64-5.12.4.run"를 다운로드 받았다.
임베디드에서 qt를 사용하는 이유는 OS를 타지 않기 때문이다. 다시 말해, OS호환성이 좋은 것이다.
haarcascde russian plate number.xml