Cuối cùng tôi đã giải quyết điều này, nhưng theo một cách khá không chính thống. Tôi đã từ bỏ bit-banging vì quá không đáng tin cậy và cố gắng tìm các giải pháp khác cho phép tôi làm điều tương tự mà không cần thêm phần cứng. Tôi đã xem xét việc viết trình điều khiển hạt nhân, điều này sẽ kích hoạt ngắt trên GPIO và sau đó cấu hình lại mã pin thành SPI và sử dụng SPI để đọc toàn bộ byte dữ liệu - nhưng sau đó tôi đã hiểu rõ hơn.
Tôi sử dụng SPI để lấy mẫu các dòng ở tốc độ bx 20 lần. Tôi hoàn toàn bỏ qua các chân SCLK và SS, kết nối đường dây RX với đường MISO và TX với MOSI. Điều này mang lại cho tôi chế độ xem giống như dao động (1 bit) trong dòng RX và thấy rõ các bit được truyền trong dòng nối tiếp:
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
Từ đó, việc mã hóa để tìm ra các vị trí chính xác để lấy mẫu các bit dữ liệu thực tế là một vấn đề đơn giản. Phía gửi cũng tầm thường không kém, tôi chỉ cần chuyển đổi từng byte thành một luồng bit dài với bit start và bit stop đi kèm.
Lý do điều này hoạt động tốt hơn so với đập bit là vì SPI có đồng hồ riêng không bị đóng băng với kernel và các dòng gửi và nhận SPI có FIFO 16 byte để chuyển cũng độc lập với đóng băng kernel. Đối với 9600 baud, tôi đang sử dụng đồng hồ SPI 250kHz và điều đó có nghĩa là tôi có thể ngủ thậm chí trong một phần nghìn giây giữa việc làm đầy và làm cạn kiệt các FIFO mà không có bất kỳ lỗi truyền nào. Tuy nhiên, để đảm bảo an toàn, tôi đang sử dụng 300 giấc ngủ. Tôi đã thử nghiệm ngắn gọn về việc tôi có thể đẩy mức này bao xa và ít nhất một đồng hồ SPI 2 MHz vẫn có thể sử dụng được để giải pháp này có tỷ lệ baud cao hơn.
Một phần xấu của giải pháp này là trình điều khiển SPI kernel không hỗ trợ truyền bit như vậy. Điều này có nghĩa là tôi không thể làm điều này bằng cách viết mô-đun hạt nhân của riêng mình bằng trình điều khiển SPI kernel và tôi cũng không thể làm điều đó bằng cách sử dụng /dev/sdidev0.0 từ vùng người dùng. Tuy nhiên, trên Raspberry Pi, SPI và các thiết bị ngoại vi khác có thể truy cập trực tiếp từ vùng người dùng bằng mmap (): n / dev / mem, bỏ qua toàn bộ điều khiển kernel. Tôi không hài lòng lắm với điều này, nhưng nó hoạt động hoàn hảo và nó mang lại lợi ích bổ sung rằng các lỗi phân đoạn trong vùng người dùng không thể làm hỏng kernel (trừ khi vô tình làm hỏng các thiết bị ngoại vi khác). Đối với việc sử dụng CPU, 300 giấc ngủ dường như cung cấp cho tôi khoảng 7% CPU sử dụng liên tục, nhưng mã của tôi rất không tối ưu. Tăng thời lượng ngủ rõ ràng làm giảm việc sử dụng CPU trực tiếp.
Chỉnh sửa: Quên đề cập đến, tôi đã sử dụng thư viện bcm2835 đẹp để kiểm soát SPI từ vùng người dùng, mở rộng nó khi cần thiết.
Vì vậy, để tóm tắt: Tôi có thể truyền và nhận một cách đáng tin cậy trên một liên kết nối tiếp 9600 baud hoàn toàn từ vùng người dùng bằng cách sử dụng trực tiếp chip SPI qua / dev / mem ở 250kHz trên Raspberry Pi.
reliabilitycó thể phụ thuộc vào hành động và kỳ vọng.