जब एक एम्बेडेड प्रोग्राम खत्म होता है तो क्या होता है?


29

एक एम्बेडेड प्रोसेसर में क्या होता है जब निष्पादन उस अंतिम returnविवरण तक पहुंचता है, क्या सब कुछ बस के रूप में फ्रीज होता है? बिजली की खपत आदि, आकाश में एक लंबे अनन्त एनओपी के साथ? या NOP लगातार निष्पादित होते हैं, या एक प्रोसेसर पूरी तरह से बंद हो जाएगा?

मेरे द्वारा पूछे जाने का एक कारण यह है कि क्या मैं सोच रहा हूं कि क्या किसी प्रोसेसर को निष्पादन समाप्त होने से पहले बिजली की आवश्यकता होती है और यदि यह हाथ से पहले नीचे चला गया है तो यह निष्पादन को कभी कैसे समाप्त करता है?


22
यह आपकी मान्यताओं पर निर्भर करता है। कुछ कहते हैं कि यह पुनर्जन्म लेगा।
तेलक्लेवो

9
क्या यह मिसाइल के लिए है?
ली कोवलकोव्स्की

6
कुछ प्रणालियाँ HCF (Halt and Catch Fire) निर्देश का समर्थन करती हैं । :)
स्टीफन पॉल नैक

1
यह आत्म विनाश की दिनचर्या को शाखा देगा

जवाबों:


41

यह एक सवाल है जो मेरे पिताजी हमेशा मुझसे पूछते थे। " यह सभी निर्देशों के माध्यम से क्यों नहीं चलता है और अंत में बंद हो जाता है? "

आइए एक पैथोलॉजिकल उदाहरण पर एक नज़र डालें। PIC18 के लिए माइक्रोचिप C18 कंपाइलर में निम्नलिखित कोड संकलित किया गया था:

void main(void)
{

}

यह निम्न कोडांतरक आउटपुट का उत्पादन करता है:

addr    opco     instruction
----    ----     -----------
0000    EF63     GOTO 0xc6
0002    F000     NOP
0004    0012     RETURN 0
.
. some instructions removed for brevity
.
00C6    EE15     LFSR 0x1, 0x500
00C8    F000     NOP
00CA    EE25     LFSR 0x2, 0x500
00CC    F000     NOP
.
. some instructions removed for brevity
.
00D6    EC72     CALL 0xe4, 0            // Call the initialisation code
00D8    F000     NOP                     //  
00DA    EC71     CALL 0xe2, 0            // Here we call main()
00DC    F000     NOP                     // 
00DE    D7FB     BRA 0xd6                // Jump back to address 00D6
.
. some instructions removed for brevity
.

00E2    0012     RETURN 0                // This is main()

00E4    0012     RETURN 0                // This is the initialisation code

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

अब, यह कहा जा रहा है, यह वह तरीका नहीं है जिससे लोग आमतौर पर चीजें करते हैं। मैंने कभी कोई एम्बेडेड कोड नहीं लिखा है जो मुख्य () को उस तरह से बाहर निकलने की अनुमति देगा। ज्यादातर, मेरा कोड कुछ इस तरह दिखेगा:

void main(void)
{
    while(1)
    {
        wait_timer();
        do_some_task();
    }    
}

इसलिए मैं आमतौर पर मुख्य () को बाहर निकलने नहीं देता।

"ठीक है ठीक है" आप कह रहे हैं। यह सब बहुत दिलचस्प है कि कंपाइलर सुनिश्चित करता है कि कभी भी अंतिम रिटर्न स्टेटमेंट न हो। लेकिन अगर हम इस मुद्दे को बल देते हैं तो क्या होगा? क्या होगा यदि मैं अपने कोडांतरक को कोड करूं, और शुरुआत में वापस छलांग न लगाऊं?

खैर, जाहिर है सीपीयू सिर्फ अगले निर्देशों को क्रियान्वित करता रहेगा। वे कुछ इस तरह दिखेंगे:

addr    opco     instruction
----    ----     -----------
00E6    FFFF     NOP
00E8    FFFF     NOP
00EA    FFFF     NOP
00EB    FFFF     NOP
.
. some instructions removed for brevity
.
7EE8    FFFF     NOP
7FFA    FFFF     NOP
7FFC    FFFF     NOP
7FFE    FFFF     NOP

मुख्य में अंतिम निर्देश () के बाद अगला मेमोरी एड्रेस खाली है। फ्लैश मेमोरी के साथ एक माइक्रोकंट्रोलर पर, एक खाली निर्देश में मान 0xFFFF होता है। PIC पर कम से कम, उस ऑप कोड की व्याख्या 'एनओपी', या 'ऑपरेशन नहीं' के रूप में की जाती है। यह बस कुछ नहीं करता है। CPU अंत तक उन नोड्स को सभी तरह से मेमोरी को निष्पादित करना जारी रखेगा।

उसके बाद क्या है?

अंतिम निर्देश पर, CPU का निर्देश सूचक 0x7FFe है। जब CPU अपने निर्देश सूचक में 2 जोड़ता है, तो इसे 0x8000 प्राप्त होता है, जिसे केवल 32k FLASH के साथ PIC पर एक अतिप्रवाह माना जाता है, और इसलिए यह लगभग 0x0000 पर वापस आ जाता है, और CPU खुशी से कोड की शुरुआत में निर्देशों को निष्पादित करना जारी रखता है। , जैसे कि यह रीसेट किया गया था।


आपने बिजली डाउन करने की आवश्यकता के बारे में भी पूछा। मूल रूप से आप जो चाहें कर सकते हैं, और यह आपके आवेदन पर निर्भर करता है।

यदि आपके पास एक ऐसा एप्लिकेशन है जो केवल बिजली के बाद एक काम करने के लिए आवश्यक है, और फिर कुछ नहीं करते हैं तो आप बस कुछ समय लगा सकते हैं (1); मुख्य के अंत में () इतना है कि सीपीयू कुछ भी ध्यान देने योग्य करना बंद कर देता है।

यदि एप्लिकेशन को सीपीयू को बिजली की आवश्यकता होती है, तो, सीपीयू के आधार पर, संभवतः विभिन्न नींद मोड उपलब्ध होंगे। हालांकि, सीपीयू को फिर से जागने की आदत है, इसलिए आपको यह सुनिश्चित करना होगा कि नींद के लिए कोई समय सीमा नहीं थी, और कोई वॉच डॉग टाइमर सक्रिय नहीं है, आदि।

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


20

संकलित कोड के लिए, यह संकलक पर निर्भर करता है। राउली क्रॉसवर्क्स एआरएम कंपाइलर जो कि मैं crt0.s फ़ाइल में कोड के लिए जंप का उपयोग करता है जिसमें एक लूप है। 16-बिट dsPIC और PIC24 उपकरणों के लिए माइक्रोचिप C30 संकलक (gcc पर आधारित) प्रोसेसर को रीसेट करता है।

बेशक, अधिकांश एम्बेडेड सॉफ़्टवेयर कभी भी उस तरह समाप्त नहीं होता है, और एक लूप में लगातार कोड निष्पादित करता है।


13

यहां दो बिंदु बनाए जाने हैं:

  • एक एम्बेडेड प्रोग्राम, सख्ती से बोलना, "खत्म" नहीं कर सकता।
  • कुछ समय के लिए एम्बेडेड प्रोग्राम चलाने की आवश्यकता बहुत कम होती है और फिर "खत्म" होती है।

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

सी या सी ++ जैसी भाषा में लिखे फर्मवेयर के मामले में, यदि मुख्य () निकास स्टार्टअप कोड द्वारा निर्धारित किया जाता है तो क्या होता है। उदाहरण के लिए, यहां STM32 स्टैंडर्ड पेरिफेरल लाइब्रेरी (जीएनयू टूलकिन के लिए, टिप्पणी मेरी है) से स्टार्टअप कोड का प्रासंगिक हिस्सा है:

Reset_Handler:  
  /*  ...  */
  bl  main    ; call main(), lr points to next instruction
  bx  lr      ; infinite loop

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

ध्यान दें कि ARMv7-M ARM A2.3.1 में निर्दिष्ट है, लिंक रजिस्टर को रीसेट पर 0xFFFFFFFF पर सेट किया गया है, और उस पते की एक शाखा एक गलती को ट्रिगर करेगी। तो कोर्टेक्स-एम के डिजाइनरों ने रीसेट हैंडलर से वापसी को असामान्य मानने का फैसला किया, और उनके साथ बहस करना मुश्किल है।

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


1
"आप स्लीप मोड्स से जाग्रत हो सकते हैं (यह है कि वे सामान्य रूप से कैसे उपयोग किए जाते हैं), और यहां तक ​​कि एक लॉकअप सीपीयू अभी भी एक एनएमआई हैंडलर को निष्पादित कर सकता है (यह कोर्टेक्स-एम के लिए मामला है)।" <- भयानक भाग की तरह लगता है एक किताब या फिल्म की साजिश। :)
मार्क एलन

निम्नलिखित निर्देश ("बीएक्स एलआर") के पते के साथ "ब्ल मुख्य" "एलआर" को लोड करेगा, क्या यह नहीं होगा? "Bx lr" निष्पादित होने पर "lr" के कुछ और होने की अपेक्षा करने का कोई कारण है?
सुपरकैट

@ सुपरकैट: आप बिल्कुल सही कह रहे हैं। मैंने त्रुटि को दूर करने और इसे थोड़ा विस्तारित करने के लिए अपने उत्तर को संपादित किया। इस पर विचार करते हुए, जिस तरह से वे इस लूप को लागू करते हैं वह बहुत अजीब है; वे आसानी से कर सकते थे loop: b loop। मुझे आश्चर्य है कि अगर वे वास्तव में एक वापसी करना चाहते थे, लेकिन बचाना भूल गए lr
कांटा

यह उत्सुक है। मुझे उम्मीद है कि बहुत से एआरएम कोड एलआर के साथ बाहर निकलेंगे जो प्रवेश पर उसी मूल्य को धारण करेंगे, लेकिन यह नहीं जानते कि इसकी गारंटी है। इस तरह की गारंटी अक्सर उपयोगी नहीं होगी, लेकिन इसे बनाए रखने के लिए रूटीन में एक निर्देश जोड़ने की आवश्यकता होगी जो r14 को किसी अन्य रजिस्टर में कॉपी करते हैं और फिर कुछ अन्य दिनचर्या को कॉल करते हैं। यदि रिटर्न पर lr को "अज्ञात" माना जाता है, तो कोई सहेजे गए प्रतिलिपि को पकड़े हुए रजिस्टर को "bx" कर सकता है। हालांकि, संकेतित कोड के साथ बहुत ही अजीब व्यवहार होगा।
सुपरकैट

वास्तव में मुझे पूरा यकीन है कि lr को बचाने के लिए गैर-पत्ती कार्यों की अपेक्षा की जाती है। ये आमतौर पर प्रोल में ढेर पर lr धक्का देते हैं और पीसी में सहेजे गए मान को पॉप करके वापस लौटते हैं। यह वह है जैसे कि C या C ++ मुख्य () क्या करेगा, लेकिन लाइब्रेरी के डेवलपर्स ने स्पष्ट रूप से Reset_Handler में ऐसा कुछ नहीं किया।
कांटा

9

के बारे में पूछने पर return, आप उच्च स्तर पर सोच रहे हैं। C कोड का अनुवाद मशीन कोड में किया जाता है। इसलिए, यदि आप इसके बजाय प्रोसेसर के बारे में सोचते हैं कि वह आँख बंद करके निर्देशों को याद से निकाल रहा है और उन्हें क्रियान्वित कर रहा है, तो इसका कोई पता नहीं है कि कौन सा "अंतिम" है return। इसलिए, प्रोसेसर का कोई अंतर्निहित अंत नहीं है, लेकिन इसके बजाय अंतिम मामले को संभालने के लिए प्रोग्रामर पर निर्भर है। जैसा कि लियोन अपने जवाब में बताते हैं, कंपाइलरों ने एक डिफ़ॉल्ट व्यवहार क्रमादेशित किया है, लेकिन कई बार प्रोग्रामर अपना स्वयं का शटडाउन अनुक्रम चाह सकते हैं (मैंने कम पावर मोड में प्रवेश करने और रुकने या यूएसबी केबल के प्लग लगाने के लिए इंतजार करने जैसे कई काम किए हैं। (और फिर रिबूटिंग)।

कई माइक्रोप्रोसेसर में रुकावट के निर्देश होते हैं, जो प्रोसेसर को पेरिफेरल को प्रभावित किए बिना रोक देता है। अन्य प्रोसेसर केवल एक ही पते पर बार-बार कूदकर "पड़ाव" पर भरोसा कर सकते हैं। विकल्प हो सकते हैं, लेकिन यह प्रोग्रामर पर निर्भर है, क्योंकि प्रोसेसर केवल मेयोरी से निर्देश पढ़ता रहेगा, भले ही वह मेमोरी निर्देश के लिए न हो।


7

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

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

व्यवहार में 3 दृष्टिकोण हैं:

  • कोई विशेष उपाय न करें। मुख्य रिटर्न अपरिभाषित होने पर क्या होता है।

  • एप्लिकेशन को पुनः आरंभ करने के लिए 0 पर जाएं या किसी अन्य माध्यम का उपयोग करें।

  • एक तंग लूप दर्ज करें (या एक रुकावट निर्देश को बाधित और निष्पादित करना), प्रोसेसर को हमेशा के लिए बंद करना।

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


5

मैं दूसरे दिन कुछ ATTiny45 असंतुष्ट (C ++ avr-gcc द्वारा संकलित) कोड को देख रहा था और कोड के अंत में यह क्या करता है यह 0x0000 पर कूद जाता है। मूल रूप से रीसेट / पुनरारंभ करना।

यदि कंपाइलर / असेंबलर द्वारा 0x0000 पर अंतिम छलांग लगाई जा रही है, तो प्रोग्राम मेमोरी में सभी बाइट्स को 'मान्य' मशीन कोड के रूप में व्याख्या किया जाता है और यह सभी तरह से चलता है जब तक कि प्रोग्राम काउंटर 0x0000 पर रोल नहीं करता।

AVR पर 00 बाइट (किसी सेल के खाली होने पर डिफॉल्ट वैल्यू) एक NOP = कोई ऑपरेशन नहीं है। तो यह वास्तव में जल्दी से चलता है, कुछ भी नहीं बल्कि बस कुछ समय ले रहा है।


1

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

लिंकर फिर सभी एप्लिकेशन और स्टार्टअप कोड को मेमोरी सेगमेंट में रखता है, इसलिए आपके प्रश्नों का उत्तर इस पर निर्भर करता है: 1. स्टार्टअप से कोड, क्योंकि यह उदाहरण के लिए हो सकता है:

  • खाली लूप ( bl lrया b .) के साथ समाप्त होता है , जो "प्रोग्राम एंड" के समान होगा, लेकिन पहले से सक्षम किए गए व्यवधान और परिधीय अभी भी संचालित होंगे,
  • कार्यक्रम की शुरुआत करने के लिए कूद के साथ अंत (या तो पूरी तरह से फिर से चलाने स्टार्टअप या jsut main)।
  • केवल mainरिटर्न के लिए कॉल के बाद "आगे क्या होगा" को अनदेखा करें ।

    1. तीसरी गोली में, जब प्रोग्राम काउंटर बस mainव्यवहार से लौटने के बाद वेतन वृद्धि आप (लिंकिंग के दौरान इस्तेमाल किया लिंकर और (या लिंकर स्क्रिप्ट) पर निर्भर करेगा।
  • यदि आपके फ़ंक्शन के बाद अन्य फ़ंक्शन / कोड को mainअमान्य / अपरिभाषित तर्क मानों के साथ निष्पादित किया जाएगा,

  • यदि निम्न स्मृति खराब निर्देश अपवाद के साथ शुरू होती है, तो अपवाद उत्पन्न होता है और MCU अंततः रीसेट हो जाएगा (यदि अपवाद रीसेट उत्पन्न करता है)।

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


-1

एम्बेडेड डिवाइस को रोकने का सबसे अच्छा तरीका एनओपी निर्देशों के साथ हमेशा के लिए प्रतीक्षा करना है।

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


वास्तव में इस सवाल का जवाब नहीं है।
मैट यंग

-4

यह मैनुअल में स्पष्ट रूप से समझाया गया था। आमतौर पर सीपीयू द्वारा एक सामान्य अपवाद को फेंक दिया जाएगा क्योंकि यह मेमोरी स्थान तक पहुंच जाएगा जो स्टैक सेगमेंट के बाहर है। [स्मृति सुरक्षा अपवाद]।

आपको एम्बेडेड सिस्टम से क्या मतलब था? माइक्रोप्रोसेसर या माइक्रोकंट्रोलर? किसी भी तरीके से, यह मैनुअल पर परिभाषित किया गया है।

X86 CPU में हम ACIP कंट्रोलर को कमांड भेजकर कंप्यूटर को बंद कर देते हैं। सिस्टम प्रबंधन मोड में प्रवेश करना। इसलिए कि नियंत्रक एक I / O चिप है और आपको इसे मैन्युअल रूप से बंद करने की आवश्यकता नहीं है।

अधिक जानकारी के लिए ACPI विनिर्देश पढ़ें।


3
-1: टीएस ने किसी भी विशिष्ट सीपीयू का उल्लेख नहीं किया है, इसलिए बहुत अधिक नहीं मानें। विभिन्न प्रणालियां इस मामले को बहुत अलग तरीके से संभालती हैं।
वाउटर वैन ऊइजेन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.