콘텐츠로 이동

연결된 서브시스템

이 튜토리얼은 주변 장치 시작하기에서 다룬 GPIO, 셸, ADC/PWM 기초, rt_device_find() 드라이버 패턴에 익숙한 상태를 전제로 합니다. 이 트랙에서는 단일 주변 장치에서 미들웨어를 포함한 통합 워크플로로 나아갑니다. I2C 센서, 그래픽 UI, BLE 서비스, 오디오 재생, 영구 스토리지, 기본적인 공존 테스트를 다룹니다.

목표는 각 서브시스템을 한 번 동작시키는 데 그치지 않습니다. SF32 펌웨어의 일반적인 구성 방식을 익히는 것이 핵심입니다. 해당 기능과 가장 가까운 SDK 예제에서 시작해 하드웨어 경로를 검증하고, 이를 RT-Thread 디바이스나 미들웨어 계층에 연결한 뒤 제품의 다른 기능과 함께 테스트하는 과정을 익힙니다.

개별 주변 장치가 정상 동작하고 통합 위험이 드러나기 시작할 때 이 시리즈를 활용하십시오. 공유 메모리, 타이밍, 전력, 보드별 배선, 미들웨어 간 상호작용을 점검합니다. 각 실습은 화면만 보여 주는 데모가 아니라 테스트할 수 있는 서브시스템 경계를 만들도록 구성했습니다.

시작하기 전에

아래 C 코드는 전체 소스 파일이 아니라 발췌입니다. 프로젝트와 SDK 버전에 필요한 헤더, 선언, 오류 처리, 리소스 정리 코드를 추가하십시오.

예제 경로와 지원 보드는 SDK 릴리스에 따라 달라질 수 있습니다. 빌드하기 전에 각 예제의 현재 Supported Platforms 목록과 보드별 하드웨어 및 구성 요건을 확인하십시오. 한 실습이 지원된다고 해서 다른 실습도 지원된다는 뜻은 아닙니다.

표: 시작하기 전에
요건 중요한 이유
동작하는 셸 list_thread, list_device, 로그, 빠른 점검이 필요합니다.
정상 동작하는 GPIO 입력/출력 많은 미들웨어 데모에는 여전히 버튼, LED, 인터럽트가 필요합니다.
보드 회로도 I2C 핀, 디스플레이 핀, 오디오 경로, 스토리지 레이아웃은 보드마다 다릅니다.
깨끗한 기준 구성 하나 기능을 결합하기 전에 정상 동작하는 빌드를 보관하십시오.
전류를 측정할 방법 연결된 서브시스템 기능은 정상 동작하는 것처럼 보여도 유휴 전력을 바꿀 수 있습니다.

I2C로 센서 읽기

목표: GPIO 핀 하나가 아니라 실제 I2C 주변 장치와 통신합니다.

소요 시간: 30~45분

시작 위치: example/hal/i2c/master 또는 example/rt_device/i2c/eeprom

struct rt_i2c_bus_device *bus = (struct rt_i2c_bus_device *)rt_device_find("i2c1");
struct rt_i2c_msg msgs[2] = { /* write register address, then read result */ };
rt_i2c_transfer(bus, msgs, 2);

i2c1이라는 이름은 예시입니다. 보드에 등록된 I2C 디바이스 이름을 사용하고, 버스를 사용하기 전에 rt_device_find()가 성공하는지 확인하십시오.

  1. 센서 데이터시트에서 I2C 주소, 레지스터 맵, 공급 전압, 필요한 풀업을 확인하십시오.
  2. 보드가 사용하는 i2cX 버스와 핀을 확인하십시오.
  3. I2C EEPROM 또는 마스터 예제를 센서 통신에 맞게 수정하십시오. 디바이스 ID 레지스터가 있으면 먼저 읽고, 없으면 예상 동작을 알고 있는 레지스터부터 시작하십시오.
  4. 실제 측정값 하나를 디코딩해 셸에 출력하십시오.
  5. 센서에 인터럽트 또는 데이터 준비 신호 핀이 있으면 첫 주변 장치의 실습 2에서 다룬 GPIO 인터럽트 패턴을 적용하십시오.
  6. 가능한 경우 고정 폴링을 이벤트 기반 읽기로 바꾸십시오.

성공 기준: 펌웨어가 알려진 레지스터를 예상대로 읽고(가능하면 디바이스 ID), 그럴듯한 센서 값을 디코딩하며, 디바이스가 없을 때도 시스템을 차단하지 않습니다.

문제 해결: 읽기 결과가 모두 0xff이거나 모두 0x00이거나 타임아웃이 발생하면 주소 폭, 7비트와 8비트 주소 표기 방식, 풀업, 전원 시퀀싱, 다른 주변 장치가 같은 핀을 사용하고 있는지 확인하십시오.

배운 내용: 멀티바이트 I2C 트랜잭션, 그리고 인터럽트 기반 GPIO 핀과 버스 주변 장치를 결합하는 방법.

기본 LVGL 화면 만들기

목표: 원시 프레임버퍼 쓰기가 아니라 실제 UI 요소를 디스플레이에 표시합니다.

소요 시간: 45~60분

시작 위치: example/multimedia/lvgl/lvgl_v8_examples

lv_obj_t *label = lv_label_create(lv_scr_act());
lv_label_set_text(label, "Hello, SF32!");
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
  1. 디스플레이 드라이버를 브링업하고, LVGL 위젯을 디버깅하기 전에 단색 채우기가 동작하는지 확인하십시오.
  2. 레이블과 버튼 위젯을 만드십시오.
  3. 버튼 콜백이 레이블 텍스트를 바꾸도록 연결하십시오.
  4. 작은 애니메이션 하나를 추가하고 셸 도구로 CPU 사용률이나 프레임 타이밍을 관찰하십시오.
  5. 규모를 키우기 전에 그래픽 개요에서 버퍼 전략, 부분 갱신, ePicasso를 다루는 절을 읽으십시오.

성공 기준: 리셋 후 화면이 일관되게 초기화되고, 구성된 터치 또는 버튼 입력이 있으면 UI 상태가 바뀌며, 간단한 애니메이션이 셸이나 Bluetooth 동작에 필요한 CPU 시간을 빼앗지 않습니다.

문제 해결: 패널 문제와 LVGL 문제를 분리하십시오. 단색 채우기가 실패하면 LVGL 코드를 건드리기 전에 전원, 리셋, 초기화 시퀀스, 픽셀 포맷, 바이트 순서를 확인하십시오.

배운 내용: LVGL의 객체/이벤트 모델, 그리고 그래픽 비중이 큰 모든 프로젝트가 시작하는 디스플레이 브링업 시퀀스.

목표: 동작하는 GATT 서비스를 통해 휴대폰 또는 BLE 센트럴을 보드에 연결합니다.

소요 시간: 45~60분

시작 위치: example/ble/peripheral

  1. 기본 페리퍼럴 예제에서 시작하여 BLE 스캐너 앱에서 광고가 보이는지 확인하십시오.
  2. 휴대폰에서 연결하고 디바이스가 몇 분 동안 안정적으로 유지되는지 확인하십시오.
  3. 센서 데이터를 보내려면 예제의 GATT 서비스에 적절한 특성을 구성하고, 첫 주변 장치의 실습 4에서 다룬 ADC 읽기값이나 이 트랙의 실습 1에서 다룬 I2C 센서 읽기값 같은 실제 측정값으로 갱신하십시오.
  4. 필요한 특성 속성을 구성하십시오. 알림을 사용한다면 이를 활성화하고 휴대폰이 값 변경을 수신하는지 확인하십시오.
  5. 연결 해제/재연결을 테스트하고, 연결이 활성 상태일 때 보드를 리셋하십시오.
  6. 커스텀 서비스를 설계하기 전에 Bluetooth 개요를 읽으십시오.

성공 기준: 디바이스가 광고하고, 연결되고, 구성된 GATT 서비스를 노출하고, 선택한 특성 속성으로 데이터를 교환하며, 연결 해제/재연결 후 깨끗한 상태로 돌아갑니다.

문제 해결: 오래된 본딩, 휴대폰 쪽의 디바이스 삭제, 연결 중 디바이스 재부팅, 연결 파라미터 변경을 테스트하십시오. 많은 BLE 버그는 첫 번째 정상 경로 연결 이후에야 나타납니다.

배운 내용: 대부분의 BLE 제품이 사용하는 광고 -> 연결 -> GATT 알림 흐름.

스토리지에서 로컬 오디오 재생하기

목표: 합성한 톤이 아니라 오디오 파일을 재생합니다.

소요 시간: 45~60분

시작 위치: example/multimedia/audio/local_music

현재 문서는 example/multimedia/audio/mp3_sd_player의 지원 플랫폼으로 sf32lb52-lchspi-ulp를 나열합니다. 사용하는 보드가 이를 지원한다고 가정하지 말고, 사용하기 전에 지원 플랫폼 및 하드웨어 요건을 확인하십시오.

  1. 작은 WAV 또는 MP3 파일을 예제가 요구하는 스토리지 매체에 넣으십시오.
  2. 예제를 빌드하고 플래시에 기록하십시오.
  3. 재생이 시작되는지, 오디오가 깨끗한지, 재생이 시작될 때 보드가 리셋되지 않는지 확인하십시오.
  4. 재생 시작/중지를 첫 주변 장치의 실습 2에서 다룬 버튼 핸들러에 연결하십시오.
  5. 셸 로깅이나 디스플레이 갱신이 활성 상태일 때 언더런이 발생하는지 관찰하십시오.
  6. 샘플레이트, 포맷, 버퍼 크기를 바꾸기 전에 오디오 개요를 읽으십시오.

성공 기준: 팝 노이즈, 언더런, 활성 전력 상태 누수 없이 재생을 반복해서 시작, 중지, 재시작할 수 있습니다.

문제 해결: 소리가 왜곡되면 샘플레이트, 비트 심도, 출력 경로, 코덱 구성, 파일 포맷, 버퍼 크기, 스토리지 읽기 때문에 디코더가 데이터를 제때 받지 못하는지 확인하십시오.

배운 내용: SDK의 오디오 미들웨어, 버퍼링된 재생, 파일 디코딩이 서로 맞물리는 방식.

영구 데이터 저장 및 조회

목표: 리셋할 때마다 잃어버리지 않고 재부팅 후에도 데이터를 유지합니다.

소요 시간: 30~45분

시작 위치: example/storage/littlefs 또는 example/storage/flashdb

파일 지향 데이터에는 LittleFS를 사용하십시오. FlashDB는 키-값(KVDB)과 시계열(TSDB) 모드를 갖춘 임베디드 데이터베이스이며, 스토리지 백엔드와 지원 보드는 예제 구성에 따라 달라집니다. 타깃을 고르기 전에 공식 LittleFS NOR 및 FlashDB 예제 문서를 참조하십시오.

아래 POSIX 호출은 마운트된 파일 시스템에 접근하는 예시이며 FlashDB API 호출이 아닙니다.

int fd = open("/data/log.txt", O_WRONLY | O_CREAT | O_APPEND, 0666);
write(fd, buf, len);
close(fd);
  1. 파일 형태의 로그에는 LittleFS 같은 파일 시스템을 선택하십시오. 구조화된 설정이나 타임스탬프가 있는 레코드에는 FlashDB의 KVDB 또는 TSDB 모드를 검토하고, 보드와 메모리 디바이스에 맞는 스토리지 백엔드를 선택하십시오.
  2. 예제에서 사용하는 파티션과 마운트 경로를 확인하십시오.
  3. 로그 항목이나 설정을 하나 기록하십시오.
  4. 보드의 전원을 껐다 켠 뒤에도 데이터가 남아 있는지 확인하십시오.
  5. 튜토리얼 1의 센서 측정값을 주기적으로 기록하십시오.
  6. 로그가 계속 늘어나지 않도록 간단한 보존 정책을 추가하십시오.

성공 기준: 재부팅 후에도 데이터가 유지되고, 펌웨어가 스토리지가 없거나, 가득 찼거나, 방금 포맷된 경우를 무리 없이 처리합니다.

문제 해결: 파티션 레이아웃, 마운트 경로, 플래시 삭제/쓰기 오류, 파일 닫기 동작, 스토리지 내구성 목표에 비해 쓰기가 너무 자주 발생하고 있지는 않은지 확인하십시오.

배운 내용: 파일 시스템과 임베디드 데이터베이스 중 무엇을 언제 사용할지, 그리고 리셋 이후에도 제품 상태를 보존하는 방법.

서브시스템 두 개를 의도적으로 결합하기

목표: 서브시스템 두 개를 동시에 실행하고 서로 어떤 영향을 주는지 파악합니다.

소요 시간: 1시간

시작 위치: 튜토리얼 1~5 중 제품과 가장 관련이 깊은 두 가지

  1. 제품에서 실제로 함께 사용할 서브시스템 두 개를 고르십시오. 예를 들어 BLE와 I2C 센서, 또는 LVGL과 오디오 재생을 선택할 수 있습니다.
  2. 먼저 각 서브시스템을 독립적으로 검증하십시오.
  3. 최소한의 변경만 적용해 두 서브시스템을 결합하십시오.
  4. 두 기능을 동시에 실행하십시오. 예를 들어 I2C를 읽는 동안 BLE 알림을 보내거나, 오디오를 재생하면서 UI 애니메이션을 실행하거나, 센서를 갱신하면서 스토리지에 쓸 수 있습니다.
  5. CPU 사용률, 로그, 메모리, 사용자에게 보이는 동작을 관찰하십시오.
  6. 결과를 Bluetooth 개요, 그래픽 개요, 저전력 설계 개요와 비교하십시오.

성공 기준: 동시에 동작하는 중에도 두 서브시스템이 모두 계속 동작하고, 테스트가 끝난 뒤 유휴 전류가 예상 수준으로 돌아옵니다.

문제 해결: 오래 차단되는 호출, 과도한 로깅, 타이머 폭주, 지연에 민감한 경로의 스토리지 쓰기, 공유 버퍼의 캐시 실수를 찾아보십시오.

배운 내용: 따로 동작하던 서브시스템도 CPU 시간, 메모리 대역폭, 인터럽트, 전력 정책을 공유하게 되면 서로 나쁜 영향을 줄 수 있습니다.

연결된 서브시스템 통합 체크리스트

  • 모든 튜토리얼이 정상 동작하는 SDK 예제에서 시작합니다.
  • 각 하드웨어 경로를 먼저 검증합니다. 알려진 센서 레지스터 또는 값, 패널 채우기, BLE 광고, 오디오 출력, 스토리지 마운트가 해당합니다.
  • 해당하는 경우 기능이 리셋과 연결 해제/재연결 후에도 유지됩니다.
  • 오류 경로를 테스트합니다. 센서 없음, 파일 없음, 휴대폰 연결 끊김, 스토리지 가득 참이 해당합니다.
  • 결합 부하 테스트를 최소 한 번 수행했습니다.
  • 각 기능이 중지된 후 유휴 동작을 확인했습니다.

다음 단계

제품 검증에서는 저전력 튜닝, OTA 업데이트, 커스텀 디스플레이 및 드라이버 브링업, 다중 연결 Bluetooth, 양산 디버깅을 다룹니다. 이 트랙은 동작하는 데모를 제품 수준의 펌웨어로 발전시킵니다.

최종 업데이트: