2012-11-15 10 views
9

हमारे पास 3.2 कर्नेल का उपयोग करके एक एआरएम 9 है - सब ठीक काम करने लगता है। हाल ही में मुझे स्टार्टअप पर कुछ जीपीआईओ लाइनों पर 50 एमएमएस पल्स जोड़ने के लिए कुछ कोड जोड़ने के लिए कहा गया था। पल्स कोड ठीक है; मैं उम्मीद कर सकता हूं कि रेखाएं नीचे और ऊपर जा सकती हैं। जिस तरह से मैं उम्मीद करता हूं वह udelay() फ़ंक्शन नहीं है। दस्तावेज़ों को पढ़ना मुझे लगता है कि इकाइयां माइक्रोसॉन्ड में हैं, लेकिन तर्क विश्लेषक में मापा गया यह बहुत छोटा था। इसलिए मैंने अंततः 50 एमएमएस प्राप्त करने के लिए यह कोड जोड़ा।मैं कैसे साबित कर सकता हूं कि __udelay() मेरे एआरएम एम्बेडेड सिस्टम पर सही तरीके से काम कर रहा है?

// wait 50ms to be sure PCIE reset takes 
for (i=0;i<6100;i++) // measured on logic analyzer - seems wrong to me!! 
{ 
    __udelay(2000); // 2000 is max 
} 

मुझे यह पसंद नहीं है, लेकिन यह ठीक काम करता है। udelay कोड में कुछ अजीब स्थिरांक और निर्देश हैं। क्या कोई मुझे इस बारे में बता सकता है कि यह कैसे काम करना चाहिए? सभी घड़ियों को शुरू करने के बाद इस कोड को बुलाया जाता है, इसलिए बाकी सबकुछ ठीक लगता है।

उत्तर

4

this thread में लिनुस के अनुसार:

तो इसके बारे में 1% तक की छूट है, यह सब ठीक है। किसी देरी मूल्य कि इतने देरी में छोटी त्रुटियों के प्रति संवेदनशील है उठाया है कि वे कि महसूस करते हैं - या यहां तक ​​कि 5% की तरह कुछ नोटिस - तो वे एक देरी की भी कम चुना है।

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

तो ऐतिहासिक दृष्टि से, हम udelay देखा है() जा रहा है वास्तव में बंद (यानी 50% आदि बंद), मैं 1% रेंज में चीजों के बारे में चिंता नहीं करता।

लीनुस

तो यह एकदम सही होने के लिए नहीं जा रहा है। यह बंद होने जा रहा है। बहुत से कारकों पर कितना निर्भर है। for लूप का उपयोग करने के बजाय, mdelay का उपयोग करने पर विचार करें। यह थोड़ा और सटीक हो सकता है।

udelay कॉल केवल कम समय चूकों के लिए बुलाया जाना चाहिए क्योंकि loops_per_second की परिशुद्धता केवल आठ बिट है, और ध्यान देने योग्य त्रुटियों जमा जब बहुत ज़्यादा समय लग की गणना: O'Reilly Linux Device Drivers पुस्तक से। भले ही अधिकतम स्वीकार्य देरी लगभग एक सेकंड है (गणना लंबी देरी के लिए ओवरफ्लो के बाद), udelay के लिए सुझाए गए अधिकतम मूल्य 1000 माइक्रोसॉन्ड (एक मिलीसेकंड) है। फ़ंक्शन mdelay मामलों में सहायता करता है जहां देरी एक मिलीसेकंड से अधिक होनी चाहिए।

यह भी याद रखना कि udelay व्यस्त-प्रतीक्षा समारोह है (और इस प्रकार mdelay भी है) महत्वपूर्ण है; अन्य कार्यों को विलंब के दौरान नहीं चलाया जा सकता है।इसलिए आपको बहुत सावधान रहना चाहिए, खासकर mdelay, और इसका उपयोग करने से बचें जब तक कि आपके लक्ष्य को पूरा करने का कोई अन्य तरीका न हो।

वर्तमान में, कुछ माइक्रोसेकंड से अधिक देरी के लिए समर्थन और टाइमर टिक से कम बहुत अक्षम है। यह आमतौर पर समस्या नहीं है, क्योंकि देरी को मनुष्यों या हार्डवेयर द्वारा ध्यान देने योग्य होने की आवश्यकता होती है। एक सेकंड का सौवां हिस्सा मानव-संबंधित समय अंतराल के लिए सटीक है, जबकि एक मिलीसेकंड हार्डवेयर गतिविधियों के लिए पर्याप्त देरी है।

विशेष रूप से लाइन "udelay के लिए सुझाए गए अधिकतम मूल्य 1000 माइक्रोसेकंड (एक मिलीसेकंड) है" बाहर मुझ पर जब से तुम राज्य है कि 2000 अधिकतम है चिपक जाता है। this document डालने देरी पर से:

mdelay udelay आसपास मैक्रो आवरण, जब बड़े तर्क गुजर udelay को

तो यह संभव है कि आप एक अतिप्रवाह त्रुटि में चला रहे हैं संभव अतिप्रवाह के लिए खाते में करने के लिए है। हालांकि मैं आमतौर पर 2000 को "बड़ी बहस" नहीं मानता।

लेकिन अगर आपको अपने समय में वास्तविक सटीकता की आवश्यकता है, तो आपको अपने ऑफसेट से निपटने की ज़रूरत होगी, अपना खुद का रोल करें या एक अलग कर्नेल का उपयोग करें। असेंबलर का उपयोग करके अपने हार्ड विलंब फ़ंक्शन को रोल करने या हार्ड रीयल टाइम कर्नेल का उपयोग करने के बारे में जानकारी के लिए, इस आलेख को High-resolution timing पर देखें।

यह भी देखें: Linux Kernel: udelay() returns too early?

+0

आधुनिक कर्नेल hrtimer_nanosleep पर्याप्त पोर्टेबल होना चाहिए पर। – cdleonard

+0

@cdleonard 'nanosleep' शेड्यूलर मोड और देरी की लंबाई के आधार पर इसके व्यस्त पाश में 'udelay' का उपयोग कर सकता है। [उच्च-रिज़ॉल्यूशन समय] पर उपलब्ध लिंक देखें (http://tldp.org/HOWTO/IO-Port-Programming-4.html)। –

+0

@ embedded.kyle - वास्तव में आपके उत्तर की सराहना करते हैं, लेकिन मैं संतुष्ट नहीं हूं। mdelay सिर्फ लूप में udelay कहते हैं, तो यह कोई मदद नहीं है। और udelay राशि बंद है 1% या 50% के करीब कहीं नहीं - मैं 25 के लूप काउंटर की उम्मीद कर रहा था अगर सबकुछ सही काम करता है (2ms प्रत्येक लूप)। अगर यह 50% बंद था - मेरे लूप की तुलना में 50 होगा। लेकिन 6100? यह बहुत दूर है, यह मुझे बहुत परेशान करता है। फिर से धन्यवाद, लेकिन मैं अभी भी एक खोज पर हूं :) – Jeff

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

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