Yocto 애플리케이션 개발
이 글에서는 Yocto 기반으로 Rockchip RK3399 플랫폼에서 애플리케이션을 개발하는 방법을 다룹니다. 특히 GPIO, UART, I2C와 같은 주변 장치를 제어하는 방법과 간단한 웹 서버, 데이터 로깅 애플리케이션을 구현하는 과정을 설명합니다. 이를 통해 실무 환경에서도 활용 가능한 애플리케이션을 작성하는 방법을 익히실 수 있을 것입니다.
1. RK3399 기반 애플리케이션 개발 개요
RK3399는 강력한 성능과 다양한 주변 장치를 지원하는 ARM 기반 프로세서입니다. Yocto 프로젝트를 통해 임베디드 리눅스를 빌드하면 다음과 같은 환경에서 애플리케이션을 개발할 수 있습니다.
- C/C++ 기반의 네이티브 애플리케이션: 성능 최적화가 필요할 때 유용합니다.
- Python 기반의 스크립트 애플리케이션: 빠른 개발과 유지보수에 적합합니다.
- 웹 기반 애플리케이션: 경량 웹 서버와 함께 RESTful API를 제공하는 서비스 개발이 가능합니다.
이 글에서는 C/C++과 Python을 중심으로 주변 장치 제어와 웹 애플리케이션 개발 방법을 설명하겠습니다.
2. GPIO 제어 예제
GPIO는 간단한 신호 제어와 센서 입력을 처리하는 데 사용됩니다. RK3399에서는 sysfs 인터페이스를 통해 GPIO를 제어할 수 있습니다. 다음은 LED를 제어하는 예제입니다.
2.1 C 언어 기반 GPIO 제어 예제
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#define GPIO_PIN "23"
void write_to_file(const char *path, const char *value) {
int fd = open(path, O_WRONLY);
if (fd < 0) {
perror("Failed to open GPIO file");
exit(EXIT_FAILURE);
}
write(fd, value, sizeof(value));
close(fd);
}
int main() {
// GPIO Export
write_to_file("/sys/class/gpio/export", GPIO_PIN);
sleep(1);
// GPIO 방향 설정
write_to_file("/sys/class/gpio/gpio" GPIO_PIN "/direction", "out");
// GPIO ON
write_to_file("/sys/class/gpio/gpio" GPIO_PIN "/value", "1");
printf("LED ON\n");
sleep(2);
// GPIO OFF
write_to_file("/sys/class/gpio/gpio" GPIO_PIN "/value", "0");
printf("LED OFF\n");
// GPIO Unexport
write_to_file("/sys/class/gpio/unexport", GPIO_PIN);
return 0;
}
2.2 Python 기반 GPIO 제어 예제
import time
def write_to_file(path, value):
with open(path, 'w') as f:
f.write(value)
GPIO_PIN = "23"
# GPIO Export
write_to_file("/sys/class/gpio/export", GPIO_PIN)
time.sleep(1)
# GPIO 방향 설정
write_to_file(f"/sys/class/gpio/gpio{GPIO_PIN}/direction", "out")
# GPIO ON
write_to_file(f"/sys/class/gpio/gpio{GPIO_PIN}/value", "1")
print("LED ON")
time.sleep(2)
# GPIO OFF
write_to_file(f"/sys/class/gpio/gpio{GPIO_PIN}/value", "0")
print("LED OFF")
# GPIO Unexport
write_to_file("/sys/class/gpio/unexport", GPIO_PIN)
3. UART 통신 예제
UART는 외부 장치와 직렬 통신을 수행하는 데 사용됩니다. 다음은 UART를 통해 데이터를 송수신하는 간단한 예제입니다.
3.1 C 언어 기반 UART 통신
#include <stdio.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
int main() {
int uart_fd = open("/dev/ttyS1", O_RDWR | O_NOCTTY);
if (uart_fd < 0) {
perror("Failed to open UART");
return -1;
}
struct termios options;
tcgetattr(uart_fd, &options);
cfsetispeed(&options, B115200);
cfsetospeed(&options, B115200);
options.c_cflag |= (CLOCAL | CREAD);
tcsetattr(uart_fd, TCSANOW, &options);
char send_buf[] = "Hello UART!\n";
write(uart_fd, send_buf, sizeof(send_buf));
char recv_buf[100];
int n = read(uart_fd, recv_buf, sizeof(recv_buf) - 1);
if (n > 0) {
recv_buf[n] = '\0';
printf("Received: %s\n", recv_buf);
}
close(uart_fd);
return 0;
}
3.2 Python 기반 UART 통신
import serial
ser = serial.Serial("/dev/ttyS1", baudrate=115200, timeout=1)
ser.write(b"Hello UART!\n")
response = ser.readline().decode('utf-8')
print(f"Received: {response}")
ser.close()
4. I2C 통신 예제
I2C는 센서와 같은 주변 장치와 통신하는 데 주로 사용됩니다. 다음은 I2C 장치에서 데이터를 읽는 간단한 예제입니다.
4.1 C 언어 기반 I2C 통신
#include <stdio.h>
#include <fcntl.h>
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#include <unistd.h>
int main() {
int file = open("/dev/i2c-1", O_RDWR);
if (file < 0) {
perror("Failed to open I2C device");
return -1;
}
int addr = 0x48; // I2C 장치 주소
if (ioctl(file, I2C_SLAVE, addr) < 0) {
perror("Failed to set I2C address");
close(file);
return -1;
}
char reg = 0x00;
write(file, ®, 1);
char data;
read(file, &data, 1);
printf("Received data: %d\n", data);
close(file);
return 0;
}
4.2 Python 기반 I2C 통신
import smbus
bus = smbus.SMBus(1)
addr = 0x48
# 0x00 레지스터에서 데이터 읽기
bus.write_byte(addr, 0x00)
data = bus.read_byte(addr)
print(f"Received data: {data}")
bus.close()
5. 간단한 웹 서버 구현
RK3399에서 Flask를 사용하여 간단한 웹 서버를 구현할 수 있습니다. 다음은 RESTful API를 제공하는 예제입니다.
from flask import Flask, jsonify
app = Flask(__name__)
@app.route("/status", methods=["GET"])
def status():
return jsonify({"status": "running", "board": "RK3399"})
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
이 코드를 실행한 후 브라우저에서 http://<보드_IP>:5000/status
에 접속하면 상태 정보를 확인할 수 있습니다.
6. 데이터 로깅 애플리케이션
센서 데이터를 주기적으로 읽어 파일에 기록하는 애플리케이션을 작성해보겠습니다.
import time
log_file = "/var/log/sensor_data.log"
while True:
with open(log_file, "a") as f:
f.write(f"Timestamp: {time.time()}, Sensor Data: 123\n")
print("Data logged.")
time.sleep(10)
7. 결론
이 글에서는 RK3399 기반의 Yocto 환경에서 GPIO, UART, I2C와 같은 주변 장치를 제어하고, 간단한 웹 서버와 데이터 로깅 애플리케이션을 구현하는 방법을 살펴보았습니다. 실무에서도 이러한 기법을 활용하여 다양한 임베디드 애플리케이션을 개발할 수 있습니다.
'Linux > yocto' 카테고리의 다른 글
이미지 배포 및 보드 플래싱 (0) | 2025.05.26 |
---|---|
Yocto 실무 예제: 멀티미디어 및 네트워킹 (0) | 2025.05.24 |
고급 개발 기법: 커널 커스터마이징 및 Device Tree 수정 (0) | 2025.05.22 |
Yocto SDK 생성과 활용 (0) | 2025.05.20 |
Yocto 고급 개발 기법: 디버깅과 성능 튜닝 (0) | 2025.05.19 |