क्या होता है जब माइक्रोकंट्रोलर रैम से बाहर निकलते हैं?


12

यह महज एक संयोग हो सकता है, लेकिन मैंने देखा है कि जब मैंने रैम को बाहर किया तो माइक्रोकंट्रोलर्स ने उनका उपयोग किया (यदि हार्डवेयर विशिष्ट हो तो Atmega 328)। यह है कि जब वे स्मृति से बाहर निकलते हैं तो माइक्रोकंट्रोलर क्या करते हैं? यदि नहीं, तो क्या होता है?

क्यों कैसे? स्टैक पॉइंटर निश्चित रूप से एक गैर-आवंटित मेमोरी रेंज (या लुढ़का हुआ) पर नेत्रहीन रूप से बढ़ जाता है, लेकिन फिर क्या होता है: क्या कुछ प्रकार की सुरक्षा है जो इसे रिबूट करती है या यह (अन्य प्रभावों के बीच) महत्वपूर्ण के ओवरराइटिंग का परिणाम है डेटा (जो मुझे लगता है कि कोड से अलग लगता है जो सीधे फ्लैश से चलाया जाता है)?

मुझे यकीन नहीं है कि यह यहां या स्टैक ओवरफ्लो पर होना चाहिए, कृपया मुझे बताएं कि क्या इसे स्थानांतरित किया जाना चाहिए, हालांकि मुझे पूरा यकीन है कि हार्डवेयर की इसमें भूमिका है।

अपडेट करें

मुझे यह इंगित करना चाहिए कि मैं स्मृति भ्रष्टाचार के पीछे वास्तविक तंत्र में विशेष रूप से दिलचस्पी रखता हूं (क्या यह सपा के रोल ओवर करने का परिणाम है -> क्या यह यूसी की मेमोरी मैपिंग आदि पर निर्भर करता है)?


8
यदि आप अमान्य पतों को एक्सेस करने का प्रयास करते हैं तो कुछ माइक्रो रीसेट कर देंगे। यह हार्डवेयर में लागू एक मूल्यवान विशेषता है। अन्य बार यह कहीं न कहीं मनमाने तरीके से कूद सकता है (जैसे कि आपने ISR के लिए रिटर्न एड्रेस को क्लोब किया है), शायद कोड के बजाय डेटा निष्पादित कर रहा है यदि आर्किटेक्चर अनुमति देता है, और शायद एक लूप में पकड़ा जा रहा है जो वॉचडॉग इसे बाहर लाता है का।
— स्परोहो पेफेनी

2
एक प्रोसेसर रैम से बाहर नहीं चल सकता है, कोई निर्देश नहीं है जो इसे रैम से बाहर चलाएगा। रैम से बाहर चलना पूरी तरह से एक सॉफ्टवेयर अवधारणा है।
— user253751

जवाबों:


14

सामान्य तौर पर स्टैक और हीप एक दूसरे में दुर्घटनाग्रस्त होते हैं। उस समय यह सब गड़बड़ हो जाता है।

MCU के आधार पर कई चीजें हो सकती हैं (या होंगी)।

  1. चर भ्रष्ट हो जाते हैं
  2. ढेर भ्रष्ट हो जाता है
  3. कार्यक्रम दूषित हो जाता है

जब 1 होता है तो आप अजीब व्यवहार करना शुरू कर देते हैं - चीजें जो वे नहीं कर रहे हैं उन्हें करना चाहिए। जब 2 होता है तो नरक के सभी तरीके ढीले हो जाते हैं। यदि स्टैक पर वापसी पता (यदि कोई है) दूषित है, तो वर्तमान कॉल वापस आ जाएगी, किसी का भी अनुमान है। उस समय मूल रूप से एमसीयू यादृच्छिक चीजें करना शुरू कर देगा। जब 3 फिर से होता है, तो कौन जानता है कि क्या होगा। यह केवल तब होता है जब आप RAM से कोड निष्पादित कर रहे होते हैं।

सामान्य तौर पर जब स्टैक दूषित हो जाता है तो यह सब खत्म हो जाता है। बस क्या होता है MCU नीचे।

यह हो सकता है कि पहली बार स्मृति को आवंटित करने का प्रयास विफल हो जाए ताकि भ्रष्टाचार न हो। इस मामले में MCU एक अपवाद बढ़ा सकता है। यदि कोई अपवाद हैंडलर स्थापित नहीं है, तो सबसे अधिक बार MCU बस रुकेगा (एक समतुल्य while (1);। यदि कोई हैंडलर स्थापित किया गया है, तो यह साफ रीबूट हो सकता है।

यदि स्मृति आबंटन आगे बढ़ता है, या यदि वह प्रयास करता है, विफल रहता है, और अभी कोई स्मृति आबंटित नहीं हुई है, तो आप "कौन जानता है?" के दायरे में हैं। MCU घटनाओं के सही संयोजन के माध्यम से स्वयं को रिबूट करने का अंत कर सकता है (इस वजह से अंत में चिप को रीसेट करना बंद हो जाता है, आदि), लेकिन ऐसा होने की कोई गारंटी नहीं है।

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


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

1
यह ज्यादातर उपयोग में संकलक और मानक सी लाइब्रेरी पर निर्भर है। यह कभी-कभी इस बात पर भी निर्भर करता है कि कंपाइलर कैसे कॉन्फ़िगर किया गया है (लिंकर स्क्रिप्ट आदि)।
— मजेंको

क्या आप उस पर विस्तार कर सकते हैं, शायद कुछ उदाहरणों के साथ?
— मिस्टर मिस्टेयर

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

12

एक वैकल्पिक दृश्य: माइक्रोकंट्रोलर मेमोरी से बाहर नहीं चलते हैं।

कम से कम, ठीक से प्रोग्राम किए जाने पर नहीं। एक माइक्रोकंट्रोलर की प्रोग्रामिंग बिल्कुल सामान्य उद्देश्य प्रोग्रामिंग की तरह नहीं है, इसे ठीक से करने के लिए आपको इसके बाधाओं और तदनुसार कार्यक्रम के बारे में पता होना चाहिए। यह सुनिश्चित करने के लिए उपकरण हैं। उन्हें खोजें और जानें - कम से कम लिंकर स्क्रिप्ट और चेतावनी को कैसे पढ़ें।

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

माइक्रोकंट्रोलर के लिए सामान्य प्रोग्रामिंग नियम इससे बचते हैं: उदाहरण के लिए, सभी मेमोरी या तो स्टैक पर आवंटित की जाती है या स्टैटिकली (विश्व स्तर पर) आवंटित की जाती है; "नया" या "मॉलॉक" निषिद्ध है। इसलिए पुनरावृत्ति है, ताकि उप-प्रकार के घोंसले की अधिकतम गहराई का विश्लेषण किया जा सके और उपलब्ध स्टैक में फिट किया जा सके।

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

तब माइक्रोकंट्रोलर मेमोरी से बाहर नहीं चला सकता है, लेकिन आपका प्रोग्राम हो सकता है। और उस मामले में, आप करने के लिए मिलता है

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

माइक्रोकंट्रोलर प्रोग्रामिंग के लिए नियमों का एक सामान्य सेट MISRA-C है , जिसे मोटर उद्योग द्वारा अपनाया गया है।

मेरे विचार में सबसे अच्छा अभ्यास SPARK-2014- Ada के सबसेट का उपयोग करना है । एडीए वास्तव में एवीआर, एमएसपी 430 और एआरएम कॉर्टेक्स जैसे छोटे नियंत्रकों को यथोचित रूप से लक्षित करता है, और स्वाभाविक रूप से सी की तुलना में माइक्रोकंट्रोलर प्रोग्रामिंग के लिए एक बेहतर मॉडल प्रदान करता है।

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

यद्यपि SPARK के साथ अधिक अप-फ्रंट कार्य शामिल है, अनुभव यह दिखा रहा है कि यह एक उत्पाद को तेज़ी से और सस्ता कर सकता है क्योंकि आप रहस्यमय रिबूट और अन्य अजीब व्यवहार का पीछा करते हुए समय नहीं बिताते हैं।

MISRA-C और SPARK की तुलना


3
+1 यह। AVR के लिए पोर्टिंग malloc()(और यह C ++ का साथी है new) सबसे खराब चीजों में से एक है जिसे arduino लोग कर सकते थे, और इसके कारण कई, बहुत सारे भ्रमित प्रोग्रामर अपने मंच पर टूटे हुए कोड के साथ, और arduino स्टैक एक्सचेंज। बहुत कम, बहुत कम परिस्थितियाँ होती हैं जहाँ mallocपर ATmega का सेवन फायदेमंद होता है।
— कॉनर वुल्फ

3
दर्शन के लिए +1, यथार्थवाद के लिए -1। यदि सामान ठीक से प्रोग्राम किया जाएगा, तो इस प्रश्न की आवश्यकता नहीं होगी। सवाल यह था कि क्या होता है जब माइक्रोकंट्रोलर मेमोरी से बाहर निकलते हैं। उन्हें स्मृति से बाहर जाने से कैसे रोका जाए यह एक और सवाल है। एक अन्य नोट पर, पुनरावृत्ति एक शक्तिशाली उपकरण है, दोनों समस्याओं को हल करने और स्टैक से बाहर निकलने के लिए।
— 13

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

2
@PkP: फिर ज़ोर से और स्पष्ट सुनो। मैंने इसे एक वैकल्पिक दृश्य लेबल किया - क्योंकि यह वास्तव में प्रश्न का उत्तर नहीं देता है!
— ब्रायन ड्रमंड

2
@ मिस्टर मिस्टेयर: माइक्रोकंट्रोलर आम तौर पर स्मृति से बाहर नहीं चलते हैं। एक माइक्रोकंट्रोलर जिसके पास 4096 बाइट्स रैम है जब यह पहली बार संचालित होता है तो इसमें 4096 बाइट्स हमेशा के लिए होंगे। यह संभव है कि कोड ग़लती से उन पतों को एक्सेस करने की कोशिश करे जो मौजूद नहीं हैं या उम्मीद करते हैं कि कंप्यूटिंग पतों की दो अलग-अलग विधियाँ अलग-अलग मेमोरी तक पहुँच जाएँगी जब वे नहीं करेंगे, लेकिन नियंत्रक स्वयं ही दिए गए निर्देशों को निष्पादित करेगा।
— सुपरकैट

6

मुझे वास्तव में माजेंको का जवाब पसंद है और मैंने इसे स्वयं ही +1 किया। लेकिन मैं इसे एक तीव्र बिंदु पर स्पष्ट करना चाहता हूं:

कुछ भी हो सकता है जब एक माइक्रोकंट्रोलर स्मृति से बाहर चलाता है।

जब ऐसा होता है तो आप वास्तव में किसी भी चीज पर भरोसा नहीं कर सकते। जब मशीन स्टैक मेमोरी से बाहर निकलती है, तो स्टैक सबसे भ्रष्ट हो जाता है। और जैसा कि होता है, कुछ भी हो सकता है। परिवर्तनीय मूल्य, फैल, अस्थायी रजिस्टर, सभी भ्रष्ट हो जाते हैं, कार्यक्रम प्रवाह बाधित हो जाता है। यदि / तो / elses गलत तरीके से मूल्यांकन कर सकते हैं। रिटर्न पतों को विकृत कर दिया जाता है, जिससे प्रोग्राम को रैंडम पतों पर लाया जाता है। प्रोग्राम में आपके द्वारा लिखा गया कोई भी कोड निष्पादित हो सकता है। (जैसे कोड पर विचार करें: "अगर [स्थिति] तो {fire_all_missiles ();}")। निर्देशों का एक पूरा गुच्छा जो आपने नहीं लिखा है, जब एक गैर-मेमोरी मेमोरी स्थान पर कोर कूदता है, तो निष्पादित कर सकता है। सभी दांव बंद हैं।


2
परिशिष्ट के लिए धन्यवाद, मुझे विशेष रूप से fire_all_missiles () लाइन पसंद है।
— मिस्टर मिस्टेयर

1

AVR ने वेक्टर को एड्रेस जीरो पर रीसेट कर दिया है। जब आप स्टैक को यादृच्छिक कचरे से अधिलेखित करते हैं, तो आप अंततः लूप करेंगे और कुछ रिटर्न एड्रेस को ओवरराइट कर देंगे और यह "कहीं नहीं" को इंगित करेगा; तब जब आप एक सबरूटीन से उस स्थान पर लौटते हैं, तो निष्पादन 0 के आसपास लूप करेगा जहां आमतौर पर हैंडलर को रीसेट करने के लिए एक कूद है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.