2 puan yazan GN⁺ 2024-11-12 | 1 yorum | WhatsApp'ta paylaş
  • Bir mikrodenetleyicide TCP/IP stack'ini doğrudan kurmanın ilk adımı olarak, STM32F401 Nucleo ile Wiznet W5100 shield bağlanarak Ethernet frame göndermesi denendi
  • W5100'ün donanımsal TCP/IP özelliği kullanılmadı; yalnızca MAC Raw modu kullanılarak, frame göndermek için gereken düşük seviyeli işlemler çipe bırakıldı
  • İlk engel, Arduino Ethernet shield'ın SPI kablolamasının Nucleo ile uyuşmamasından kaynaklandı; ICSP header yönlendirmesi doğrulandıktan sonra kart üzerinde yapılan düzeltme kablolamasıyla çözüldü
  • Ardından chip select zamanlamasıyla ilgili görünen MISO anormal yanıtları ve Wireshark'ta görünen çöp paketler yaşandı; logic analyser ve referans uygulama karşılaştırması temel hata ayıklama araçları hâline geldi
  • Nihai neden, w5100_write16() fonksiyonunun ikinci byte'ı aynı adrese yeniden yazmasına yol açan bir bug'dı; SPI capture CSV analiz aracı yazılması sayesinde düzgün paket göndermeye ulaşıldı

Doğrudan TCP/IP stack'i yazmak için başlangıç noktası

  • Amaç, bir mikrodenetleyici üzerinde TCP/IP stack'ini sıfırdan uygulayan “Networking from scratch” serisine başlamaktı
  • Bu aşamanın görünürdeki sonucu ilk Ethernet paketinin gönderilmesi olsa da asıl odak, donanım ile driver arasında ortaya çıkan bug'ı izleme sürecindeydi
  • Kullanılan kart, STM32F401 tabanlı Nucleo geliştirme kartıydı
    • ARM Cortex-M4
    • En fazla 84MHz çalışma
    • 96KiB RAM
    • Birkaç paketi tutmak için yeterli bellek olduğu değerlendirildi

Ethernet ve W5100'ün rolü

  • Ethernet yalnızca basit bir port veya frame biçimi değil; fiziksel katman donanımını, sinyal yöntemini, bus çakışması yönetimini ve frame yerleşimini de kapsayan bir teknoloji ve standartlar ailesidir
  • Ethernet sinyal işlemesi karmaşık olduğundan, genellikle özel bir ASIC frame düzeyindeki veriyi alır ve kablodaki elektriksel sinyal işlemesini üstlenir
  • Projede Wiznet W5100 çipli bir Arduino Ethernet shield kullanıldı
    • Kullanılan kart düşük maliyetli bir klon olduğundan, düzgün çalışması için modifikasyon gerekiyordu
  • W5100, Ethernet ASIC üzerine donanımsal TCP/IP stack yerleştirilmiş bir çiptir
    • 4 “socket” sunar
    • TCP, UDP, IP ve “MAC Raw” seviyesinde yapılandırılabilir
  • Doğrudan TCP/IP stack'i uygulama amacı nedeniyle W5100'ün TCP/IP özellikleri kullanılmadı; tek bir socket yalnızca MAC Raw modunda kullanıldı
    • Kullanıcı Ethernet frame'i verir
    • W5100 gerçek gönderimi yapar
    • Preamble ve start-of-frame marker elektriksel seviye unsurları olduğundan çip tarafından işlenir
    • 32-bit CRC'yi de W5100 hesaplar

Sorun 1: SPI sinyalinin W5100'e ulaşmaması

  • W5100 ile veri alışverişi SPI üzerinden yapılır
    • MOSI: ana çip olan mikrodenetleyicinin çıkışı
    • MISO: W5100 çıkışı
    • clock: veri için referans saat
    • chip select: bağımlı çiple iletişimde olunduğunu bildiren sinyal
  • W5100 datasheet'i, SPI üzerinde 4 byte'lık bir komut protokolü tanımlar
    • 1 byte operation
    • 2 byte 16-bit big-endian address
    • 1 byte value
  • operation, yazma için 0xf0 veya okuma için 0x0f değeridir
    • Diğer değerler geçerli değildir ve yok sayılmalıdır
  • W5100, her byte'ı clock out ederken MISO üzerinden bilinen bir değer döndürdüğü için iletişim sorunlarını kontrol etmek kolaydır
    • Okuma komutunda 4. byte, belirtilen adresten okunan değer olur
  • Başta MOSI üzerinden komut gönderildiğinde bile MISO'da çöp değerler görülüyordu
  • Neden, Arduino Ethernet shield'ın SPI sinyallerini Arduino standart header'ına değil ICSP 6-pin header'ına yönlendiren tasarımıydı
    • Resmî Arduino kartlarında ICSP ile standart header'daki SPI sinyalleri içeride bağlı olduğundan sorun yoktur
    • Nucleo kartında ICSP header bulunmadığından, gönderilen SPI sinyali W5100'e ulaşmıyordu
  • Bağlantı sorunu, multimetreyle güç rail'leri ile SPI sinyalleri arasındaki direnç ölçülerek doğrulandı
    • Sonsuz direnç görülmesi kablonun kopuk olduğunu gösterir
  • Lehim ve emaye kaplı bakır tel ile Nucleo ile W5100 arasındaki sinyaller doğrudan bağlandı

Sorun 2: chip select zamanlaması ve MISO anormal yanıtı

  • SPI sinyali gerçekten bağlandıktan sonra W5100 ile iletişim mümkün hâle geldi ve sonraki aşamalar uygulandı
    • W5100 raw Ethernet transmission ayarı
    • MAC address ayarı
    • TX/RX bellek segmenti ayarı
    • Test Ethernet frame'ini TX belleğine yazıp gönderimi tetikleme
  • Nucleo ve shield, CAT5 kabloyla dizüstü bilgisayara bağlanıp Wireshark çalıştırıldı, ancak paket görünmedi
  • Düşük seviyeli sorunlarda hata mesajı veya stack trace yoktur; “elektronları salladım ama beklediğim şey olmadı” biçiminde oldukları için izlemek zordur
  • Hata ayıklamada logic analyser kullanıldı
    • Birden fazla kanalda dijital sinyallerin high/low geçişlerini örnekler
    • SPI bus gibi sinyal gruplarını yazılım yorumlayarak transaction byte'larını gösterir
    • CSV gibi yapılandırılmış formatlarda dışa aktarabilir
  • Kullanılan cihaz Saleae Logic 8'di
    • Yaklaşık €10 seviyesindeki düşük maliyetli analyser'lar da Saleae Logic2 ile çalışabilir, ancak düzgün ve tutarlı çalışma konusunda tradeoff'lar vardır
  • İlk SPI komutu normal görünüyordu
    • 0xf0 0x00 0x00 0x80
    • 0x0000 adresindeki Mode Register'da en üst biti ayarlayarak software reset tetikler
    • MISO, 0x00'dan 0x03'e kadar normal yanıt verdi
  • Sonraki okuma komutunda anormal yanıt ortaya çıktı
    • MOSI: 0x0f 0x00 0x00 0x00
    • MISO: 0x03 0xff 0xff 0xff
  • 0x03 değerinin bir önceki transaction'ın son değeri olması, W5100'ün iç durumu veya zamanlamasıyla ilgili bir sorun olabileceğini düşündürdü
  • SPI clock, datasheet'teki yaklaşık 14MHz maksimum değerin çok altında kullanıldığı için neden olarak görülmedi
  • Bunun yerine chip select sinyalinin çok hızlı high'a geçtiği ve çipi kötü bir duruma soktuğu varsayıldı; durum değişiminden önce birkaç mikrosaniyelik gecikme eklendi
    • Sonrasında MISO yanıtları normale döndü
    • Ayar değerleri tekrar okunduğunda da makul değerler geldi
  • Bu sorunun kesin nedeni hâlâ tam olarak anlaşılmış değil
    • Datasheet'in 66. sayfasındaki SPI timing diagram'da yer alan chip select ile ilgili kısıtlar karşılanıyordu
    • Kesin sınır koşulları yeniden incelenebilir, ancak şimdilik projenin ilerlemesine öncelik veriliyor

Sorun 3: Wireshark'ta görünen çöp paket

  • Wireshark tekrar çalıştırıldığında paketler görünüyordu, ancak amaçlanan paket değildi
  • Mikrodenetleyici gönderim komutunu verdiği anda, asıl yerleştirilen veriden çok daha büyük bir raw Ethernet packet çöp verilerle dolu olarak göründü
  • Yalnızca datasheet ve spesifikasyona bakarak uygulama yapma planı bırakıldı; bu aşamada çalıştığı doğrulanmış bir uygulamayla karşılaştırma yapılmasına karar verildi
  • Arduino, hızlıca referans uygulama oluşturmak için kullanışlıdır
    • Arduino, kütüphane ve yaklaşık 5 satır kodla karmaşık davranışlar doğrulanabilir
  • raw Ethernet packet gönderme kütüphanesi bulmak daha uzun sürdü
    • Çoğu Arduino kullanıcısı ağ işlevlerini sıfırdan uygulamaya çalışmaz
    • Resmî kütüphane, public API'den raw packet gönderme desteğini kaldırmıştı
  • Asgari düzeyde packet gönderip almayı yapan GitHub projesi W5100MacRaw bulundu
  • Bu kaynak kod ile kendi uygulaması karşılaştırıldı, ancak hemen görünen farklar belirleyici değildi
    • register read/write sırası farklıydı
    • Yalnızca bir tarafta bulunan read/write işlemleri vardı
    • Genellikle sıra bağımlılığı varsa bunun datasheet'te belirtilmiş olacağı varsayılır
  • read/write sırası referans uygulamayla aynı hâle getirilse de Wireshark'ta hâlâ çöp paketler görünüyordu

Küçük bir araçla ortaya çıkan gerçek bug

  • Sonraki strateji, Saleae Logic2'nin SPI capture CSV çıktısını parse edip register read/write listesini yeniden gösteren bir araç yazmaktı
  • Araç Python ile yazıldı ve toplam uzunluğu 200 satırın biraz üzerindeydi
    • Çoğu, datasheet'ten kopyalanan register adları ve adresleriydi
    • Yazılması yaklaşık 1 saat sürdü
    • Girdi ve çıktıyı netleştirmek için argument parsing de eklendi
  • Arduino referans uygulamasından ve kendi uygulamasından ayrı ayrı SPI capture alınıp CSV olarak dışa aktarıldı; ardından araçla işlendi ve diff yapıldı
  • Sorun w5100_write16(u16 address, u16 value) yardımcı fonksiyonundaydı
    • W5100'deki birçok register 16-bit değerdir
    • Komut biçimi tek seferde yalnızca 8-bit yazabildiğinden high/low byte olarak bölüp yazmak gerekir
    • Bu fonksiyon ikinci byte'ı address + 1 adresine yazmak yerine aynı adrese yeniden yazıyordu
  • Arduino referans log'u S0_TX_WR0 ve S0_TX_WR1 register'larına ayrı ayrı yazmıştı
    • S0_TX_WR0 [0x0424] 0x00
    • S0_TX_WR1 [0x0425] 0x3c
  • Kendi log'unda ikisi de S0_TX_WR0 [0x0424] adresine yazılıyordu
    • S0_TX_WR0 [0x0424] 0x00
    • S0_TX_WR0 [0x0424] 0x3c
  • Bu register, Socket 0 transmit write pointer idi
    • W5100'ün bu 16-bit register'ı sırayla okuması
    • TX belleğine byte'ları yazması
    • Yeni write pointer'ı tekrar yazması
    • Ardından socket send command göndermesi beklenir
  • İkinci byte yazılmamışken send çalıştırılınca çip tanımsız ve anormal bir duruma girdi; Wireshark'ta rastgele sonuçlara benzeyen paketler göründü
  • Fonksiyon düzeltilince test paketi Wireshark'ta düzgün şekilde göründü

Hata ayıklama aracı yazmaya harcanan zamanın değeri

  • İlk Ethernet paketini göndermek tek başına devasa bir başarı değildir, ancak proje için net bir başarı anı olarak kabul edilebilir
  • Bug'ı geriye doğru izlemek kişisel projelerde keyiflidir; araç yazmaya ve hata ayıklama alanını keşfetmeye zaman ayırmak neredeyse her zaman değerlidir
  • Bazı profesyonel ortamlarda doğrudan deliverable üretmeyen işler israf olarak görülme eğilimindedir
    • Geliştirme süreci JIRA tarzı küçük parçalara bölündükçe, doğrudan checkbox doldurmayan işler düşük değerli sayılır
    • Sistem henüz yeterince anlaşılmamışken araç yazmak, test yazmak kadar, hatta bazen daha da önemli olabilir
  • Hata ayıklama, bilimsel yöntemin uygulanmasına yakındır
    • Veri toplanır
    • Tahmin oluşturulur
    • Tahmin deneyle doğrulanır
    • Yeni verilerle tahmin güncellenir
  • Bu proje bundan sonra daha yüksek soyutlama seviyesindeki sorunlara geçer
    • RFC yanlış anlamaları
    • multitasking code yazımı
    • Yeni bug'larla devam ediyor

1 yorum

 
GN⁺ 2024-11-12
Hacker News yorumları
  • Doğrudan küçük araçlar yapabilme becerisi bir süper güçtür ve çoğu zaman sıkça sözü edilen 10x programcının özünde yer alır.
    Ne yazık ki bu tür beceriler genellikle gözlerden uzak yerlerde sessizce sergilenir.

    • Ben de böyle bir durum yaşadım. Kuruluşların dişli çark gibi geliştiricilere de ihtiyacı var ve birçok kuruluşta işlerin gerçekten yürümesinin tek yolu da bu olabiliyor.
      Ama meraklı olan, ikincil etkileri ya da yakında gerekecek özellikleri düşünen biri için, bunu yapmayan geliştiricilerle çalışmak epey sancılı.
      Yakın zamanda birlikte çalıştığım kişi kötü biri değildi, ama şu anda biletin söylediği şeyi %100 uygulayan bir projeyi toparlıyorum. Mevcut yazılımdaki sorunları değiştirmesi beklenen yeni projede, aynı nedenlerle mevcut sorunların tamamı aynen kalmıştı.
      Yine de 10x geliştirici ifadesi biraz moda terim kokuyor. Çünkü aklıma, denetim olmadan “işi bitiren” gözü kara geliştiricilerin büyük maliyetler bırakması; her şeyin silo hâline gelmesi ve sonradan biri dokunduğunda ya da o kişi ayrıldığında iskambil kulesi gibi yıkılması geliyor.
    • Tersinden bakınca, Frank Ethernet paketleri gönderirken başkalarının tüm kuruluşun ihtiyaç duyduğu asıl işleri onun yerine halletmesi gerekiyor. Çözülmesi gereken gerçek sorunlardan oluşan neredeyse sonsuz bir backlog varken, “neden inovasyonu orada yapmıyorsunuz?” diye karşı çıkmak da mümkün.
      İdeal olarak herkese keşif zamanı verilmeli, ama üst yönetim “daha hızlı bitirmeliyiz” dediğinde bile bunu sıkı biçimde koruyacak bir yöneticiye ihtiyaç var. Başka bir ekibin yöneticisi “O ekip kaybolan zamanı telafi etmek için daha fazla kişi alabilecek mi? O insan gücüne bizim de ihtiyacımız var” derse iş daha da zorlaşıyor.
      Sonuçta kuruluş düzeyinde bir sisteme ihtiyaç var ve Google bile 20% zaman uygulamasından vazgeçti.
      “Etik olmayan” çözüm, geliştirme tahminlerine bu zamanı biraz dahil etmek.
    • 10x geliştiriciler genellikle bir yönetici ya da ürün sorumlusu tarafından belirlenmiş en yüksek önceliğe bağlı kişiler olmuyor. Bunun talimat almayı reddettiklerinden mi, kendileri yönetici olduklarından mı, yoksa baştan yöneticileri olmadığından mı kaynaklandığını bilmiyorum.
      Uygun durumlarda kendi aracını yapmak faydalıdır, ama üretken bir geliştiricinin en az kodu yazıp zaten var olanı kullandığı da söylenebilir. Bu yazıdaki örnekten gidersek, kimsenin doğrudan TCP stack’ini baştan yapmasına gerek yok; zaten harika uygulamalar var.
      Yine de doğrudan yapmak derin bir anlayış kazanmanın en iyi yolu olabilir ve derin anlayış, efsanevi 10x geliştiricinin bileşenlerinden biridir. Ancak işverenin bu süreç için para ödemesini beklemem.
    • Ben de iki uçtaki tepkilerin ikisini de yaşadım. “Vay, gerçekten faydalıymış. Bu araç modelimizi doğruladı” tepkisini de gördüm, “Önce PM’e sordunuz mu? Tavşan deliğine düşmemeye dikkat etmelisiniz” tepkisini de.
      Genelde bir gün içinde bitecek bir işse yaparım. Hiç yanlış çıkmadı, boşa da gitmedi. En kötü durumda daha sonra o kodu başka bir yere kopyalayıp yapıştırıyorum.
    • Son zamanlarda işte Python ve shell’i karıştırarak WSL’de çalışan küçük bir araç seti yaptım; müşterinin IoT sistemini debug ederken beni gören yöneticim oldukça etkilendi.
      Sonra programcı olmayanların da kullanabilmesini istemeye başladı ve bir anda o araçlar beklediğimden çok daha büyük bir işe dönüştü.
  • Başlık oldukça muğlak; bu yazı, mikrodenetleyiciler için TCP/IP ve Ethernet framing stack’ini sıfırdan yapma serisinin başlangıcı.
    Yazar TCP/IP’yi kendi işleyebilen W5100 çipini kullanıyor, ama önceden hazırlanmış Ethernet frame’leri vermeyi de destekliyor. Yine de preamble ve CRC hesaplamasını çip hallediyor.
    Yazının büyük kısmı çipin kendisiyle iletişim kurma ve test paketi gönderme sürecine dair. Hardcode edilmiş paket gibi görünüyor, ama yazıda açıkça belirtilmiyor.
    Kişisel olarak saçma denecek bir donanımda Ethernet’i bit banging ile yapan bir içerik olmasını ummuştum.

    • RP2040, yalnızca bir transceiver varsa Ethernet bit banging yapabiliyor; 100Mb/s de mümkün.
      Püf noktalarından biri, yaygın bir PHY + MagJack kartını değiştirip clock sinyalini RP2040’ın üretmesini sağlamak. Böylece sinyal senkronize oluyor ve RMII’yi aşırı örneklemeye gerek kalmıyor.
      Sadece 10Mb/s gerekiyorsa daha da kirli bir yöntemle de yapılabilir. RP2040’a DVI/HDMI görüntü çıkışı ve Ethernet’i birleştiren “modern” bir cam terminal çıkmasını hâlâ bekliyorum. Sadece telnet bile yeterli; SSH muhtemelen zor olur.
    • Eskiden biri bunu ATTiny85 ile yapmıştı: https://hackaday.com/2014/08/29/bit-banging-ethernet-on-an-a...
  • Yakın zamanda kariyerimi biraz sıra dışı biçimde Ethernet merkezli FPGA mühendisliğine kaydırdım.
    Eğlenceli bir yolculuktu ve sonunda doğrudan Hard MAC IP tasarlayıp özel PHY IP üzerinden paket göndermeye kadar gittim.
    Bu meydan okumayı “hard mode”da denemek isteyenlere kesinlikle tavsiye ederim. Ağ iletişimi kullanıcıdan o kadar soyutlanmış durumda ki, Ethernet kartlarının, modemlerin ve switch’lerin paketin her bölümünü nasıl birleştirip ayırdığını; PHY/PCS’nin link üzerindeki sinyali nasıl geri kazandığını anlamak gerçekten değerliydi.

    • Yaklaşık 10 yıl önce FPGA üzerinde doğrudan TCP işleyen bir projede yer aldım.
      Debug ve doğrulama için Verilator ile yapılmış simülasyon sürümünü Linux TUN/TAP aygıtına bağlayabilir hâle getirmiştik; böylece fiziksel donanımı meşgul etmeden doğrudan geliştirici makinesinden bağlanılabiliyordu. Tek bir donanım olduğu için özellikle kullanışlıydı.
    • Başlarken ağ iletişimine ya da Ethernet’e zaten aşina olup olmadığını merak ediyorum. Değilsen, genel resmi kavramak için hangi kaynakları kullandığını da bilmek isterim.
      Benim ağ bilgim OSI modeline dair çok temel bir anlayışla sınırlı, ama ağ dünyasını derinlemesine kurcalamak istiyorum.
  • MOSI/MISO’nun yeniden yorumlanmasını ilk kez gördüm. master out/slave in yerine main out/subordinate in denmesi.
    Böyle olunca pin adları hâlâ MOSI/MISO olarak kalabiliyor; ben de kullanırım gibi geliyor. COPI/CIPO (controller out/peripheral in) alternatifi akılda pek kalmamıştı.

  • Yazarın W5100 Ethernet shield’i ve STM32F401 kullanma nedeni bana tuhaf geldi. Benzer şekilde, kullanımı kolay bir STM32F407 kartı kullansa yerleşik Ethernet MAC’i olurdu ve ucuz bir Ethernet PHY kartıyla birlikte geliştirme yapabilirdi
    Örnek Ethernet projeleri de çok ve geliştirmesi STM32F401 kadar kolay
    Ayrıca “Ethernet sinyal işlemenin karmaşıklığı nedeniyle genelde özel ASIC kullanılır” açıklamasının mikrodenetleyici bağlamında çoğunlukla doğru olmadığını düşünüyorum. Çoğu durumda Ethernet işlevi, STM32F407 veya ESP32 gibi mikrodenetleyicilerin içinde yerleşik çevre birimi olarak bulunuyor

    • Yazar benim. Nedeni epey sönük: projeye başlamaya karar verdiğimde elimde olan parçalar bunlardı
      Yerleşik Ethernet çevre birimi olan bir çip kullanmak kesinlikle daha mantıklı. Yine de bu, W5100 yapılandırmasının karmaşıklığını ST çevre birimi yapılandırmasının karmaşıklığıyla takas etmek anlamına da geliyor
      Ağ kodu zaten gerçek çipi sürücü arayüzünün (read/write/ioctl benzeri) arkasında soyutladığı için port etmek oldukça kolay olacaktır
      Bu seride STM32F407’yi değerlendireceğim
    • Bazı insanlar için en güncel yöntemle yapmak yerine öğrenme sürecinin kendisi eğlencelidir
    • Bugün Ethernet’li ESP32 kartlarına baktığımda, çoğunun ya da epey büyük bir kısmının Ethernet’i seri aygıt gibi kullandığını gördüm
  • Ethernet paketlerle değil, frame’lerle ilgilenir
    Paket bir IP kavramıdır

    • IP’yi tanımlayan RFC 791 hem paketlerden hem de datagramlardan söz eder. IP datagram gönderir ve her IP datagramı, alttaki L2 ağına bağlı olarak bir veya daha fazla pakete parçalanır
      Ancak RFC 791, alttaki L2 ağının 128 baytlık paketler kullanan ARPAnet olma olasılığının yüksek olduğu dönemden kalma bir belgedir
      Günümüzde bu ayrımın fiilen anlamsız olması gerekir. Büyük bir IP datagramını birden çok L2 paketiyle göndermek için IP parçalamaya bel bağlıyorsanız bir şeyler yanlış demektir. IPv6 ağ içi parçalamayı bile desteklemez
      Pratikte zamanla ayrım neredeyse kayboldu. Çünkü genelde bir Ethernet frame’i bir IP datagramı taşır ve herkes buna kısaca paket der
    • Ancak HN’de olabilecek bir şey. Birisi ağ iletişimini sıfırdan uygulamış, yorumlarda ise tek bir terim yüzünden ne yaptığını bilmiyormuş gibi küçümseniyor
    • Ethernet’te paket fiziksel katman kavramıdır ve veri bağlantı katmanı kavramı olan frame’i kapsüller
      https://en.wikipedia.org/wiki/Ethernet_frame
    • Paket bir TCP kavramıdır; IP datagram gönderir
  • Mikrodenetleyicide kablolu Ethernet denemek istiyorsanız, daha büyük STM32 Nucleo kartlarından bazılarında 100 Mbps Ethernet yerleşik geliyor ve yaklaşık 25 dolar ile oldukça ucuzlar
    STM32Cube yazılımı hakkındaki değerlendirmeler karışık olsa da, çalışan Ethernet iletişimi örnekleri üretiyor
    https://www.st.com/en/evaluation-tools/nucleo-f439zi.html

    • ESP32 tabanlı bir şey istiyorsanız WT32-ETH01 Aliexpress’te yaklaşık 7 dolar. Kişisel olarak STM parçaları kadar, hatta onlardan daha kolay başlayabildim
      MQTT, HTTP istemcisi ve sunucusu vb. birlikte geliyor
      Cube-MX’i en son kullandığımda genel olarak çok tatsız bir deneyimdi. Yeniden STM32 kullanacak olsam stm32-hal veya libopencm3 tercih ederdim. Aracın kendisinde ve ürettiği kodda her türden kötü hata ve uç durum vardı; günlerce hata ayıklamak zorunda kaldım. Şimdi daha iyi olabilir
      https://github.com/egnor/wt32-eth01
    • Ethernet’li RISC-V ESP32-P4 kartının yaklaşık 20 dolar olması ilginç
      https://liliputing.com/waveshare-esp32-p4-nano-is-a-tiny-ris...
      Az önce daha ucuz modüllerin de olduğunu gördüm. WT32-ETH01 gibi şeyler performans olarak daha zayıf olabilir
    • STM32Cube çalışan Ethernet iletişimi örnekleri üretebiliyor, ama bazı donanımlarda bozuk
    • Neyse ki GitHub’da alternatif CMake projeleri epey var
    • STM32Cube’da belirgin bir “90’lar” hissi var
  • Linux’ta doğrudan kendi ağ yığınınızı yazmayı denemek istiyorsanız socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)) kullanarak bu yazıdan çok da farklı olmayan bir soyutlama düzeyinde çalışabilirsiniz
    SOCK_RAW paketleri, paket verisini değiştirmeden aygıt sürücüsüyle alıp verir. Alırken adres ayrıştırılır ve standart sockaddr_ll adres yapısı olarak iletilir
    Gönderirken kullanıcının sağladığı tamponda fiziksel katman başlığı bulunmalıdır ve o paket, hedef adresin belirttiği arayüzün ağ sürücüsü kuyruğuna değiştirilmeden girer
    https://man7.org/linux/man-pages/man7/packet.7.html

    • Ters yönden yapmak için tun(sanal IP) veya tap(sanal Ethernet) arayüzlerini kolayca açabilirsiniz
      Bunlar, VPN arayüzü gibi ağ yığınına sanal bir arayüz ekler. Paket soketleri ise tersine gerçek arayüzle doğrudan iletişim kurmanızı sağlar
  • Tam olarak Ethernet frame’i demek gerekir gibi geliyor

  • İyi yapılmış. Ben de az önce son 16 saatlik iş zamanımı bunun tersine harcadım: Ethernet II’yi (VLAN dahil), IPv4+6’yı ve UDP’yi otomotive yönelik IP protokolüne kadar ayrıştıran bir uygulama
    Kullanım amacı, özel mülk bir bus yakalama akışını anlamak; bu akış Ethernet frame’lerinin içine iç içe geçmiş Ethernet frame’leri vb. taşıyor ve ben bunları raw socket ile alıyorum
    Bu tür işler için Wireshark ve ChatGPT gerçekten paha biçilmez