यह एक सवाल है जो मेरे पिताजी हमेशा मुझसे पूछते थे। " यह सभी निर्देशों के माध्यम से क्यों नहीं चलता है और अंत में बंद हो जाता है? "
आइए एक पैथोलॉजिकल उदाहरण पर एक नज़र डालें। 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); मुख्य के अंत में () इतना है कि सीपीयू कुछ भी ध्यान देने योग्य करना बंद कर देता है।
यदि एप्लिकेशन को सीपीयू को बिजली की आवश्यकता होती है, तो, सीपीयू के आधार पर, संभवतः विभिन्न नींद मोड उपलब्ध होंगे। हालांकि, सीपीयू को फिर से जागने की आदत है, इसलिए आपको यह सुनिश्चित करना होगा कि नींद के लिए कोई समय सीमा नहीं थी, और कोई वॉच डॉग टाइमर सक्रिय नहीं है, आदि।
आप कुछ बाहरी सर्किटरी भी व्यवस्थित कर सकते हैं जो सीपीयू को पूरी तरह से अपनी शक्ति को काटने की अनुमति देगा जब यह समाप्त हो गया था। यह प्रश्न देखें: लैगिंग ऑन-ऑफ टॉगल स्विच के रूप में एक क्षणिक धक्का बटन का उपयोग करना ।