2011-09-09 17 views
12

में स्ट्रक्चर इनोड और स्ट्रक्चर फ़ाइल का उपयोग कर डेटा पास करने का कारण मैं Linux Device Drivers, 3rd edition का अध्याय 3.5 का अध्ययन कर रहा हूं। इस अनुभाग में एक कस्टम संरचना हम खुले समारोह में struct inode *inode से खुद को परिभाषित पुनः प्राप्त करने के लिए एक विधि का परिचय:लिनक्स डिवाइस ड्राइवर प्रोग्रामिंग

int scull_open(struct inode *inode, struct file *filp) 
{ 
    struct scull_dev *dev; 

    dev = container_of(inode->i_cdev, struct scull_dev, cdev); 
    filp->private_data = dev; /* for other methods */ 

    } 
    return 0;   
} 

मेरी समझ से, जबकि डिवाइस खोला जाता है, struct inode *inode डिवाइस का प्रतिनिधित्व scull_open को पारित कर दिया है। फिर, कस्टम संरचना dev निकाला जाता है और filp->private_data में भेजा जाता है तो इस तरह के scull_read के रूप में है कि अन्य तरीकों के लिए इसका इस्तेमाल कर सकते हैं:

ssize_t scull_read(struct file *filp, char _ _user *buf, size_t count, 
       loff_t *f_pos) 
{ 
    struct scull_dev *dev = filp->private_data; 
    /* other codes that uses *dev */ 
} 

यह जब तक मुझे एहसास हुआ कि हम पहले से ही scull_setup_cdevhere में प्रारंभ के दौरान एक struct scull_dev *dev था मेरे लिए ठीक लग रहा है।

मैं नहीं बल्कि उलझन के बाद से मैंने सोचा था कि हम struct scull_dev *dev एक वैश्विक चर कर सकते हैं, तो scull_read और अन्य तरीकों अंततः सभी गुजर inode और file का उपयोग कर के माध्यम से जा के बिना यह करने के लिए उपयोग होगा हूँ।

मेरा सवाल है, हम इसे वैश्विक चर क्यों नहीं बनाते?

कोई भी डेटा पास करने के लिए इस विधि का उपयोग करने के कुछ व्यावहारिक उदाहरण प्रदान कर सकता है?

+4

देख सकते हैं इस प्रश्न/उत्तर में क्यों वैश्विक चर बुरा कर रहे हैं और जब वहाँ कोई अन्य रास्ता नहीं है, सिवाय इसके प्रयोग नहीं करना चाहिए आप के लिए एक सबक हो। –

+0

हाँ, लेकिन लेखक को पढ़ाने के दौरान यह बताने चाहिए कि विशेष कार्य का उपयोग क्यों और क्या है। – mrigendra

उत्तर

8

थ्रेड-सुरक्षा! क्या होगा यदि दो धागे/प्रक्रियाएं ड्राइवर का एक साथ उपयोग कर रही हैं?

+1

विभिन्न सिंगल-थ्रेडेड प्रक्रियाओं में भी धागे। (जो अधिकतर लोग नैतिक रूप से "धागे" के बजाए "प्रक्रियाओं" को बुलाएंगे।) –

+1

धन्यवाद, लेकिन मुझे अभी भी कुछ संदेह हैं। आइए मान लें कि मेरे पास एक सरल उपयोगकर्ता प्रोग्राम है (चलिए इसे 'open_device.c' कहते हैं)' ओपन() ',' read() ', 'write()', आदि जैसे सिस्टम कॉल के माध्यम से अपने ड्राइवर के साथ संवाद करने के लिए। यदि मैं' मुझे यकीन है कि एक ही समय में, मैं अपने ड्राइवर तक पहुंचने के लिए केवल ** एक ** 'open_device.c' का उपयोग करूंगा, क्या मुझे अभी भी थ्रेड सुरक्षा चिंता का ख्याल रखने की आवश्यकता है? क्या थ्रेड सुरक्षा समस्या तब होती है जब मैं अपने ड्राइवर तक पहुंचने के लिए ** ** ** ** ** ** ** _ open_device.c' का उपयोग कर रहा हूं? –

+1

संरचना का जीवनकाल क्या है, क्या यह सिस्टम कॉल के बीच जारी रहता है? यदि ऐसा होता है, तो यदि आप पहले बंद करने से पहले दूसरी फ़ाइल खोलते हैं तो आपका प्रोग्राम टूट जाएगा। –

0

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

ssize_t scull_read(struct file *filp, 
        char __user* buf, 
        size_t count, 
        loff_t * f_pos) { 

    int minor = MINOR(filp->f_dentry->d_inode->i_rdev); 
    printk("reading on minor number %d\n", minor); 
    /* use dev[minor] in ur code */ 
    return 0; 
} 
0

मुझे लगता है कि यह एक thead-सुरक्षा मुद्दा है donot: यह ऐसा ही कुछ हो जाएगा। यह एक डिजाइन पसंद की तरह है। अगर मुझे गलत नहीं लगता है, तो scull_dev में सेमफोर नीचे और ऊपर तक थ्रेड-सुरक्षा प्राप्त की जाती है। यदि आप कोड में खोदते हैं, तो आप खुले, पढ़ सकते हैं, सभी इस्तेमाल डाउन_इंटरप्टिबल() लिख सकते हैं।

मैं लेखक 1) का मानना ​​है कि तक पहुँचने scull_dev सीधे doesnot अच्छा 2 देखने) हमें बताएंगे कि कैसे private_data उपयोग करने के लिए करना चाहता है लगता है। बिंदु फ़ाइल को scull_dev में डालकर जिसका पॉइंटर प्रत्येक ऑपरेशन को भेजा जाता है, प्रत्येक ऑपरेशन वैश्विक चर का उपयोग किए बिना इसका उपयोग कर सकता है।

10

मुख्य कारण यह है कि आपका चालक एक से अधिक डिवाइस प्रबंधित कर सकता है। उदाहरण के लिए, आप (mknod) कई उपकरणों /dev/scull1, बना सकते हैं /dev/scull2, /dev/scull3 ... और फिर इनमें से प्रत्येक एक अलग scull_dev इसके साथ जुड़े होगा।

वैश्विक चर के साथ आप एक तक सीमित हैं। और यहां तक ​​कि यदि आपका चालक केवल एक ऐसे डिवाइस का समर्थन करता है, तो कोड भविष्य के सबूत को डिजाइन न करने का कोई कारण नहीं है।

0

खेना चालक 4 नाबालिगों, जिनमें से प्रत्येक एक अलग scull_dev है के साथ लागू किया जाता है, प्रत्येक scull_dev है "struct cdev" यह में एम्बेडेड। अब मान लें कि उपयोगकर्ता ने/dev/scull0 से scull0 खोला है। खुले() फ़ंक्शन में आपको सही scull_dev संरचना को इंगित करने की आवश्यकता है। Scull_dev संरचनाओं को गतिशील रूप से आवंटित किया जाता है।

पूर्ण कार्यान्वयन यहाँ https://github.com/mharsch/ldd3-samples/blob/master/scull/main.c#L450

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