2016-04-14 9 views
6

मैं कुछ यूजरस्पेस कोड बनाए रख रहा हूं जो एसपीआई के माध्यम से एफपीजीए से बात करते हैं। अभी यह देखने के लिए मतदान कर रहा है कि क्या कार्य करने के लिए डेटा है, जिसे मैं रोमांचित नहीं करता हूं। (भारी-सरलीकृत) कॉम धागे की संरचना इस तरह दिखता है:क्या मैं एक/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 का उपयोग किया जा सकता है? क्या यह हमेशा कुछ/मूर्खतापूर्ण "कभी पढ़ने के लिए तैयार" नहीं होगा? क्या यह बनाया जा सकता है जिस तरह से व्यवहार करने के लिए बनाया गया है? क्या यह हार्डवेयर निर्भर है? यदि आवश्यक हो तो मैं थोड़ा कर्नेल ड्राइवर हैकिंग के विपरीत नहीं हूं, लेकिन मुझे सच में यकीन नहीं है कि मुझे कहां दिखाना है।

+1

'चयन()' काम करना चाहिए। जैसे ही कर्नेल के बफर में एक बाइट तैयार होता है, डेटा पढ़ने के लिए तैयार होता है। हालांकि, मैं गारंटी नहीं दे सकता कि डिवाइस चालक के लेखक ने किसी भी कोने में कटौती नहीं की है। – fuz

+0

यदि चालक ध्वनि है तो 'चुनें()' काम करना चाहिए। जबकि आप इन मुद्दों से सावधान रहें, एक अच्छा समय होगा एक उपयुक्त परीक्षण लिखें - भले ही डिवाइस पर अब सब कुछ काम कर रहा हो, फिर भी आप परीक्षण के लिए आभारी होंगे यदि आप बाद में किसी डिवाइस या ड्राइवर के लिए निर्माण करने का प्रयास करते हैं जिस पर यह विफल रहता है। –

+1

* "मैं वास्तव में एक घटना-आधारित समाधान पसंद करूंगा" * - यदि एसपीआई चालक आपको मतदान करने के लिए मजबूर कर रहा है क्योंकि यह इंटरप्ट्स का उपयोग नहीं करता है, तो कोई जादुई दिनचर्या नहीं है जो स्थिति को बदल देगी।** का चयन करें() ** (जो *** उपयोगकर्ता-स्थान *** एसपीआई ड्राइवर के साथ काम नहीं कर सकता है) केवल आपके कोड से मतदान को स्थानांतरित करेगा, और एक libc कॉल के पीछे छिप जाएगा। यदि आप ईवेंट संचालित I/O चाहते हैं, तो आपको उस ड्राइवर का उपयोग/लिखना होगा जो उत्पन्न करता है और सेवाएं बाधित होती है। – sawdust

उत्तर

2

क्या मैं/dev/spidev फ़ाइल डिस्क्रिप्टर पर() चुन सकता हूं?

सं
spidev documentation राज्यों

At this time there is no async I/O support; everything is purely synchronous. 

इससे भी महत्वपूर्ण बात spidev driver एक सर्वेक्षण फ़ाइल आपरेशन का समर्थन नहीं करता। का चयन करें() syscall को डिवाइस ड्राइवर को पोल का समर्थन करने की आवश्यकता होती है।

670 static const struct file_operations spidev_fops = { 
671   .owner =  THIS_MODULE, 
672   /* REVISIT switch to aio primitives, so that userspace 
673   * gets more complete API coverage. It'll simplify things 
674   * too, except for the locking. 
675   */ 
676   .write =  spidev_write, 
677   .read =   spidev_read, 
678   .unlocked_ioctl = spidev_ioctl, 
679   .compat_ioctl = spidev_compat_ioctl, 
680   .open =   spidev_open, 
681   .release =  spidev_release, 
682   .llseek =  no_llseek, 
683 }; 
+1

यदि इसमें न तो एसिंक I/O समर्थन है और न ही डिवाइस को डेटा प्रदान करने के लिए तैयार होने तक ब्लॉक करने का कोई तरीका है, तो यह बहुत दुखद है। :( –

+0

@ डेविडस्वार्टज़ - स्पाइडव चालक का उत्पादन उत्पादन-गुणवत्ता वाला ड्राइवर नहीं था। यह एक उपयोगकर्ता-अंतरिक्ष क्लज है जो एसपीआई ड्राइवर मॉडल में प्रोटोकॉल ड्राइवर के तेज़ी से विकास और परीक्षण की अनुमति देता है। यदि एसपीआई दास डिवाइस को ध्यान देने की आवश्यकता है , आमतौर पर एक एचडब्ल्यू क्लज जैसे जीपीआईओ इंटरप्ट होता है। – sawdust

1

होने से पहले ही इस एक लिनक्स एसपीआई चालक सवाल हो सकता है, आप कैसे स्थिति की जानकारी FPGA से प्राप्त किया जा सकता को देखने के लिए की है।

जब तक एफपीजीए किसी इंटरप्ट या ध्यान रेखा को चलाने की तरह कुछ नहीं कर रहा है, तो एसपीआई मास्टर (संभावित रूप से सीपीयू से जुड़ा हुआ) को एफपीजीए के मतदान के लिए एसपीआई ऑपरेशन करना होगा। तो जब तक कि आपके पास कर्नेल स्पेस में कोड न हो, जो समय-समय पर मतदान करता है, उपयोगकर्ता के लिए अर्थपूर्ण रूप से चयन() पर ड्राइवर के भीतर कोई जानकारी उपलब्ध नहीं है।

तुम वापस प्रोसेसर के FPGA से एक ध्यान संकेत मिलता है कि एक बाधा के रूप में तो आप शायद की निगरानी कर सकता है (जो करता है, तो कुछ और यह साझा कर रहा है पर निर्भर करता है, बाहर के बदले MISO ड्राइविंग के रूप में सरल हो सकता है) या तो एक कर्नेल एसपीआई ड्राइवर में, या अलग-अलग उपयोगकर्ताओं द्वारा इंटरप्ट इंटरफ़ेस का उपयोग करके, जिसे आप चुन सकते हैं()।

यदि नहीं, तो आपको एसपीआई के माध्यम से एक कस्टम कर्नेल ड्राइवर में बनाम स्थिति के मतदान को स्थानांतरित करने के ट्रेडऑफ का मूल्यांकन करना होगा, बनाम इसे उपयोगकर्ताओं के स्थान पर छोड़कर।

संबंधित मुद्दे