( 내용이 길어 라이브러리만 필요하실경우
Ep.까지 맨 아래로 스크롤하시면 됩니다)
Pr. sd모듈구입
저번 첫 웹서버 구동성공글을 올린지 2일만에 파oo츠 쇼핑몰 https://www.parts-kits.com/
을 통해 sd모듈을 구해왔습니다. 케이블 포함 순 단가 740원,
납땜작업 후 테스트결과 피코와 호환도 문제없었습니다.
1. 파이썬 소스로부터 HTML파일 분리 및 기본이미지 로딩 지원
기존 소스에 포함된 html 태그데이터를 외부파일로 빼내
이걸 다시 라이브러리로 불러오는 것부터 시작했습니다.
파이썬초보로서 자료형에 영향받지 않는걸 알게되면서부터 작업이 수월해졌지만
이미지파일에선 약간의 난항끝에 태그쪽 id와 웹앱 라이브러리쪽
route 오버라이딩 메서드 인자값을 맞춰가며 문제를 해결,
여기까진 비교적 진행이 순조로웠습니다.
2. SD카드 지원 - 핀 교체 납떔 및 ( baudrate )
사실 1.과 2.의 과제는 파이썬초보입장에서 파일관리명령을 익히기 위해
sd카드예제를 보는김에 거의 동시 교대로 진행했었습니다.
sd쪽이 거의 먼저지만 진도는 알 수 없는 원인에 더뎌졌죠.
SD의 SPI는 GP1~4(2~6), W5100 이더넷은 GP16~19(21~25)번 핀에
각각 떨어져 연결되었으니 독립된 포트라 생각했는데... 알고보니 같은 SPI 0번 포트였습니다.
파이피코는 스펙상 최대 2개의 SPI포트만 동시지원하는걸로 알고 있기에 평소 괜찮더라도
단 1%라도 충돌여지가 있다면 잠재 버그요소는 배제하잔 취지로 번거롭더라도
더 아래쪽 GP9~12(12~16)번 핀으로 재납땜해야 했고
파워전압도 의심되어 기존 5v단자를 3.3v로 옮겼습니다.
(만년 야매초보 임베디드쪽엔 노자사상주의라 개인소유의 빵판은 없습니다.
동생한테 빌릴수야 있지만 그렇게까진 하고싶지 않아 늘 반복되는 삽질 ^Tㅋ)
며칠 뒤에야 진짜원인은 baudrate SPI 전송속도에 있음을 알았습니다!
어째선지 무심코 참조하게된 SDCard 메서드 끝에 숨겨진 3번 째 인수를 이제야 발견 !
전원소스의 파형에 민감하거나 mcu의 태생적인 성능한계가
microSD속도에 제약을 걸고 있던 것입니다 !
이 부분은 혼자 알아낸 것은 아니고 챗GPT의 추측이 도움이 되었습니다
AI가 만능은 아니어도 3.5정도만 해도 때때로 인간이상의 추리가 되니
이럴 때마다 1인이 아닌 협업한다는 든든한기분을 얻습니다 ㅋ
주파수 디폴트인 1.32Mhz 값을 내려 대략 600Khz대까진 안정적이었고
786Khz부턴 되다안되다 반복했는데 100uF콘덴서 장착시 거의 허용범위이긴 했습니다.
그러므로 안정성 최우선시 실전송성능은 대략 80KB/s정도 였던셈!
3. 2KB를 초과하는 이미지 -
거의 불확실한 모험에 가까운 도전과제였습니다.
웹상의 수많은 피코-웹서버 예제들 중 이미지를 띄운 예제도 드물 뿐더러
그마저도 2KB제한에 걸린 아이콘정도의 크기라 일반적인 큰 이미지띄우긴
애시당초 불가능한건가? 싶었으니까요
wsgi_app.py LIB분석부터 시작했는데 여기 쓰이던 route함수의 마지막 인수
methods의 디폴트값이 GET 으로 되어있고 구글링해본 다른 이미지서버 예제 역시
하이퍼링크주소에 이미지데이터를 통으로 첨부하는걸 볼 때
"GET이라서 2KB제한에 걸렸나 보구나그러면 새로 POST용 코드를 짜야되나?" 싶었습니다.
그러기위해 "200 OK" 라고 된 인수를 "HTTP/2.0 200 OK\r\nContent-type:
text/html; charset=utf-8\r\nContent-Length: 8192" 로 길게 바꿔야했는데,
실 테스트결과는 아무런 변화가 없는 의미없는 시도였죠.
그렇게 분석을 거듭하니 __call__ 이 기본적인 반복호출구간인듯 했고 이것만으론 부족해
더 아래로 파내려가니 통신 라이브러리의 본체격인 adafruit_wiznet5k.py까지 도달해버리고
그 중 socket_write함수의 SOCK_SIZE값이 0x800 10진수로 2048인 것,
buffer와 분기 비교 후 그 값으로 지정한다는 것에서 의심이 확신으로 변하게 됩니다!
그래 이놈이 모든 2KB제한의 원흉이었구나!!
이제 기다려온 수술칼을 뽑아야할 때가 왔습니다!
하지만 통신프로토콜에 전문지식이 있는 것도 아니었고, 파이썬도 입문자에 불과한
그저 C, 자바의 경험치를 바탕으로 추론에 의지하는 문외한일 뿐인데
차량면허 1종 보통으로 요트를 몰아 파도가 몰아치는협곡을 통과하라니?
정말 무모한 짓이 아닐 수 없었습니다
그래서 처음엔 소스를 대강분석만 하되 건들지않고
최대한 우회를 위한 카드로 재귀호출을 꺼내들었습니다!
그렇게 드디어 10일만인 어버이날 지지부진했던 임계점 돌파!
비록 전체이미지는 아니었지만 드디어 2KB 벽을 넘어선 이미지가
웹페이지상에 출력되고 단단한 요새에도 균열이 났습니다!
전체 이미지표현이 안되고 메모리 오버플로우 에러에 막혔는데
재귀호출과정에 이미지가 담긴버퍼가 끊임없이 자동 재할당됐기때문 같았습니다.
가비지컬렉트 같은 여러해제수단이 통하지 않아 결국 통짜 while루프로 교체해
2KB단위로 분할전송하는코드로 바꿨습니다. 또 다시 8KB에서 더 출력이 되지않은건
아까 POST 메타문자열의 Content-Length가 문제였고
그냥 원래의 "200 OK"로 되돌리고 나니 비로소 완전한 이미지 출력성공!!
Ep. 이후 행보, GitHub에 반영
완성된 결과물은 전송속도가 모뎀시절조차 안되는 5KB/s미만의 속도를 보여
이를 개선하고자인터프리터 기반 기존 .py라이브러리를 .mpy로 pre컴파일 변환하기위해
mpy-cross를 apt패키지나 커맨드로 python3 옵션 pip install로 설치시도도 했지만
컴파일엔 실패하고 대신 써킷파이썬 공홈의 주소를 찾아내었으니
https://learn.adafruit.com/welcome-to-circuitpython/frequently-asked-questions#how-can-i-create-my-own-mpy-files-3020687-11
에서 실행가능 mpy-cross 6.x 전용 배포판을 획득해냈고
이걸로 필수 라이브러리를 전부 mpy로 교체할 수 있었습니다.
그렇게 차지하는 내부공간이 절반이 되었지만 아쉽게도
전송속도는 10~20% 약간 더 빨라질 뿐이었습니다.
https://github.com/easygn/RP2040-HAT-CircuitPython
그렇게 작업된 모든 결과물은 전부 깃헙 계정을 만들어 이곳에 반영했습니다.
깃헙도 인생 첫 입문이라 모르는게 많아 적응하는데 또 몇 날이 걸렸네요 ㅎ
덤으로 마크다운언어 .md도 간략히 배울 수 있었습니다.
기존 위즈넷 공식 리포지토리의 포크버전으로써
피코-웹서버 구축시 필요 라이브러리도 동일하게 갖췄고
변경된것은 adafruit_wiznet5k.py 파일 하나 뿐이니 그대로 적용하시면 됩니다.
필요한만큼 or 전부 .mpy로 대체를 원할경우 mpy_lib_cpython-6.3.0 폴더의 것을 받아주세요
긴 글 읽어주셔서 감사합니다.
기록일지를 참조하며 기억들을 다듬느라 영영 빼먹은부분도 있어 작성에 시간이 걸렸습니다.
다음목표는 이미지 전송속도의 정상화, 적어도 1MB/s이상을 목표하고 있습니다.
UDP전송예제상 가능한 것 처럼은 나오는데, 그대로 먹힐진 잘 모르겠네요. 분발해보겠습니다!
전송소스에서 상당지분을 차지할 검증코드를 실험적으로 제거해봤으나 전혀 빨라지지않았습니다.
결국 인터프리터기반 .py 자체가 느린거였고 별도의 타이머 테스트결과 10Mhz치 루프를 처리에
41초가 소모됨으로서 의심이 확신이 되었네요. 원래 스펙대로면 1초안쪽을 끊어야 정상... ㅜ
고작 250Khz짜리니 전송속도 ~5KB/s가 이상할게 없었던 거 였습니다
게다가 .mpy도 속도면에선 전혀 차이없음이 밝혀지며 프리컴파일러는 다를거란 기대가 와장창 ~! ㅠ
결론 : 그러게 누가 파이썬으로 입문하랬 ...? 꼬우면 라데온, 아니 C (대충 그 황회장짤) ...