2012-02-16 24 views
5

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

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

अब कुछ लोग कह सकते - जड़ बग के कारण होता है कि हम भी लिखने कोड में कूद ठीक। खैर, जब आप विकास कर रहे हैं तो आप लगातार कोड बदल रहे हैं। यहां तक ​​कि अगर इस समय वहां कोई ऐसी बग नहीं है, तो कल भी हो सकता है। इसके अलावा, कोई कोड बग मुक्त नहीं है - या कम से कम मेरा नहीं।

तो अब मैं कुछ प्रकार की क्रॉस जांच कर रहा हूं। मेरे पास 'वेन' नामक एक चर है जो सामान्य चेक से पहले 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" 
); 

अभी तक कोड की कोशिश नहीं की है, कल वह करेंगे। क्या आपको कोई समस्या है? आप इस तरह की समस्या कैसे हल करेंगे?

उत्तर

3

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

आप सुनिश्चित करने के लिए दिए गए निर्देशों का सही ढंग से समझा जाता है अपने रीसेट करने से पहले कुछ NOPs की आवश्यकता हो सकती है।

यह सत्यापित करने की आपकी तकनीक कि शुरुआत से ही चल रहा है, एक अच्छा लगता है, यह मानते हुए कि आप लिखने के बाद wen चर को साफ़ करते हैं।

+0

हां, सफल लेखन के बाद वेन साफ़ हो गया है। यह कॉल __assert को वास्तव में वॉचडॉग रीसेट ट्रिगर करता है (साथ ही यह ट्रिगर किए जाने के बारे में कुछ जानकारी लॉग करता है)। यह सुनकर खुशी हुई कि लोग वास्तव में ऐसे दृष्टिकोण का उपयोग करते हैं :) – Stefan

2

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

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

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

+0

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

+0

@Stefan: अपने बूटलोडर को अपने एप्लिकेशन से अपडेट करने से सावधान रहें। मिटाने और लिखने के बीच बिजली के नुकसान पर क्या होता है? ओह, आपका बूटलोडर चला गया है और आपने अपना डिवाइस ब्रिकेट किया है। एक फ्रीस्केल एचसीएस08 प्रोजेक्ट, बूटलोडर वास्तव में सीपीयू रजिस्टरों को ओवरराइट होने से बचाने के लिए सेट करता है, और फ्लैश में उन पृष्ठों को एप्लिकेशन लिखना असंभव है। सुरक्षित रहना। – tomlogic

+0

@tomlogic: मेरे पास 2 लिखने के कोड हैं - एप्लिकेशंस और बूटलोडर में - और वे एक-दूसरे को अपडेट कर सकते हैं। डिफ़ॉल्ट रूप से यूसी आवेदन कोड में जागता है। अगर मैं बूटलोडर को अपडेट करने में असफल रहता हूं तो भी मैं एप्लिकेशन में जागता हूं और पुनः प्रयास कर सकता हूं। और बूटलोडर एक चाल का उपयोग करता है। यह एप्लिकेशन कोड को उच्चतम पृष्ठ से निम्नतम तक लिखता है। इससे पहले कि यह पहला (जो वास्तव में उच्चतम है) पृष्ठ लिखता है, यह पृष्ठ 0 में 'बूटलोडर पर कूद' लिखता है। अब केवल चिंता यह है कि यह अंतिम पृष्ठ (पृष्ठ 0) लिखने में विफल नहीं होना चाहिए। इसलिए गैर-पुनर्प्राप्ति योग्य फ़्लैश के साथ समाप्त होने की संभावना बहुत कम है। – Stefan