मैं कुछ यूजरस्पेस कोड बनाए रख रहा हूं जो एसपीआई के माध्यम से एफपीजीए से बात करते हैं। अभी यह देखने के लिए मतदान कर रहा है कि क्या कार्य करने के लिए डेटा है, जिसे मैं रोमांचित नहीं करता हूं। (भारी-सरलीकृत) कॉम धागे की संरचना इस तरह दिखता है:क्या मैं एक/dev/spidev फ़ाइल डिस्क्रिप्टर पर() चुन सकता हूं?
int spi_fd;
void do_transfer(char *buf, int len)
{
struct spi_ioc_transfer xfer;
memset(xfer, 0, sizeof(xfer));
ioctl_tell_some_fpga_register_heads_up();
xfer[0].len = len;
xfer[0].tx_buf = NULL;
xfer[0].rx_buf = buf;
ioctl(spi_fd, SPI_IOC_MESSAGE(1), xfer);
ioctl_tell_some_fpga_register_were_done();
}
void *comm_thread(void arg)
{
uint8_t config = SPI_MODE_3;
__u32 speed = 4000000;
char buffer[5120];
spi_fd = open("/dev/spidev1.0", O_RDWR);
ioctl(spi_fd, SPI_IOC_WR_MODE, &config);
ioctl(spi_fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
while(1) {
sleep(2); //ugh
if(ioctl_read_some_fpga_register_that_says_if_theres_data())
{
do_transfer(buffer, some_small_number_of_bytes());
do_stuff(buffer); //you get the picture
}
}
}
मैं वास्तव में चाहते पसंद करते हैं चुनाव और नींद से अधिक एक घटना के आधार पर समाधान। पहली बात यह है कि मन के लिए आया था की तरह
fd_set myset;
while(1) {
FD_ZERO(&myset);
FD_SET(spi_fd, &myset);
select(spi_fd + 1, &myset, NULL, NULL, NULL);
do_transfer(buffer, some_small_number_of_bytes());
do_stuff(buffer);
}
बात कुछ रजिस्टर हर एक्स सेकंड, कुछ की जाँच के बजाय spidev फ़ाइल वर्णनकर्ता पर (एक का चयन) कर रहा था मैं जैसे एसपीआई से निपटने के लोगों की किसी भी उदाहरण नहीं मिल सकता है वह, और मैं सोच रहा हूं कि शायद इसके लिए एक अच्छा कारण है। क्या इस तरह से/dev/spidev का उपयोग किया जा सकता है? क्या यह हमेशा कुछ/मूर्खतापूर्ण "कभी पढ़ने के लिए तैयार" नहीं होगा? क्या यह बनाया जा सकता है जिस तरह से व्यवहार करने के लिए बनाया गया है? क्या यह हार्डवेयर निर्भर है? यदि आवश्यक हो तो मैं थोड़ा कर्नेल ड्राइवर हैकिंग के विपरीत नहीं हूं, लेकिन मुझे सच में यकीन नहीं है कि मुझे कहां दिखाना है।
'चयन()' काम करना चाहिए। जैसे ही कर्नेल के बफर में एक बाइट तैयार होता है, डेटा पढ़ने के लिए तैयार होता है। हालांकि, मैं गारंटी नहीं दे सकता कि डिवाइस चालक के लेखक ने किसी भी कोने में कटौती नहीं की है। – fuz
यदि चालक ध्वनि है तो 'चुनें()' काम करना चाहिए। जबकि आप इन मुद्दों से सावधान रहें, एक अच्छा समय होगा एक उपयुक्त परीक्षण लिखें - भले ही डिवाइस पर अब सब कुछ काम कर रहा हो, फिर भी आप परीक्षण के लिए आभारी होंगे यदि आप बाद में किसी डिवाइस या ड्राइवर के लिए निर्माण करने का प्रयास करते हैं जिस पर यह विफल रहता है। –
* "मैं वास्तव में एक घटना-आधारित समाधान पसंद करूंगा" * - यदि एसपीआई चालक आपको मतदान करने के लिए मजबूर कर रहा है क्योंकि यह इंटरप्ट्स का उपयोग नहीं करता है, तो कोई जादुई दिनचर्या नहीं है जो स्थिति को बदल देगी।** का चयन करें() ** (जो *** उपयोगकर्ता-स्थान *** एसपीआई ड्राइवर के साथ काम नहीं कर सकता है) केवल आपके कोड से मतदान को स्थानांतरित करेगा, और एक libc कॉल के पीछे छिप जाएगा। यदि आप ईवेंट संचालित I/O चाहते हैं, तो आपको उस ड्राइवर का उपयोग/लिखना होगा जो उत्पन्न करता है और सेवाएं बाधित होती है। – sawdust