Sonunda bunu çözdüm, ancak oldukça alışılmadık bir şekilde. Güvenilmez bir şekilde bit-banging'i bıraktım ve daha fazla donanım eklemeden aynı şeyi yapmama izin verecek başka çözümler bulmaya çalıştım. GPIO'da bir kesmeyi tetikleyen ve ardından pimi SPI olacak şekilde yeniden yapılandıran ve tüm veri baytını okumak için SPI'yi kullanan bir çekirdek sürücüsü yazmayı düşünüyordum - ama sonra daha iyi bir fikrim var.
SPI'yi hatları 20 kat baud hızında örneklemek için kullanıyorum. SCLK ve SS pinlerini tamamen görmezden gelirim, RX hattını MISO'ya ve TX hattını MOSI'ye bağlayın. Bu bana RX hattında (1-bit) osiloskop benzeri bir görünüm kazandırıyor ve seri hatta iletilen bitleri açıkça görüyor:
00 00 00 00 00 00
00 00 00 00 01 FF
FF FF FF FF 00 00
01 FF FF FF FF FF
FF FF E0 00 00 00
00 00 07 FF FF FF
FF FF
Bundan, gerçek veri bitlerinin örnekleneceği doğru pozisyonları bulmak basit bir kodlama meselesidir. Gönderen taraf eşit derecede önemsizdir, sadece her bit'i başlangıç bit ve stop biti içeren uzun bir bit akışına dönüştürmem gerekiyor.
Bunun bit-çarpmadan daha iyi çalışmasının nedeni, SPI'nin çekirdekle donmayan kendi saatine sahip olması ve SPI gönderme ve alma hatlarının, çekirdek donmalarından bağımsız olan transfer için 16 baytlık bir FIFO'ya sahip olmasıdır. 9600 baud için 250kHz SPI saat kullanıyorum ve bu, FIFO'ları herhangi bir iletim hatası olmadan doldurma ve boşaltma arasında bir milisaniyede bile uyuyabileceğim anlamına geliyor. Ancak, güvenli tarafta hata yapmak için, 300 µs sleeps kullanıyorum. Bunu ne kadar zorlayabileceğimi kısaca test ettim ve en azından bir 2MHz SPI saati hala kullanılabiliyordu, bu yüzden bu çözüm de daha yüksek baud oranlarına ölçeklendiriyordu.
Bu çözümün çirkin bir parçası, çekirdek SPI sürücüsünün böyle bir akış bit aktarımını desteklememesidir. Bunun anlamı, çekirdek SPI sürücüsünü kullanarak kendi çekirdek modülümü yazarak yapamayacağım ve ayrıca kullanıcı ülkesinden /dev/sdidev0.0 kullanarak bunu yapamam. Bununla birlikte, Raspberry Pi'de SPI ve diğer çevre birimlerine, mmap (): n / dev / mem, kullanıcı kontrolünden tamamen çekirdeğin kontrolünü atlayarak doğrudan kullanıcı alanından erişilebilir. Bundan çok mutlu değilim, ancak mükemmel çalışıyor ve kullanıcı alanındaki segmentasyon hatalarının çekirdeğe zarar vermeyeceği (diğer çevre birimleriyle kazayla karışmadığı sürece) ek faydası var. CPU kullanımıyla ilgili olarak, 300 µs uyku sürekli bana yaklaşık% 7 CPU kullanımı veriyor gibi görünüyor, ancak kodum çok uygun değil. Uyku süresinin arttırılması açıkça CPU kullanımını doğrudan düşürür.
Düzenleme: Bahsetmeyi unuttum, güzel bcm2835 kütüphanesini SPI'yi kullanıcı alanından kontrol etmek için kullandım, gerektiğinde uzatarak.
Böylece, özetlemek gerekirse: Raspberry Pi'deki 250kHz'de / dev / mem üzerinden SPI yongasını kullanarak doğrudan kullanıcı alanından gelen 9600 baud seri bağlantı üzerinden güvenilir bir şekilde iletebilir ve alabilirim.
reliability
eyleme ve beklentilere bağlı olabilir.