पहले कुछ पृष्ठभूमि ओवरराइट करें। जब भी किसी भी कारण से फर्मवेयर क्रैश हो जाता है (उदा। स्टैक ओवरफ़्लो, दूषित फ़ंक्शन पॉइंटर ...) ऐसा हो सकता है, यह कहीं कहीं कूदता है और कुछ कोड निष्पादित करना शुरू करता है। यह वॉचडॉग रीसेट में जल्द या बाद में परिणाम देगा। एमसीयू रीसेट हो जाएगा और हम ट्रैक पर वापस आ गए हैं। जब तक ...आकस्मिक फर्मवेयर से बचें
के बारे में क्या जब हम कोड है कि फ्लैश करने के लिए (उदाहरण के लिए बूटलोडर) लिखते है? अब ऐसा हो सकता है कि हम गलती से फ्लैश लिखित कोड में सीधे कूद जाएंगे - सभी चेक छोड़कर। वॉचडॉग छाल से पहले आप दूषित फर्मवेयर के साथ खत्म हो जाएगा। यह वही है जो मेरे साथ हो रहा था।
अब कुछ लोग कह सकते - जड़ बग के कारण होता है कि हम भी लिखने कोड में कूद ठीक। खैर, जब आप विकास कर रहे हैं तो आप लगातार कोड बदल रहे हैं। यहां तक कि अगर इस समय वहां कोई ऐसी बग नहीं है, तो कल भी हो सकता है। इसके अलावा, कोई कोड बग मुक्त नहीं है - या कम से कम मेरा नहीं।
तो अब मैं कुछ प्रकार की क्रॉस जांच कर रहा हूं। मेरे पास 'वेन' नामक एक चर है जो सामान्य चेक से पहले 0xa5 पर सेट होता है (उदाहरण के लिए यह सुनिश्चित करने के लिए जांचें कि गंतव्य मान्य है)। फिर वास्तविक मिटाने या लिखने से पहले मैं जांचता हूं कि 'वेन' वास्तव में 0xa5 पर सेट है या नहीं। अन्यथा इसका मतलब है कि हम किसी भी तरह गलती से लेखन कोड में कूद गए हैं। सफल लिखने के बाद 'वेन' साफ़ हो गया है। मैंने इसे सी में किया है और यह अच्छी तरह से काम किया है। लेकिन अभी भी मामूली सैद्धांतिक मौका भ्रष्टाचार होगा, क्योंकि एसपीएमसीआर रजिस्टर को लिखने तक 'वेन' की अंतिम जांच से कुछ निर्देश दिए गए हैं।
अब मैं विधानसभा में इस चेक डाल, लिखने SPMCR करने और एसपीएम अनुदेश के बीच से इस सुधार करना चाहते हैं।
__asm__ __volatile__
(
"lds __zero_reg__, %0\n\t"
"out %1, %2\n\t"
"ldi r25, %3\n\t"
"add __zero_reg__, r25\n\t"
"brne spm_fail\n\t"
"spm\n\t"
"rjmp spm_done\n\t"
"spm_fail: clr __zero_reg__\n\t"
"call __assert\n\t"
"spm_done:"
:
: "i" ((uint16_t)(&wen)),
"I" (_SFR_IO_ADDR(__SPM_REG)),
"r" ((uint8_t)(__BOOT_PAGE_ERASE)),
"M" ((uint8_t)(-ACK)),
"z" ((uint16_t)(adr))
: "r25"
);
अभी तक कोड की कोशिश नहीं की है, कल वह करेंगे। क्या आपको कोई समस्या है? आप इस तरह की समस्या कैसे हल करेंगे?
हां, सफल लेखन के बाद वेन साफ़ हो गया है। यह कॉल __assert को वास्तव में वॉचडॉग रीसेट ट्रिगर करता है (साथ ही यह ट्रिगर किए जाने के बारे में कुछ जानकारी लॉग करता है)। यह सुनकर खुशी हुई कि लोग वास्तव में ऐसे दृष्टिकोण का उपयोग करते हैं :) – Stefan