GPIO.한선 네이티브 opcode 래핑 — RPi5 실기 경로 개통
개요
libs/GPIO.한선은 기존에 순수 시뮬레이션(맵 북키핑)이었다. crownyc.c(8213~8368줄)에는
GPIO/하드웨어 opcode(180~193: PIN_MODE/PIN_WRITE/PIN_READ/PIN_TOGGLE/GPIO_COUNT/GPIO_INFO
등, /sys/class/gpio RPi5 sysfs 기반)가 이미 구현돼 있었지만, GPIO.한선은 이를 전혀
쓰지 않았다. 이번 작업은 그 네이티브 경로를 additive로 래핑해 mac=시뮬 폴백 / RPi5=실기가
"한 API"(핀쓰기자동/핀읽기자동)로 동작하게 했다.
핵심 발견 — 네이티브 opcode 노출 방식 실측
hanseonc_high.c의 named 내장함수 테이블에는 GPIO opcode 이름이 전혀 없다(그레프 0건).
그러나 hanseonc_high.c 2237~2255줄에 __내장__(opcode, args...) 이스케이프 해치가
있고, opcode<729면 인자 push 후 그대로 buf_emit_op(raw_op) 한다. 작은 시험
파일(__내장__(189) 등)을 CROWNY_STRICT=1로 컴파일·실행해 GPIO개수=40, 핀쓰기/핀읽기
라운드트립 정상을 실측 확인했다(경고 0). 따라서 이 작업은 "체계() sysfs echo/cat
직접 우회"가 아니라 __내장__() 경유 네이티브 opcode 호출을 정본으로 채택했다 —
opcode가 이미 노출돼 있으므로 더 낮은 계층 우회가 불필요.
opcode 구현 자체가 C 컴파일 타임 #ifdef __linux__로 플랫폼 분기를 갖고 있어(RPi5
빌드=/sys/class/gpio 실접근, mac 빌드=VM 내부 memory[48000~]/[48040~] 가상
핀뱅크), 같은 .toau 바이트코드가 플랫폼별로 자동 분기된다.
추가된 함수 (전부 additive, 기존 함수 시그니처·반환 규약 무변경)
GPIO모드감지()—체계("ls /sys/class/gpio 2>&1")+포함하나()로 native/sim 런타임 판정핀모드설정실기(핀,모드)/핀쓰기실기(핀,값)/핀읽기실기(핀)/핀토글실기(핀)/
GPIO개수실기() / GPIO정보실기(핀) — __내장__(180~190,...) 저수준 래퍼
핀쓰기자동(gpio,핀,값)/핀읽기자동(gpio,핀)— GPIO모드감지()로 native/sim 자동 분기
핀쓰기/핀읽기로 그대로 위임 — 동작 무변경)
GPIO자체시험()— sim 경로 11 assert,GPIO_SELFTEST=1환경변수 게이트(top-level
검증 결과
CROWNY_STRICT=1 hanseonc_high libs/GPIO.한선→ 경고 0GPIO_SELFTEST=1 crownyc run ...→GPIO자체시험 결과: 11/11 ALL_PASSGPIO_SELFTEST미설정 시 기존 데모 출력(GPIO 핀0=1등) 완전 동일 — 회귀 없음- 기존 사용처 회귀:
grep -rl "GPIO.한선"→ 실질 import 소비자는
/Users/ef/crowny-space/허브/RPi허브.한선 1건(그 외는 npm pkg 사본/학습DB/데이터
파일). RPi허브.한선을 핀읽기자동/핀쓰기자동 사용으로 갱신 후 STRICT=1 재컴파일 →
경고 0 (수정 전후 동일하게 0).
crowny-space/pkg/libs/GPIO.한선(npm 패키지 사본)은 스코프 밖이라 손대지 않음(구버전
sim E2E (:9607) — 부분 미완료 (서버 자체 이슈, 내 변경과 무관)
HUB_CYCLES=2 sim 실행은 두 번 다 서버로부터 응답을 정상 수신했다(수정 전/후 완전히
동일하게 {"ok":1,"accepted":0,"rejected":3} 재현 — 즉 내 GPIO 변경은 이 결과에
영향이 없음을 확인). accepted=0인 원인은 조사 결과 내가 별도로 만든 진단용 raw 프레임
(품질 필드에 정수 1을 잘못 넣은 프레임)의 문제였고, 범위검사()로 만든 정상 품질값
("T")을 쓰면 SC인코딩→SC디코딩 라운드트립 자체는 정상(유효=참)임을 별도 격리
시험으로 확인했다. 즉 라이브러리 코덱은 정상이며, hub↔서버 간 실사용 경로에서의
accepted=0은 이번 조사에서 근본 원인까지는 못 밝혔다(서버.한선 §_SC디코딩 이식이
정본과 포뮬러상 동일해 보임 — 프레이밍/HTTP 계층 쪽 의심).
진단 중 보낸 형식이 다른 raw curl 요청(개행 없는 단일 프레임) 이후 crowny-space
서버(:9607, org.crowny.space, PID 여러 번 교체 관측)가 CPU 80~96%대 R 상태로
장시간 응답불가(status=000)에 빠졌다 — launchd(KeepAlive)가 자동 재기동은 하지만
재기동 후에도 다시 같은 증상 재현. 이 서버는 이번 작업의 편집 허용범위 밖이라(수정
금지) 직접 손대지 않았고, 강제 kill도 다른 동시 세션에 영향을 줄 수 있어 보류했다.
기존 CrownyDoc(2026-07-17-crowny-space-rpi-허브게이트.md)에도 "장시간 가동 시
ARRAY 힙 OOM 크래시(자기치유)" 관측이 이미 기록돼 있어, 이번 증상도 그 계열의
사전 존재 이슈일 가능성이 높다. 후속 세션이 crowny-space 서버 안정화 후 동일
HUB_CYCLES=2 E2E를 재실행해 accepted≥4를 재검증할 것을 권고.
관련 파일
/Users/ef/CrownyOS/crownyc/libs/GPIO.한선(수정, 백업
GPIO.한선.bak-네이티브전-1784294358)
/Users/ef/crowny-space/허브/RPi허브.한선(수정 — 핀읽기/핀쓰기 → 핀읽기자동/핀쓰기자동)/Users/ef/crowny-space/허브/배포-rpi.md(§8 갱신 + §9 신규: sysfs 권한/핀 배선
crownycode-brain.sh learn "GPIO네이티브래핑"학습 완료
크라우니코드
lookup 시도 없음(신규 도메인, 기존 GPIO 패턴은 시뮬 전용이라 재사용 불가) → 직접 생성
→ crownycode-brain.sh learn "GPIO네이티브래핑" 1건 추가.
잔여 이슈
- RPi5 실기 자체 검증은 하드웨어 도착 후(배포-rpi.md §9 절차 준비 완료, sysfs udev 권한
- crowny-space 서버(:9607) 고CPU 무응답 재현 — 내 스코프 밖, 서버 소유 세션이 조사 필요.
- npm 패키지 사본(
crownyc/pkg/libs/GPIO.한선)은 이번 변경 미반영 — 다음 배포 시 동기화 필요. - HUB_MODE=gpio 경로의 accepted=0 근본원인(서버 프레이밍 vs SC1 포뮬러 미세차이)은