2009-11-12 7 views
13

तो एक एम्बेडेड सिस्टम इकाई में, कि मैं अगले वर्ष यूनी ले रहा हूं, हम सीखेंगे कि एक एम्बेडेड सिस्टम प्रोग्राम में गतिशील डेटा संरचनाएं एक बुरी चीज हैं। लेकिन व्याख्यान नोट्स क्यों नहीं जाते हैं।एम्बेडेड सिस्टम पर डायनामिक डेटास्टक्चर का उपयोग करना कितना बुरा है?

अब मैं एक मध्यम पैमाने पर, एम्बेडेड सिस्टम \ 'LURC' नियंत्रक पर काम कर रहा हूं, ज्यादातर एवीआर 169MEGA के लिए "तितली" डेमो बोर्ड के परिधीय के फायदे लेता है। ने contol servo और ESC को 4 पीडब्लूएम सिग्नल का उत्पादन किया। और 9 सीजी एलसीडी स्क्रीन भी प्रदान करने के लिए।

अब मैं निर्देशों को स्टोर करने के किसी भी प्रकार के बारे में नहीं सोच सकता क्योंकि उन्हें कतार की तुलना में शीश यूएसएआरएआर सीरियल प्राप्त होता है। उन चीजों के लिए esp जहां मुझे एक अज्ञात राशि प्राप्त होने तक प्रतीक्षा करने की आवश्यकता होगी: उदाहरण के लिए एलसीडी स्क्रीन पर प्रदर्शित करने के लिए एक स्ट्रिंग।

तो आप एक एम्बेडेड सिस्टम में माइक्रोकंट्रोलर पर गतिशील डेटा संरचनाओं का उपयोग क्यों नहीं करते? क्या यह सिर्फ इतना है कि आप भारी मेमोरी प्रतिबंधित वातावरण पर हैं, और यह सुनिश्चित करना होगा कि आपके मॉलॉक्स सफल हो रहे हैं?

+1

यह: http://www.nongnu.org/avr-libc/user-manual/malloc.html शांत अच्छा –

उत्तर

18

एम्बेडेड सिस्टम में मॉलोक (या समतुल्य) का उपयोग न करने के कई कारण हैं।

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

सबसे अच्छा - यदि आप गतिशील रूप से स्मृति आवंटित नहीं करते हैं तो आपको स्मृति रिसाव नहीं मिल सकता है।

+0

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

+1

"गतिशील रूप से आवंटित स्मृति सीपीयू स्टैक को आसानी से ओवरराइट कर सकती है।" - यह वास्तव में सच नहीं है। वास्तव में, यह * स्टैक * है जो प्रकृति द्वारा गतिशील है और अन्यथा आवंटित स्मृति को ओवरराइट करने के लिए बढ़ सकता है। गैर-स्टैक मेमोरी में गतिशील और स्थैतिक आवंटन के लिए एक ऊपरी बाउंड सेट होगा, लेकिन जब स्टैक उम्मीदों से परे बढ़ता है तो यह डेटा को ओवरराइट करता है, चाहे वह आवंटित या अन्यथा कोई फर्क नहीं पड़ता। गतिशील आवंटन का उपयोग करते समय ढेर अधिक खतरे में नहीं है। – JimmyB

0

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

4

ठीक है, कई छोटे माइक्रोकंट्रोलर के पास एमएमयू की तरह कुछ नहीं है, या आपके साथ काम करने के लिए एक अच्छा ढेर वाला ओएस नहीं है।

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

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

3

मेरी धारणा यह है कि एक एम्बेडेड सिस्टम पर, मुझे बिल्कुल पता है कि कितनी मेमोरी उपलब्ध है, और मुझे इसका बिल्कुल 100% उपयोग करने की अनुमति है; अन्य (समवर्ती रूप से चल रहे) कार्यक्रमों के लिए थोड़ा छोड़ने की कोई आवश्यकता नहीं है, लेकिन मुझे 101 वें प्रतिशत देने के लिए कोई वर्चुअल मेमोरी उपलब्ध नहीं है। तो एक कतार के लिए, मैं आसानी से calulate कर सकते हैं कि मेरे पास 981 रिकॉर्ड के लिए जगह है; इसलिए मैं उन रिकॉर्ड्स के लिए एक सरणी बना देता हूं और यदि मुझे कभी भी 982 वें रिकॉर्ड की आवश्यकता होती है, तो मुझे फंसाया जाता है और उसे शानदार तरीके से विफल होने का एक तरीका मिलना चाहिए।

+0

मेरा अधिकांश एम्बेडेड काम सरकारी नौकरियों पर रहा है, जहां 50% छोड़ने की नियमित आवश्यकता है भविष्य के उन्नयन के लिए अतिरिक्त। क्या वाणिज्यिक दुनिया ऐसा नहीं करती है? –

+0

टी.ई.डी. यह बुद्धिमान सलाह है कि मैंने आपको – bazz

0

एम्बेडेड सिस्टम पर गतिशील डेटा संरचनाएं सी ++ में पॉइंटर्स की तरह थोड़ी सी हैं। पॉइंटर्स (सी ++ में) बुराई हैं। लेकिन कभी-कभी वे एकमात्र विकल्प होते हैं; कभी-कभी वे कम बुराई होते हैं; और कभी-कभी उन्हें पूरी तरह से टालना ठीक है। ऐसे मामलों में जहां उनका उपयोग करने का एक अच्छा कारण है, ऐसा करने के लिए "अच्छे" तरीके और "खराब" तरीके हो सकते हैं।

स्थिर आवंटित चर और सरणी आवंटित करने और हटाने के लिए बहुत तेज हैं, और गतिशील रूप से आवंटित डेटा की तुलना में, पहुंचने के लिए तेज़ हो सकते हैं। this answer देखें।

गतिशील रूप से (जिसके द्वारा मेरा मतलब है malloc() एड या समान) आवंटित डेटा भी अंतरिक्ष ओवरहेड्स की आवश्यकता आवंटन का ट्रैक रखने के। कम से कम आवंटन के कई बाइट्स - यह स्थान एम्बेडेड सिस्टम पर बहुत मूल्यवान हो सकता है!

मेमोरी लीक बड़े पैमाने पर एम्बेडेड सिस्टम पर समस्या है, जिसे कभी-कभी वर्षों तक चलाने की उम्मीद की जा सकती है। गतिशील आवंटन से बचें इस परिप्रेक्ष्य से समझदार है।

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

4

यह पिछले 4 वर्षों में मेरे दृश्य में "एम्बेडेड" के अर्थ के रूप में निर्भर करता है।

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

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

जावा, सी ++, कई स्क्रिप्टिंग भाषाओं और अन्य भाषाओं सहित बफर ओवररन सुरक्षा और अपवाद हैंडिंग और अन्य उच्च स्तरीय भाषाओं सहित भाषाओं की एक विस्तृत श्रृंखला का उपयोग करने की क्षमता है। तो वास्तव में, उन पुरानी समस्याओं की तरह वे नहीं थे।

मुझे संदेह है कि यह सब नया उपलब्ध हार्डवेयर मुद्दों की एक नई श्रृंखला आता है।

+0

32 केबी रैम! आप भाग्यशाली थे। मेरे पास 1 केबी रैम है (हम सभी 26) जिसमें मुझे शीर्षक साझा करना है, वह सीपीयू स्टैक –

0

मैं Atmel MEGA169, लेकिन MEGA168 है, जो मुझे लगता है कि 169 से संबंधित है के बारे में पता नहीं है, SRAM का केवल 1024 बाइट है। इसमें केवल 16k प्रोग्राम रोम है, और आधुनिक कंप्यूटर की तुलना में अपेक्षाकृत धीमी है। तो यह स्मृति, कार्यक्रम के आकार और गति में सीमित है।

एवीआर असेंबलर प्रोग्रामिंग के साथ अपने अनुभव में, यह जितना संभव हो सके पीआईसी में उतनी कार्यक्षमता को क्रैक करने का प्रयास करता है। गतिशील डेटा संरचनाओं (अतिरिक्त मेमोरी उपयोग, एसआरएएम से डेटा खींचने और धक्का देने के लिए आवश्यक अतिरिक्त निर्देशों का उपयोग करने के लिए आवश्यक ओवरहेड की मात्रा, ट्रैक के बीच में चर 'जब हटाए जाते हैं, तब मेमोरी ब्लॉक को स्थानांतरित करते हुए, जहां गतिशील चर रहता है। ..) सिर्फ योग्यता को न्यायसंगत नहीं ठहराता है।

तो यदि संकलक इसे लागू करता है तो भी मैं प्रदर्शन के लिए स्थिर डेटा संरचनाओं के साथ चिपक जाता हूं।

+0

पीआईसी? ओपी एवीआर के बारे में पूछ रहा है। – iter

+0

मैं एवीआर के बारे में भी बात कर रहा था। मेरी गलती। – thomaspaulb

2

एक एम्बेडेड वातावरण में गतिशील स्मृति के साथ कुछ भी गलत नहीं है, हालांकि आम तौर पर यह आपको एम्बेडेड वातावरण में ज्यादा नहीं खरीदता है।

मेरी राय में रिंग-बफर का उपयोग करना एक बहुत अच्छा विचार है (यह I/O ड्राइवरों के लिए एक बहुत ही सामान्य डेटा संरचना है)। इस तरह यदि किसी कारण से आप अपनी कतार की सेवा करने में असमर्थ हैं, तो स्मृति उपयोग अभी भी निर्धारिती है।

कुछ मैक्रोज़ का उपयोग संकलन समय पर परिवर्तनीय आकार संरचनाओं को आवंटित करना संभव है।

उदाहरण के लिए -

//we exploit the fact that C doesn't check array indices to allow dynamic alloc of this struct 
    typedef struct ring_buf_t { 
     int element_sz, 
      buffer_sz, 
      head, 
      tail; 
     char data[0]; 
    } ring_buf_t; 

    #define RING_BUF_ALLOC_SZ(element_sz,n_elements) (sizeof (ring_buf_t) + \ 
                 (element_sz) * (n_elements)) 

    char backing_buf[RING_BUF_ALLOC_SZ (sizeof(type_to_buffer), 16)]; 

    //ring_buf_init() casts backing buf ring_buf_t and initialises members... 
    ring_buf_t *ring_buffer = ring_buf_init (element_sz, n_elemements, backing_buf); 

;

यह पैटर्न गारनेटेड स्मृति उपयोग के साथ एक गतिशील रूप से आकार देने योग्य बफर है। बेशक अन्य प्रकार के डेटा संरचनाओं (सूचियों, कतार आदि) को उसी तरह लागू किया जा सकता है।

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