
रास्पबेरी पाई पिको W के लिए फर्मवेयर जो एक ड्राइवर-रहित USB Wi-Fi एडाप्टर बनाता है, जिसमें पारदर्शी लेयर-2 ब्रिजिंग, WPA2/WPA3 प्रमाणीकरण, और आउट-ऑफ-बैंड प्रबंधन कंसोल शामिल है।
= pico-usb-wifi :toc: macro :toclevels: 3 :idprefix: :idseparator: -
pico-usb-wifi रास्पबेरी पाई पिको W के लिए फर्मवेयर है जो इसे एक ड्राइवर-रहित USB Wi-Fi एडाप्टर में बदल देता है, जो USB CDC-NCM डिवाइस के रूप में एन्यूमरेट होता है।
:figure-caption: AI Slop
.pico-usb-wifi आरेख image::images/openrouter-banana2-rpi-pico.png[]
फर्मवेयर एक पारदर्शी लेयर-2 ब्रिज के रूप में कार्य करता है जो पिको W के वायरलेस इंटरफेस और उसके USB इंटरफेस के बीच फ्रेम अग्रेषित करता है। होस्ट का USB इंटरफेस पिको W Wi-Fi स्टेशन का MAC पता अपना लेता है, जो अंत-से-अंत तक एकल MAC और IP पहचान प्रदान करता है।
किसी होस्ट-साइड ड्राइवर, कर्नेल मॉड्यूल या वायरलेस स्टैक की आवश्यकता नहीं है; देखें <<no-host-side-wi-fi-stack,कोई होस्ट-साइड Wi-Fi स्टैक नहीं>>।
होस्ट को केवल बिल्ट-इन cdc_ncm और cdc_acm ड्राइवरों की आवश्यकता होती है जो हर आधुनिक Linux, macOS, Windows और मोबाइल OS के साथ आते हैं।
== विशेषताएँ
pico-usb-wifi ये सुविधाएँ प्रदान करता है:
.एक वास्तविक दुनिया की स्थिति image::images/slop_2.png[]
== यह क्यों मौजूद है
मुझे एक आगामी एम्बेडेड Linux प्रोजेक्ट में उपयोग के लिए USB Wi-Fi एडाप्टर की आवश्यकता थी। मेरे पास सस्ता USB Wi-Fi डोंगल नहीं था, इसलिए किसी भौतिक स्टोर से पाँच USD में खरीदने जाने के बजाय, मैंने एक लंबे छुट्टी वाले सप्ताहांत के दो दिन और लगभग दस लाख Claude Code टोकन इस फर्मवेयर को बनाने में बिताए।
白一百, pico-usb-wifi के लेखक
Google ने कहा कि यह संभव नहीं है:
.pico-usb-wifi "संभव नहीं" image::images/gemini_says_not_possible.png[]
toc::[]
== कोई होस्ट-साइड Wi-Fi स्टैक नहीं
USB Wi-Fi डोंगल के विपरीत, यह एडाप्टर होस्ट को केवल एक ईथरनेट-जैसा इंटरफेस प्रदान करता है। पिको W संपूर्ण वायरलेस पक्ष रखता है: रेडियो, एसोसिएशन, WPA2/WPA3 सप्लीकेंट और नियामक डोमेन।
यह सिस्टम को wpa_supplicant, cfg80211/mac80211 वायरलेस स्टैक, नियामक डेटाबेस और चिपसेट फर्मवेयर या वेंडर ड्राइवर स्थापित करने से बचने की अनुमति देता है।
Wi-Fi क्रेडेंशियल की प्रोविज़निंग डिवाइस पर, उसके आउट-ऑफ-बैंड प्रबंधन कंसोल के माध्यम से होती है, न कि किसी होस्ट-साइड वायरलेस टूलिंग के माध्यम से।
यह एक सीमित या उपकरण होस्ट, या ऐसे होस्ट जिसमें वायरलेस ड्राइवर नहीं हैं, या जिसके वेंडर कर्नेल में उनकी कमी है, को केवल यूनिवर्सल CDC क्लास ड्राइवरों का उपयोग करके वायरलेस नेटवर्क से जुड़ने की क्षमता प्रदान करता है।
== यह कैसे काम करता है
[#fig-topology] .टोपोलॉजी आरेख image::images/topology.svg[पारदर्शी लेयर-2 ब्रिज टोपोलॉजी,820]
होस्ट के USB इंटरफेस को पिको W के Wi-Fi स्टेशन का MAC पता दिया जाता है, इसलिए अंत-से-अंत तक एकल MAC मौजूद रहता है और पिको W USB और Wi-Fi के बीच ईथरनेट फ्रेम को यथावत अग्रेषित कर सकता है। एक Wi-Fi स्टेशन कई MAC पतों को ब्रिज नहीं कर सकता, इसलिए होस्ट और स्टेशन को एक MAC पर समेटना ही वह चीज़ है जो पारदर्शी ब्रिज को संभव बनाती है। पूर्ण तर्क, डेटा पथ और IPv6/मल्टीकास्ट हैंडलिंग का वर्णन <<architecture,आर्किटेक्चर>> में किया गया है।
== होस्ट आवश्यकताएँ
होस्ट को इन-ट्री cdc_ncm और cdc_acm ड्राइवरों की आवश्यकता होती है।
दोनों एक दशक से अधिक समय से मेनलाइन Linux का हिस्सा रहे हैं, इसलिए कोई भी वर्तमान में समर्थित कर्नेल उन्हें शामिल करता है।
कोई आउट-ऑफ-ट्री मॉड्यूल, फर्मवेयर ब्लॉब या वेंडर ड्राइवर शामिल नहीं है।
वही क्लास ड्राइवर macOS, Windows 10 और बाद के संस्करण, Android और iOS पर मौजूद हैं।
[NOTE] किसी अन्य ऑपरेटिंग सिस्टम का परीक्षण नहीं किया गया।
== बिल्डिंग
यह प्रोजेक्ट एक मानक pico-sdk CMake प्रोजेक्ट है। इसे ARM एम्बेडेड टूलचेन, CMake, एक बिल्ड बैकएंड (Ninja या Make), Python 3 और pico-sdk की उसके सबमॉड्यूल्स सहित चेकआउट की आवश्यकता होती है। pico-sdk में बंडल किए गए TinyUSB और lwIP का उपयोग बिना संशोधन के किया जाता है।
=== निर्भरताएँ
Arch-आधारित सिस्टम (Arch, CachyOS, Manjaro) पर, टूलचेन आधिकारिक रिपॉजिटरी से आती है:
arm-none-eabi-newlib एम्बेडेड C लाइब्रेरी और हेडर प्रदान करता है; इसके बिना क्रॉस-कंपाइलर stdint.h और समान हेडर नहीं ढूँढ सकता।
libusb केवल picotool के लिए आवश्यक है, जिसे pico-sdk पहले कॉन्फ़िगर के दौरान UF2 उत्पन्न करने के लिए स्रोत से बनाता है; किसी अलग picotool पैकेज की आवश्यकता नहीं है।
=== बिल्ड चरण
git clone -b 2.2.0 --recurse-submodules https://github.com/raspberrypi/pico-sdk export PICO_SDK_PATH="$PWD/pico-sdk"
cp src/wifi_config.h.example src/wifi_config.h # then edit SSID/password, or leave blank cmake -S . -B build -G Ninja -DPICO_BOARD=pico_w -DCMAKE_BUILD_TYPE=Release cmake --build build
-G Ninja फ्लैग वैकल्पिक है; डिफ़ॉल्ट Make जनरेटर उपयोग करने के लिए इसे हटा दें (फिर cmake --build build -j)।
wifi_config.h संकलन-समय डिफ़ॉल्ट क्रेडेंशियल रखता है और gitignored है।
इसे खाली छोड़ने से बिना किसी एम्बेडेड क्रेडेंशियल वाली इमेज बनती है जिसे रनटाइम पर मैनेजमेंट कंसोल (<<management-console,मैनेजमेंट कंसोल>>) के माध्यम से प्रोविज़न किया जाता है; इसे भरने से एक डिफ़ॉल्ट नेटवर्क एम्बेड हो जाता है।
== फर्मवेयर लिखना
ये चरण बोर्ड पर फर्मवेयर लोड करते हैं।
. BOOTSEL बटन दबाए रखते हुए बोर्ड को USB से कनेक्ट करें।
यह RPI-RP2 USB मास-स्टोरेज वॉल्यूम के रूप में माउंट होता है, आमतौर पर /run/media/<user>/RPI-RP2 या /media/<user>/RPI-RP2 के अंतर्गत।
. pico-usb-wifi.uf2 को उस वॉल्यूम पर कॉपी करें।
बोर्ड स्वचालित रूप से फर्मवेयर में रीबूट हो जाता है।
. बोर्ड को उस होस्ट से कनेक्ट करें जिसे Wi-Fi कनेक्टिविटी प्राप्त करनी है।
== Linux होस्ट पर उपयोग
डिवाइस को होस्ट में प्लग करें और मैनेजमेंट कंसोल (<<management-console,मैनेजमेंट कंसोल>>) के माध्यम से एक बार उसके Wi-Fi क्रेडेंशियल प्रोविज़न करें। होस्ट का इंटरफेस तब एक्सेस पॉइंट के नेटवर्क पर किसी भी वायर्ड कनेक्शन की तरह व्यवहार करता है।
जो होस्ट इंटरफेस स्वचालित रूप से प्रबंधित करता है (NetworkManager, systemd-networkd, dhcpcd) उसे किसी सेटअप की आवश्यकता नहीं होती: यह ब्रिज पर DHCP और SLAAC चलाता है और एकल IPv4 पता, IPv6 पता, एक्सेस पॉइंट का गेटवे और DNS प्राप्त करता है, बिल्कुल वैसे ही जैसे एक वायर्ड क्लाइंट करता।
कॉन्फ़िगर करने के लिए कोई डिवाइस-साइड पता या गेटवे नहीं है, क्योंकि पिको के पास कोई नहीं है।
इंटरफेस का MAC पता Wi-Fi स्टेशन का MAC है, और इसी प्रकार नेटवर्क को एक पहचान प्रस्तुत की जाती है।
यहाँ ip कमांड का आउटपुट परिणामी इंटरफेस दिखाता है: एक्सेस पॉइंट के अपने सबनेट पर एक साधारण DHCP/SLAAC क्लाइंट, स्टेशन के MAC के साथ और पिको का कोई निशान नहीं।
== मैनेजमेंट कंसोल
मैनेजमेंट कंसोल कॉन्फ़िगरेशन फ्रंट-एंड है, जो पहले CDC-ACM सीरियल फ़ंक्शन (आमतौर पर /dev/ttyACM0) पर होता है।
यह डिवाइस के एन्यूमरेट होते ही उपलब्ध होता है, Wi-Fi के एसोसिएट होने से पहले, इसलिए प्रोविज़निंग के लिए कभी नेटवर्क की आवश्यकता नहीं होती।
इसे picocom या screen जैसे सीरियल टर्मिनल से खोलें; USB CDC के लिए बॉड दर अप्रासंगिक है।
कंसोल इनपुट को प्रतिध्वनित करता है और एक प्रॉम्प्ट दिखाता है, और प्रत्येक कमांड पूर्ण डिवाइस स्थिति प्रिंट करता है।
Wi-Fi प्रमाणीकरण या तो WPA2-PSK या WPA3-SAE (AES) है।
पासवर्ड नेटवर्क का पासफ्रेज़ होता है, या पासवर्ड खाली छोड़ने पर ओपन होता है।
एक पासवर्ड-संरक्षित प्रोफ़ाइल WPA2/WPA3 ट्रांज़िशन मोड का उपयोग करती है, इसलिए यह किसी भी प्रकार के एक्सेस पॉइंट से जुड़ सकती है।
कंसोल आठ तक क्रेडेंशियल प्रोफ़ाइल संग्रहीत करता है; एक सक्रिय प्रोफ़ाइल होती है, और डिवाइस उसी से एसोसिएट होता है।
set ssid/set pass सक्रिय प्रोफ़ाइल को संपादित करते हैं, list/use/del सेट का प्रबंधन करते हैं, और scan आस-पास के नेटवर्क खोजता है और एक क्रमांकित सूची में से किसी एक से जुड़ता है -- तब उपयोगी जब किसी SSID में ऐसे अक्षर हों जिन्हें टाइप करना कठिन हो।
कमांड शब्द केस-असंवेदनशील होते हैं; कंसोल उन्हें लोअर केस में दिखाता है।
यहाँ का सत्र नेटवर्क को स्कैन करके प्रोविज़न करता है।
$ picocom /dev/ttyACM0
एक परिवर्तन तुरंत प्रभावी होता है, सक्रिय प्रोफ़ाइल के साथ पुनः-एसोसिएट करते हुए; रीबूट की आवश्यकता नहीं होती।
अधिक नेटवर्क सहेजने के लिए दोहराएँ; list उन्हें दिखाता है और use <n> सक्रिय नेटवर्क को बदलता है:
save हर प्रोफ़ाइल को फ्लैश में स्थायी रूप से सहेजता है; restore सहेजे गए रिकॉर्ड को पुनः लोड करके असहेजे गए संपादनों को त्याग देता है।
यहाँ की तालिका कमांड सेट को सूचीबद्ध करती है।
[#tbl-config-commands] .मैनेजमेंट-कंसोल कमांड [cols="2,3", options="header"] |=== |कमांड |प्रभाव
|set ssid <text>
|सक्रिय प्रोफ़ाइल का SSID सेट करें (मान में स्पेस हो सकते हैं) और पुनः-एसोसिएट करें; यदि कोई प्रोफ़ाइल मौजूद नहीं है तो पहली प्रोफ़ाइल बनाता है।
|set pass <text>
|सक्रिय प्रोफ़ाइल का WPA2/WPA3 पासफ्रेज़ सेट करें (ओपन नेटवर्क के लिए खाली) और पुनः-एसोसिएट करें।
|set country <CC\|WORLDWIDE>
|नियामक देश सेट करें (अगले बूट पर पूर्ण रूप से लागू होता है)।
|set debug <on\|off>
|डिबग कंसोल पर डायग्नोस्टिक्स स्ट्रीम करें; देखें <<debug-console,डिबग कंसोल>>।
|list
|सहेजी गई प्रोफ़ाइलें सूचीबद्ध करें, सक्रिय को चिह्नित करते हुए।
|use <n>
|प्रोफ़ाइल n को सक्रिय बनाएं और पुनः-एसोसिएट करें।
|del <n>
|प्रोफ़ाइल n हटाएं।
|scan
|आस-पास के नेटवर्क स्कैन करें और स्कैन सबमेनू में प्रवेश करें (back, join <n>, दोहराने के लिए scan, या निरंतर डिसएसोसिएटेड स्ट्रीम के लिए live)। join चुने गए नेटवर्क को सक्रिय प्रोफ़ाइल के रूप में स्टेज करता है, जो set pass के लिए तैयार होता है।
|save
|सभी प्रोफ़ाइल और सेटिंग्स को फ्लैश में स्थायी रूप से सहेजें।
|restore
|सहेजी गई सेटिंग्स को पुनः लोड करके असहेजे गए परिवर्तन त्यागें।
|===
होस्ट को आवंटित पता स्टेट डंप में host IPv4 और host IPv6 के रूप में दिखाया जाता है, जो ब्रिज किए गए ट्रैफ़िक से निष्क्रिय रूप से स्नूप किया जाता है, क्योंकि पिको के पास रिपोर्ट करने के लिए कोई पता नहीं होता।
कॉन्फ़िगरेशन सेक्टर फ्लैश के अंत में स्थित होता है, जो शुरुआत में प्रोग्राम इमेज से अलग होता है, इसलिए एक साधारण pico-usb-wifi.uf2 रीफ्लैश सहेजी गई प्रोफ़ाइल को बरकरार रखता है (पूर्ण-चिप इरेज़ उन्हें हटा देता है)।
अपवाद v1.1.0 में अपग्रेड करना है: रिकॉर्ड लेआउट कई प्रोफ़ाइल रखने के लिए बदल गया था, इसलिए पूर्व-1.1.0 रिकॉर्ड त्याग दिया जाता है और नेटवर्क को एक बार पुनः दर्ज करना पड़ता है (चेंजलॉग देखें)।
== डिबग कंसोल
डिबग कंसोल दूसरे CDC-ACM सीरियल फ़ंक्शन (आमतौर पर /dev/ttyACM1) पर एक केवल-लेखन डायग्नोस्टिक्स स्ट्रीम है।
जब तक मैनेजमेंट कंसोल पर set debug on जारी नहीं किया जाता, यह शांत रहता है, इसलिए बंद होने पर इसकी कोई लागत नहीं होती और यह प्रबंधन में कभी हस्तक्षेप नहीं करता।
सक्षम होने पर, यह एसोसिएशन परिवर्तनों और एक आवधिक ब्रिज-सांख्यिकी पंक्ति की रिपोर्ट करता है, जैसा यहाँ के सत्र में दिखता है।
एक -DTRACE_FRAMES=1 बिल्ड प्रत्येक ब्रिज किए गए फ्रेम का एक-पंक्ति सारांश जोड़ता है, लेकिन यह लोड के समय कंसोल को भर देता है, इसलिए यह डिफ़ॉल्ट रूप से बंद रहता है।
सांख्यिकी फ़ील्ड का वर्णन यहाँ की तालिका में किया गया है।
[#tbl-debug-stats] .डिबग सांख्यिकी फ़ील्ड [cols="1,3", options="header"] |=== |फ़ील्ड |अर्थ
|->wifi
|होस्ट से Wi-Fi तक अग्रेषित फ्रेम।
|->host
|Wi-Fi से होस्ट तक अग्रेषित फ्रेम।
|txdrop
|होस्ट-से-Wi-Fi फ्रेम इसलिए छोड़े गए क्योंकि स्टेशन अभी तक एसोसिएट नहीं था (होस्ट पुनः प्रयास करता है)।
|rxdrop
|Wi-Fi-से-होस्ट फ्रेम इसलिए छोड़े गए क्योंकि USB पक्ष पर्याप्त तेज़ी से ड्रेन नहीं कर सका।
|refl
|Wi-Fi-से-होस्ट फ्रेम इसलिए छोड़े गए क्योंकि वे होस्ट के स्वयं के ट्रांसमिशन थे, जो एक्सेस पॉइंट द्वारा परावर्तित हुए।
|poolfail
|होस्ट-से-Wi-Fi फ्रेम इसलिए छोड़े गए क्योंकि lwIP pbuf पूल क्षण भर के लिए समाप्त हो गया था।
|ringpk
|चरम Wi-Fi-से-होस्ट USB-TX कतार गहराई (32 में से) पिछली सांख्यिकी पंक्ति के बाद से, फिर रीसेट -- एक लाइव गेज, जहाँ 32 के निकट मान का अर्थ है कि USB उतनी तेज़ी से ड्रेन नहीं कर सकता जितनी तेज़ी से Wi-Fi पहुँचाता है। (सर्वकालिक अधिकतम के विपरीत, बर्स्ट गुजरते ही यह फिर से गिर जाता है।)
|link
|स्टेशन Wi-Fi लिंक स्थिति: up (एसोसिएटेड), join/down (एसोसिएट हो रहा है), या विफलता कारण -- badauth (गलत पासफ्रेज़), nonet (SSID नहीं मिला), fail।
|hangs
|पिछले कोल्ड पावर-ऑन के बाद से वॉचडॉग ने फर्मवेयर को हैंग से कितनी बार पुनर्प्राप्त किया है; देखें <<automatic-recovery,स्वचालित पुनर्प्राप्ति>>।
|faults
|पिछले कोल्ड पावर-ऑन के बाद से फर्मवेयर जिन हार्ड फॉल्ट से उबरा है।
|faultpc
|सबसे हालिया हार्ड फॉल्ट का पता (0x00000000 यदि कोई नहीं), addr2line के साथ मैपिंग के लिए।
|freeram
|बफ़र आकार ट्यून करते समय हेडरूम मापने के लिए बाइट्स में मुक्त RAM।
|===
प्रति-फ्रेम ट्रेसिंग ब्रिज किए गए ट्रैफ़िक के साथ USB फुल-स्पीड लिंक साझा करती है, इसलिए यह थ्रूपुट को घटाती है और कंसोल को भर देती है; यह एक बिल्ड-समय विकल्प (-DTRACE_FRAMES=1) है जो केवल गहन डिबगिंग के लिए है।
== स्वचालित पुनर्प्राप्ति
एक हार्डवेयर वॉचडॉग डिवाइस को रीबूट करता है यदि फर्मवेयर कभी अपने मुख्य लूप की सेवा बंद कर देता है - एक लॉकअप या ड्राइवर डेडलॉक - इसलिए यह अनप्लग करने की आवश्यकता के बजाय कुछ सेकंड के भीतर स्वयं पुनः एन्यूमरेट हो जाता है। एक अलग हार्ड-फॉल्ट हैंडलर CPU फॉल्ट को तुरंत पकड़ता है और फॉल्टिंग पता रिकॉर्ड करता है।
क्रैश से ठीक पहले के ब्रिज काउंटर अनइनिशियलाइज़्ड RAM में रीबूट से बचे रहते हैं।
पुनर्प्राप्ति पर डिवाइस उन काउंटरों के साथ डिबग कंसोल पर एक-पंक्ति RECOVERED from ... रिपोर्ट प्रिंट करता है (और हार्ड फॉल्ट के लिए फॉल्टिंग पता), और चालू stats: पंक्ति में hangs, faults और faultpc गणनाएँ होती हैं, इसलिए एक क्रैश डायग्नोस्टिक ट्रेस छोड़ जाता है भले ही उसने स्वयं को साफ़ कर लिया हो।
== ऑनबोर्ड LED स्थितियाँ
यहाँ की तालिका ऑनबोर्ड LED पैटर्न और उनके अर्थ सूचीबद्ध करती है।
[#tbl-led] .ऑनबोर्ड LED पैटर्न [cols="1,3", options="header"] |=== |पैटर्न |अर्थ
|स्थिर |एक्सेस पॉइंट से एसोसिएटेड - सामान्य चालू स्थिति।
|धीमी ब्लिंक - 1 Hz |Wi-Fi कॉन्फ़िगर किया गया, एसोसिएट हो रहा है या अभी तक एसोसिएट नहीं हुआ है।
|तेज़ ब्लिंक - 5 Hz |कोई Wi-Fi कॉन्फ़िगर नहीं; इसे मैनेजमेंट कंसोल पर प्रोविज़न करें।
|डबल फ्लैश - दो त्वरित पल्स, फिर एक विराम |लाइव (निरंतर) स्कैन चल रहा है; डिवाइस डिसएसोसिएटेड है और एक कुंजी दबाए जाने तक आस-पास के एक्सेस पॉइंट को मैनेजमेंट कंसोल पर स्ट्रीम कर रहा है।
|बंद |USB तैयार नहीं है। |===
== भविष्य का कार्य
ब्रिज RP2040 के नेटिव फुल-स्पीड USB (12 Mbit/s) पर चलता है, इसलिए थ्रूपुट लगभग 4-5 Mbit/s TCP पेलोड पर सीमित हो जाता है - डैशबोर्ड या कंट्रोल सरफेस के लिए पर्याप्त, लेकिन एक कठोर सीमा। बाधा USB लिंक है, Wi-Fi रेडियो नहीं। कुछ दिशाएँ जो इसे बढ़ा सकती हैं, प्रयास के मोटे क्रम में:
इनमें से कोई भी फर्मवेयर के इच्छित उपयोग के लिए आवश्यक नहीं है; ये किसी भी व्यक्ति के लिए शुरुआती बिंदु हैं जो अधिक थ्रूपुट चाहता है।
== अपस्ट्रीम लाइब्रेरीज़ और श्रेय
यह फर्मवेयर कई अपस्ट्रीम प्रोजेक्ट्स से मिलकर बना है, जिन्हें यहाँ की तालिका में दर्ज किया गया है।
[#tbl-upstream] .अपस्ट्रीम घटक [cols="1,2,1,4", options="header"] |=== |घटक (इन-ट्री फ़ाइलें) |अपस्ट्रीम |लाइसेंस |भूमिका
|USBNet |https://github.com/mattmyne/usbnet[mattmyne/usbnet] |MIT a|आधार USB-नेटवर्क मॉड्यूल, USB डिस्क्रिप्टर और मुख्य कंकाल, जिसे यहाँ Wi-Fi ब्रिज में विस्तारित किया गया है।
usb_network.c, usb_network.h - L2 ब्रिज के रूप में पुनः लिखा गयाusb_descriptors.c - कम्पोज़िट CDC-NCM + डुअल CDC-ACM शामिल करने के लिए संशोधितtusb_config.h - संशोधित|TinyUSB |https://github.com/hathach/tinyusb[hathach/tinyusb] |MIT a|USB CDC-NCM और CDC-ACM डिवाइस स्टैक, pico-sdk में बंडल किए अनुसार उपयोग किया गया। +
|pico-sdk 2.2.0 |https://github.com/raspberrypi/pico-sdk[raspberrypi/pico-sdk] |BSD-3-Clause a|बोर्ड समर्थन, बिल्ड सिस्टम और बंडल किए गए TinyUSB, lwIP और cyw43-driver।
pico_sdk_import.cmake - सटीक प्रतिlwipopts.h - छोटा किया गया pico_w उदाहरण|TinyUSB net_lwip_webserver उदाहरण
|Peter Lawrence और Ha Thach, https://github.com/hathach/tinyusb[hathach/tinyusb] के माध्यम से
|MIT
a|USB-नेटवर्क गोंद का मूल आधार; CDC-NCM पथ तक सीमित किया गया। +
|lrndis |https://github.com/fetisov/lrndis[fetisov/lrndis] |MIT a|USB-नेटवर्क दृष्टिकोण पर डिज़ाइन प्रभाव +
शेष स्रोत इस प्रोजेक्ट के मूल हैं:
main.cconfig.cconfig.hconfig_proto.cconfig_proto.hserial_console.cserial_console.hwifi_scan.cwifi_scan.hdebug_console.cdebug_console.h== लाइसेंस
यह प्रोजेक्ट MIT लाइसेंस के अंतर्गत है; देखें link:LICENSE[LICENSE]। अपस्ट्रीम घटक अपने स्वयं के लाइसेंस बनाए रखते हैं जैसा कि <<upstream-libraries-and-credits,अपस्ट्रीम लाइब्रेरीज़ एंड क्रेडिट्स>> में दर्ज है।
== आर्किटेक्चर
=== अवलोकन
डिवाइस एक USB CDC-NCM पेरिफेरल है जो होस्ट को Wi-Fi से ब्रिज करता है।
पिको W Wi-Fi स्टेशन चलाता है और USB लिंक और रेडियो के बीच ईथरनेट फ्रेम शटल करता है।
होस्ट अपना स्वयं का IP स्टैक चलाता है और एकमात्र नेटवर्क पहचान रखता है; पिको अपना कोई IP नहीं रखता।
होस्ट को बिल्ट-इन cdc_ncm और cdc_acm ड्राइवरों के अलावा कुछ भी आवश्यक नहीं है।
=== MAC अडॉप्शन के माध्यम से लेयर-2 ब्रिज क्यों
लक्ष्य यह है कि होस्ट Wi-Fi नेटवर्क पर एक पते वाले साधारण डिवाइस के रूप में दिखाई दे, जबकि पिको अदृश्य रहे। एक कठोर फिजिकल-लेयर बाधा यह निर्धारित करती है कि यह कैसे प्राप्त किया जाता है।
एक Wi-Fi स्टेशन कई MAC पतों को पारदर्शी रूप से ब्रिज नहीं कर सकता। जब Infineon CYW43 स्टेशन मोड में एक एक्सेस पॉइंट से एसोसिएट होता है, तो एसोसिएशन बिल्कुल एक MAC पता प्रदान करता है, और वह जो 802.11 डेटा फ्रेम भेजता है वे उसी स्टेशन MAC से बंधे होते हैं। चार-पते (WDS) फ्रेम के बिना, जिन्हें एक्सेस पॉइंट को भी समर्थन और अनुमति देनी होती है, रेडियो अपने पीछे मौजूद अन्य MAC पतों की ओर से फ्रेम नहीं ले जा सकता। यह सर्वविदित सीमा है कि एक Wi-Fi क्लाइंट को ब्रिज नहीं किया जा सकता।यह फ़र्मवेयर उस बाधा से लड़ता नहीं है; वह इसे हटा देता है। होस्ट के USB इंटरफ़ेस को Wi-Fi स्टेशन का MAC पता अपनाने के लिए कहा जाता है, इसलिए अंत-से-अंत तक ठीक एक MAC होता है। होस्ट और स्टेशन एक ही पहचान साझा करते हुए, Pico एक डंब लेयर-2 ब्रिज है: यह USB और Wi-Fi के बीच ईथरनेट फ्रेम को यथावत अग्रेषित करता है, लेयर 2 से ऊपर कुछ भी नहीं छूता। एक्सेस पॉइंट एक एकल, साधारण स्टेशन देखता है; होस्ट स्वयं DHCP, SLAAC, और Neighbor Discovery चलाता है और परिणामी पते अपने पास रखता है।
परिणाम यहाँ तालिका में सूचीबद्ध हैं।
[#tbl-bridge-effects] .MAC-अडॉप्शन ब्रिज के गुण [cols="1,3", options="header"] |=== |गुण |यह क्यों लागू रहता है
|एक IP, होस्ट के पास |Pico स्वयं को कोई पता निर्धारित नहीं करता, इसलिए एक ही पहचान होती है, एक्सेस पॉइंट के अपने सबनेट पर - कोई निजी टेदर सबनेट नहीं।
|IPv4 और IPv6 दोनों |अग्रेषण लेयर 2 पर होता है, इसलिए SLAAC, DHCPv6, राउटर विज्ञापन, और Neighbor Discovery बिना किसी संस्करण-विशिष्ट कोड के अपरिवर्तित गुज़रते हैं।
|कोई NAT और कोई पोर्ट-फ़ॉरवर्ड नहीं |कुछ भी पुनर्लेखित नहीं होता, इसलिए इनबाउंड कनेक्शन सीधे होस्ट तक पहुँचते हैं; नकली बनाने या मैप करने के लिए कुछ भी नहीं है।
|कोई होस्ट-साइड Wi-Fi स्टैक नहीं
|Pico के पास एसोसिएशन और सप्लिकेंट होता है, इसलिए होस्ट को wpa_supplicant, रेगुलेटरी डेटाबेस, या वायरलेस ड्राइवर की आवश्यकता नहीं होती - केवल CDC क्लास ड्राइवरों की।
|===
=== डेटा पथ
USB ओर, TinyUSB CDC-NCM डिवाइस प्रदान करता है, और होस्ट के इंटरफ़ेस MAC को स्टार्ट-अप पर स्टेशन MAC पर सेट किया जाता है (usb_network_set_host_mac, एन्यूमरेशन से पहले)।
होस्ट-से-Wi-Fi: एक फ्रेम tud_network_recv_cb के माध्यम से आता है, स्टेज किया जाता है, और मुख्य लूप में cyw43_send_ethernet के साथ रेडियो पर प्रेषित किया जाता है।
Wi-Fi-से-होस्ट: स्टेशन netif का input हैंडलर बदल दिया जाता है, इसलिए cyw43 ड्राइवर को प्राप्त हर फ्रेम lwIP के बजाय ब्रिज को सौंपा जाता है, कतारबद्ध किया जाता है, और tud_network_xmit के साथ होस्ट को प्रेषित किया जाता है।
USB ओर कोई lwIP IP इंटरफ़ेस मौजूद नहीं है, और स्टेशन netif कोई IP नहीं रखता; lwIP केवल cyw43 netif की लिंक स्थिति और pbuf पूल की सेवा करता है।
=== समवर्ती मॉडल
फ़र्मवेयर pico_cyw43_arch_lwip_threadsafe_background का उपयोग करता है।
Wi-Fi की सेवा एक बैकग्राउंड IRQ और async संदर्भ में होती है ताकि यह USB को कभी भूखा न रखे, जिसका tud_task() मुख्य लूप में चलता है।
इस व्यवस्था का ब्रिज के लिए एक सख्त परिणाम है।
TinyUSB को केवल मुख्य लूप से छुआ जाना चाहिए, फिर भी Wi-Fi फ्रेम बैकग्राउंड संदर्भ में प्राप्त होते हैं।
इसलिए Wi-Fi रिसीव हैंडलर प्रत्येक फ्रेम को केवल एक रिंग बफर में एनक्यू करता है, और मुख्य लूप उस रिंग को tud_network_xmit में खाली करता है।
इस नियम का उल्लंघन होस्ट-साइड पर NETDEV WATCHDOG: transmit queue timed out के रूप में प्रकट हुआ, और USB बाहर हो गया।
होस्ट फ्रेम को Wi-Fi पर भेजना मुख्य लूप में होता है और cyw43 कॉल के आस-पास cyw43_arch_lwip_begin()/cyw43_arch_lwip_end() धारण करता है।
=== मल्टीकास्ट और IPv6
एक स्टेशन, डिफ़ॉल्ट रूप से, केवल उन मल्टीकास्ट समूहों को प्राप्त करता है जिनसे वह जुड़ा है। ब्रिज अपना कोई IP स्टैक नहीं चलाता और किसी से नहीं जुड़ता, इसलिए हस्तक्षेप के बिना रेडियो उस मल्टीकास्ट को गिरा देगा जिस पर IPv6 निर्भर है, और होस्ट का IPv6 ब्रिज के माध्यम से काम नहीं करेगा। राउटर विज्ञापन, डुप्लीकेट-पता जाँच, और पता समाधान सभी मल्टीकास्ट पर चलते हैं।
प्रत्येक एसोसिएशन पर फ़र्मवेयर CYW43 allmulti iovar सेट करता है, इसलिए स्टेशन फ़िल्टर की परवाह किए बिना सभी मल्टीकास्ट फ्रेम वितरित करता है।
यह सार्वजनिक cyw43_ioctl के साथ WLC_SET_VAR के विरुद्ध किया जाता है, मॉनिटर मोड में प्रवेश करके नहीं, इसलिए ईथरनेट फ्रेम प्रारूप अपरिवर्तित रहता है।
IGMP- या MLD-snooping स्विच के पीछे का नेटवर्क कुछ मल्टीकास्ट को अभी भी काट सकता है जिसे होस्ट ने कभी अनुरोधित नहीं किया; एक फ्लैट होम एक्सेस पॉइंट उसे बाढ़ कर देता है।
=== सेल्फ-रिफ्लेक्शन फ़िल्टर
चूँकि होस्ट स्टेशन MAC साझा करता है, होस्ट द्वारा भेजा गया मल्टीकास्ट या ब्रॉडकास्ट एक्सेस पॉइंट द्वारा स्टेशन पर वापस बाढ़ कर दिया जाता है, जो अब सभी मल्टीकास्ट प्राप्त करता है, और उसे होस्ट को उसके अपने फ्रेम के रूप में वापस सौंप दिया जाएगा।
रिसीव हैंडलर किसी भी Wi-Fi-से-होस्ट फ्रेम को गिरा देता है जिसका स्रोत MAC स्टेशन MAC है, क्योंकि वह फ्रेम केवल एक्सेस पॉइंट द्वारा परावर्तित होस्ट का अपना ट्रांसमिशन हो सकता है।
एक ब्रिज को स्टेशन के फ्रेम वापस उसकी ओर प्रतिध्वनित नहीं करने चाहिए; गिरावट डीबग आँकड़ों में refl के रूप में गिनी जाती है।
=== दो सीरियल कंसोल
प्रबंधन और डायग्नोस्टिक्स आउट-ऑफ-बैंड हैं, उसी कम्पोज़िट USB डिवाइस के दो CDC-ACM फंक्शन पर, नेटवर्क पर नहीं। यह पारदर्शिता का एक जानबूझकर परिणाम है: नेटवर्क पक्ष केवल होस्ट का ट्रैफ़िक ले जाता है और Pico के पास जवाब देने के लिए कोई पता नहीं है।
प्रबंधन कंसोल (/dev/ttyACM0) कॉन्फ़िगरेशन लाइन प्रोटोकॉल चलाता है और USB एन्यूमरेट होते ही, Wi-Fi ऊपर आने से पहले ही पहुँच योग्य होता है, इसलिए डिवाइस बिना किसी IP के हमेशा प्रोविज़न योग्य रहता है।
डीबग कंसोल (/dev/ttyACM1) एक राइट-ओनली डायग्नोस्टिक्स स्ट्रीम है - एसोसिएशन ईवेंट, आवधिक ब्रिज काउंटर, और वैकल्पिक प्रति-फ्रेम पैकेट सारांश - केवल सक्षम होने पर उत्सर्जित होता है, इसलिए बंद होने पर इसकी कोई लागत नहीं होती और यह प्रबंधन कंसोल को कभी अव्यवस्थित नहीं करता।
कोई भी कंसोल नेटवर्क को नहीं छूता, इसलिए न तो कोई ऐसा ट्रैफ़िक उत्पन्न करता है जिसे होस्ट फ़ायरवॉल लॉग करता है।
=== कॉन्फ़िगरेशन संग्रहण
रनटाइम सेटिंग्स - आठ तक Wi-Fi क्रेडेंशियल प्रोफ़ाइल, सक्रिय-प्रोफ़ाइल इंडेक्स, रेगुलेटरी देश, और डीबग फ़्लैग - फ़्लैश के अंतिम सेक्टर में एक एकल रिकॉर्ड में रहती हैं, जो फ़्लैश की शुरुआत में प्रोग्राम इमेज से अलग होता है।
रिकॉर्ड कई फ़्लैश पृष्ठों में फैला होता है, इसलिए एक save पूरे सेक्टर को एक साथ प्रोग्राम करता है (मिटाना वैसे भी सेक्टर-व्यापी होता है)।
बूट पर रिकॉर्ड केवल उसके मैजिक नंबर और शेष struct पर CRC-32 के सटीक मिलान पर स्वीकार किया जाता है; कोई भी बेमेल संकलन-समय डिफ़ॉल्ट लोड करता है।
कोई संस्करणित माइग्रेशन नहीं है: रिकॉर्ड लेआउट में बदलाव केवल मैजिक/CRC जाँच में विफल हो जाता है और डिफ़ॉल्ट पर वापस आ जाता है, जो स्वीकार्य है क्योंकि एक अंतर्निहित संकलन-समय डिफ़ॉल्ट फिर भी पहली प्रोफ़ाइल को सीड करता है। (यही कारण है कि v1.1.0 में अपग्रेड करने पर, जिसने रिकॉर्ड को प्रोफ़ाइल सूची तक बढ़ा दिया, pre-1.1.0 रिकॉर्ड छोड़ दिया जाता है।)
एक save रिकॉर्ड को flash_safe_execute के माध्यम से वापस लिखता है, जो दूसरे कोर के साथ मिटाने और प्रोग्रामिंग का समन्वय करता है और इसमें लगने वाले कुछ मिलीसेकंड के लिए इंटरप्ट बंद कर देता है।
वह लिखना कंसोल हैंडलर से चलता है जबकि lwIP लॉक धारण किया जाता है; संक्षिप्त इंटरप्ट-अक्षम विंडो बैकग्राउंड Wi-Fi सर्विसिंग को रोक देती है, जो कि एक दुर्लभ, होस्ट-आरंभित सेव के लिए स्वीकार्य है।
=== हार्डवेयर और टूलचेन विचित्रताएँ
RP2040, Infineon CYW43, और pico-sdk के ये व्यवहार वास्तविक डीबगिंग समय लेते हैं और इन्हें दोबारा लाना आसान है।
==== बैकग्राउंड सर्विसिंग के लिए केवल-मुख्य-लूप TinyUSB आवश्यक है
यह <<concurrency-model,समवर्ती मॉडल>> में बताया गया समवर्ती नियम है। बैकग्राउंड सर्विसिंग के साथ, Wi-Fi रिसीव ऐसे संदर्भ में चलता है जो TinyUSB को कॉल नहीं कर सकता, यही कारण है कि विलंबित ट्रांसमिट रिंग मौजूद है।
==== एसोसिएशन एक IP नहीं है
cyw43 हेल्पर cyw43_tcpip_link_status केवल तभी CYW43_LINK_UP रिपोर्ट करता है जब स्टेशन के पास IP पता हो, और यह स्टेशन जानबूझकर कभी नहीं लेता।
इसलिए एसोसिएटेड स्थिति netif लिंक फ़्लैग (netif_is_link_up) से पढ़ी जाती है, जिसका उपयोग ब्रिज यह तय करने के लिए भी करता है कि अग्रेषित करना है या नहीं।
==== बदली हुई पहचान के लिए नए उत्पाद ID की आवश्यकता होती है
एक कम्पोज़िट डिवाइस जो अपना इंटरफ़ेस सेट बदलता है लेकिन समान USB विक्रेता और उत्पाद ID रखता है, उसे होस्ट द्वारा एक कैश्ड डिस्क्रिप्टर दिया जा सकता है।
उत्पाद ID सक्षम कक्षाओं से व्युत्पन्न होता है, इसलिए प्रत्येक CDC-ACM फंक्शन जोड़ने से वह बदल जाता है (cafe:4020 से cafe:4022) और होस्ट नया लेआउट फिर से पढ़ता है।
==== रिलीज़ बिल्ड assert को No-Op बनाते हैं
एक CMAKE_BUILD_TYPE=Release NDEBUG को परिभाषित करता है, जो assert() को कुछ भी नहीं में संकलित करता है, इसलिए केवल एक एसर्शन द्वारा संरक्षित आवंटन विफलता को पार कर जाता है और NULL को डीरेफ़रेंस करता है।
tud_task चलने से पहले फ़र्मवेयर क्रैश होस्ट-साइड पर USB एन्यूमरेशन त्रुटि -110, एक डिवाइस-डिस्क्रिप्टर रीड टाइमआउट के रूप में दिखाई देता है।
स्टार्ट-अप पथ पर एसर्शन के बजाय वास्तविक NULL गार्ड का उपयोग किया जाता है।
=== सत्यापित वातावरण
काम करने के लिए पुष्टि किया गया कॉन्फ़िगरेशन pico-sdk 2.2.0, arm-none-eabi GCC टूलचेन, और pico-sdk में बंडल किए गए TinyUSB और lwIP का उपयोग करता है, बिना संशोधन के।
संदर्भ बोर्ड Pico W (RP2040) है।
Pico 2 W (RP2350) के काम करने की उम्मीद है।
एक बिल्ड लगभग 670 KB का build/pico-usb-wifi.uf2 उत्पन्न करता है।