피코 RP2040 + W5100S 이미지웹서버 C버전 완성
.
Preview: Pico RP2040 with WIZnet Web Server -> Process up to Support for microSD & Images
https://www.clien.net/service/board/cm_rasp/18091271?od=T31&po=1&category=0&groupCd=CLIEN
In this project, I aimed to build a web server using Raspberry Pi Pico and improve image transmission speed. The key steps were as follows:
SD Module Purchase and Testing: Acquired and tested an SD module, ensuring compatibility with the Pico.
Separating HTML Files and Supporting Image Loading: I separated the HTML tag data from the web server's code and reloaded it using a library. Issues related to image file loading were also resolved.
SD Card Support and Pin Modification: Learned file management commands through an SD card example and rearranged the Pico's pin configuration to prevent conflicts between the SD card and Ethernet module.
Baudrate Adjustment: Resolved the SD card's SPI transmission speed issue by adjusting the baudrate. Frequency was reduced from 1.32MHz to 600KHz for stability.
Overcoming Image Transmission Limits: Overcame the web server's 2KB image transmission limit by adjusting the SOCK_SIZE value in the socket_write function of the adafruit_wiznet5k.py file.
GitHub Implementation and .mpy Conversion: Uploaded the improved library to GitHub and converted .py files to .mpy files to save internal space. This conversion slightly increased transmission speed.
The next goal of this project is to increase image transmission speed to at least 1MB/s. Plans are to achieve this by referring to UDP transmission examples and further efforts.
Summary
My development journey involved transitioning from Python to C. This change was aimed at improving speed and resolving performance issues in the Python version. Throughout this process, I faced and overcame several technical challenges, leading to significant discoveries.
Initially, to address the speed issues in the Python version, I experimented with various techniques such as native assembly, asm_thumb examples, and inline compilation of C modules. However, these methods were not applicable due to the physical limitations of the Raspberry Pi Pico.
Subsequently, I decided to switch to a C language-based approach. During this phase, I utilized the RP2040-HAT-C library and the gcc-arm-none-eabi library. Despite their large sizes, these libraries facilitated development on the Raspberry Pi SBC.
After choosing Arduino IDE as my development environment, I achieved my first successful compilation. This process involved correcting several compilation errors, from which I gained valuable experience.
The next step was to tackle SD card recognition. In this phase, I encountered and solved various problems, and modified an image loading example provided by Starting Electronics. Using this example, I developed a method for efficiently loading images on a web server.
Finally, to address a bottleneck discovered during the file reading process, I added a 1KB buffer code. This significantly reduced the image loading time. After these improvements, I ultimately uploaded the project to GitHub.
Furthermore, I experimented with buffers of various sizes (2KB, 8KB, 16KB) to further reduce the 1.5-second loading time. However, the 16KB buffer actually resulted in a slower loading time by 0.5 seconds, and the 2KB buffer was identified as the most suitable standard for the w5100s socket. Consequently, I set the 2KB buffer as the release version and the 8KB buffer as the experimental version.
Origin
파이 피코에서 이미지웹서버를 구현한
지난 파이썬버전에서 속도가 대폭 개선된
C버전 개발이 드디어 마무리 완료 되었습니다!
지난 파이썬버전에 관한글 - https://www.clien.net/service/board/cm_rasp/18091271?od=T31&po=1&category=0&groupCd=CLIEN
C언어버전 (런타임 : Runnable UF2) - https://github.com/easygn/Webserver-SD-buffered-Image-Pico
아래는 개발과정에 관한글로 코딩 관련한
몇몇 유용한정보나 팁이 궁금하지 않을경우 생략하셔도 됩니다
6-7월 ) 네이티브 LIB를 찾는 여정
파이썬버전에서의 속도문제를 해결해보려 여러방법을 모색합니다.
네이티브 어셈블리부터 asm_thumb예제라던가 그에 해당하는 @데코레이터라던가
마이크로파이썬에선 지원된다는데 아쉽게도 써킷파이썬에선 지원되지 않는다더군요?
그외 C모듈 인라인 컴파일이란 꼼수도 배워보고 cython numpy 뭐든 다해봤지만
스스로의 역량부족인지 피코의 물리적한계인지 아무것도 적용되지 않아 gg
그 과정에 실행가능 bin to uf2 변환사이트인 ovobo.cc란 신박한사이트에 이어
uf2conv.py라는 마소에서 제공하는 변환툴도 발견했는데, 여러 파이썬코드가 연결된걸
함부로 단일 .uf2로 변환하자니 뭔가 신포도가 우려되어 더 진행못하다 어느새 잊혀지고...
8월 ) C로 복귀
단념 이후 6월에도 줄곧 꺼려오던 C언어기반으로 밑바닥부터 새로 시작하려 했는데
깃헙 RP2040-HAT-C 라이브러리를 통짜로 내려받으려니 2.5GB라는 무지막지한 용량압박!
이를 정상적으로 CMake하기 위한 gcc-arm-none-eabi 라이브러리도 1.7GB에 달했습니다.
보통의 개발환경에 뭐 그깟용량이 대수? 하지만 이건 파이sbc로 파이mcu용 코딩만 할 거라
이미 포화상태인 파이OS저장소에 넣자니 용도대비 넘 무거웠죠, 그나마 깃헙라이브러리만 하나하나
수작업분석해 필수요소만 취하려다 폭염, 창문에어컨소음에 지쳤고 CMake로는 엄두가 안나 또 좌절,
9월 ) 개발환경은 아두이노 IDE 로 결정, 첫 컴파일 성공!
구형 파이sbc에 일반적인 IDE 로는 더이상 정상진행이 안될 것 같아 1달전에 시도하다만
아두이노IDE를 다시 켜고 기존에 쓰던 보드매니저 URL로는 계속 여러문제로 어려움을 겪다
https://github.com/WIZnet-ArduinoEthernet/arduino-pico/releases/download/global/package_rp2040-ethernet_index.json
어떻게든 위의 새로운 URL로 새로운 보드 Pico/RP2040 Ethernet 이란걸 설치했습니다!
8월의 고뇌를 완벽히 떨쳐버릴 고작 370MB정도의 용량! 그럼에도 지원보드는 전보다 훨 많다는거!
그럼에도 이 또한 그대로 쓸 순 없었고 컴파일오류를 따라 lib폴더의 udpv6.h의 대소문자작명을 교정해주니
그제서야 첫 C기반으로 정상 컴파일된 웹서버 런타임.uf2를 손에넣을 수 있었습니다!
이때가 18일이었고 내친김에 sd카드 인식도 도전했는데 이후는 또 새로운문제가 도래했으니...
10-11월 ) SD카드 삽질의 2차 암흑기
뭐 이미 한차례 횡설수설 중간보고로 휩쓸고갔던 가을의 일이었죠,
요약하면 GPT가 꽤나 공동작업으로 열일해줬지만
최후의 일격은 킹택오버갓로우의 업적이었다나...
자세한건 - https://www.clien.net/service/board/cm_rasp/18432703?od=T31&po=0&category=0&groupCd=CLIEN
12월 ) 이미 존재하던 이미지로드예제 발견, 수정 및 속도향상!
보름간의 유유부단한 공백기간, 오랜 구글링 삽질기간 끝에
드디어 starting Electronics
https://startingelectronics.org/tutorials/arduino/ethernet-shield-web-server-tutorial/SD-card-web-server-image/
라는데서 요청데이터 파싱하는코드를 찾았습니다!
'ethernetclient read img src' 라는 우연한 키워드의 결과!
코드를 그대로 쓰기엔 양심상 며칠 고민했던건 기우에 불과,
실제론 장비상황에 맞춰 수정할게 꽤 있었네요.
가을동안 쌓아둔 삽질의경험들을 전부 녹여 포크수준으로 리팩토링하고 첫 테스트 성공!!
7달이 지나서야 파이썬에서 작동하던 이미지웹서버의 현장을
드디어 네이티브 C로도 볼 수 있게됍니다!!
심지어 파이썬에서 그토록 벽을 넘으려 애먹은 2KB 용량제한조차 없었습니다.
다만 어찌된건지 초기버전은 전송속도 또한 파이썬정도밖에 되지 않더군요?
w5100장치용 라이브러리 문제도 의심했지만 이미 성능문제를 해결한 2.0버전,
그래서 소스 정밀재분석결과 파일읽기 수행과정이 한 번에 1byte 씩 이뤄져
병목유발요인을 발견했고, 실험삼아 1KB 버퍼코드를 추가하니
드디어 10초를 잡아먹던 이미지로딩을 약 1.5초까지 단축에 성공했습니다!
12월 말 ) 완성, 깃헙에 추가
이외에 2KB, 8, 16KB 다양한 크기의 버퍼크기를 만들어
1.5초마저 단축해보려했지만 유의미한 효과는 없거나
16KB의 경우 되려 0.5초 느려졌고, 그나마 w5100s의 소켓당
표준인 2KB가 가장 안정적이라 이걸 릴리즈버전,
8KB는 실험버전 2가지로 준비했습니다.
이 소소한 프로젝트에 들인 노력과 시간대비 기여자로서 한 일은
원저작자 몫의 일부에 불과했기에 마침 라이센스문제에 관심도 생겨
며칠간 웹서핑으로 공부해보니 3-clause BSD가 가장 취지에 맞는듯해
기본적으로 아두이노 표준인 GNU(GPL) v2를 준수,
효력이 없는 극단적 예외에만 BSD라이선스가 유효함을 명시하고
28일날 리포지토리 작성, 업로드 과정을 모두 끝냈습니다!
쌓인 피로에 수면불량으로 2일 후인 오늘에야 소모임에 소식을 전하게 되었네요
업로드한 날이 하필 유명인의 비보가 있던 그날 이어서인지 유독 심경이 복잡했습니다.
아직 스스로 성능에 대한 아쉬움이 남아 올해의 마지막날이든 내년에도
꾸준히 개선해볼 계획이고, 욕심이 커질경우 멀티쓰레드까지 생각해두고 있습니다.
새해에는 좋은일까진 어렵더라도 전지구적 환란의시대에
모두가 거친풍파로부터 무사무난할 수 있는해가 되었음 하는바램입니다. 감사합니다!