अमान्य पिन नंबर का उपयोग करने पर क्या होगा?


9

संबंधित: रनटाइम त्रुटि होने पर क्या होता है?

यह सवाल ऊपर वाले के समान है, हालांकि यह एक वैकल्पिक स्थिति है:

int pin = 999;
pinMode(pin, OUTPUT);
digitalWrite(pin, HIGH);

इस उदाहरण में क्या होगा? संकलक इसे पकड़ सकता है लेकिन अगर आपने एक यादृच्छिक संख्या का उपयोग किया है तो आईडीई इसे पकड़ लेगा?

जवाबों:


9

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


आपके कोड में दूसरी पंक्ति वह जगह है जहाँ जादू होगा और जहाँ हमें ध्यान केंद्रित करने की ज़रूरत है।

pinMode(pin, OUTPUT);

के भाग pinModeइस चर्चा के लिए प्रासंगिक है:

void pinMode(uint8_t pin, uint8_t mode) 
{

    uint8_t bit = digitalPinToBitMask(pin); //The first instance where pin is used
    uint8_t port = digitalPinToPort(pin);

    if (port == NOT_A_PIN) return;

//Do something
}

(पूरा कार्यान्वयन wiring_digital.c में पाया जा सकता है )

तो, यहाँ, एक मध्यवर्ती बिट की गणना digitalPinToBitMaskकरने के लिए उपयोग pinकिया जा रहा है। आगे की खोज, digitalPinToBitMaskएक मैक्रो है Arduino.hजिसकी परिभाषा में यह एक-लाइनर है:

#define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) )

यह अजीब दिखने वाला एक लाइनर एक बहुत ही सरल कार्य करता है। यह सरणी में P th तत्व को अनुक्रमित करता है digital_pin_to_bit_mask_PGMऔर इसे लौटाता है। इस सरणी digital_pin_to_bit_mask_PGMको pins_arduino.hविशिष्ट बोर्ड के उपयोग के लिए या पिन मैप में परिभाषित किया गया है।

const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = {
    _BV(0), /* 0, port D */
    _BV(1),
    _BV(2),
    _BV(3),
    _BV(4),
    _BV(5),
    _BV(6),
    _BV(7),
...
};

इस सरणी में कुल 20 तत्व हैं, इसलिए हम भाग्य से बाहर हैं। 999 इस सरणी के बाहर फ्लैश मेमोरी में मेमोरी लोकेशन को इंडेक्स करेगा, जिससे अप्रत्याशित व्यवहार हो सकता है। या होगा?

अभी भी हमारे पास रनवे की अराजकता के खिलाफ रक्षा की एक और पंक्ति है। इसके कार्य की अगली पंक्ति pinMode:

uint8_t port = digitalPinToPort(pin);

digitalPinToPortहमें एक समान रास्ते पर ले जाता है। इसे मैक्रो के साथ-साथ परिभाषित किया गया है digitalPinToBitMask। इसकी परिभाषा है:

#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) )

अब, हम P वें तत्व को अनुक्रमित करते हैं , digital_pin_to_port_PGMजो पिन मैप में परिभाषित एक सरणी है:

const uint8_t PROGMEM digital_pin_to_port_PGM[] = {
    PD, /* 0 */
    PD,
    ....
    PC,
    PC,
};

इस सरणी में 20 तत्व हैं, इसलिए 999 फिर से सीमा से बाहर है। फिर से, यह कमांड पढ़ता है और फ्लैश मेमोरी से एक वैल्यू देता है जिसका मूल्य हम निश्चित नहीं कर सकते हैं। यह फिर से यहाँ से अप्रत्याशित व्यवहार को जन्म देगा।

अभी भी रक्षा की एक अंतिम पंक्ति है। यह वापसी मूल्य पर ifचेक pinModeहै digitalPinToPort:

if (port == NOT_A_PIN) return;

NOT_A_PINमें 0 के रूप में परिभाषित किया गया है Arduino.h। इसलिए, यदि लौटाया गया बाइट digitalPinToPortशून्य होता है, तो pinModeचुपचाप विफल हो जाएगा और वापस आ जाएगा।

किसी भी मामले में, pinModeहमें अराजकता से नहीं बचा सकता है। 999 को कयामत में परिणाम के लिए किस्मत में है।


टीएल; डीआर, कोड निष्पादित करेगा और इसका परिणाम अप्रत्याशित होगा। सबसे अधिक संभावना है, कोई पिन सेट नहीं किया जाएगा OUTPUT, और digitalWriteविफल हो जाएगा। यदि आपके पास असाधारण रूप से बुरी किस्मत है, तो एक यादृच्छिक पिन सेट हो सकता है OUTPUT, और digitalWriteइसे सेट कर सकता है HIGH


यह दिलचस्प है कि कोई सीमा जाँच नहीं है। digitalWrite वैसे भी बहुत धीमा और भारी है, इसे संकलित समय में चलाने या समय की जांच करने के लिए अजीब नहीं होगा।
साइबर्ग रिबन

यदि सभी arduino पिन एक सन्निहित सीमा में हैं, तो क्या वे पोर्ट == को पिन> BOARD_MAX_PIN चेक के साथ पिन चेक नहीं कर सकते, जहां बोर्ड मैक्स पिन कुछ डिफाइन फाइल पर आधारित है, जो बोर्ड का पता लगाता है?
अनंत काल 12

आप भूल रहे हैं कि 999 का प्रतिनिधित्व नहीं किया जा सकता है, uint8_tइसलिए इसे कोड कॉलिंग द्वारा पहले 231 में बदल दिया जाएगा pinMode। अंतिम परिणाम समान है: pinModeऔर digitalWriteअप्रत्याशित व्यवहार होगा और यदि आप उन्हें खराब पिन तर्क के साथ कॉल करते हैं तो स्मृति के यादृच्छिक भागों को बंद कर सकते हैं।
डेविड ग्रेसन

3

मानक पुस्तकालयों में, पिंस को बंदरगाहों में परिवर्तित करने के लिए डिज़ाइन किया गया है, जो विधानसभा में उपयोग किया जाता है। यहाँ वे Arduino 1.0.5 से Uno के लिए हैं:

#define digitalPinToPCICR(p)    (((p) >= 0 && (p) <= 21) ? (&PCICR) : ((uint8_t *)0))
#define digitalPinToPCICRbit(p) (((p) <= 7) ? 2 : (((p) <= 13) ? 0 : 1))
#define digitalPinToPCMSK(p)    (((p) <= 7) ? (&PCMSK2) : (((p) <= 13) ? (&PCMSK0) : (((p) <= 21) ? (&PCMSK1) : ((uint8_t *)0))))
#define digitalPinToPCMSKbit(p) (((p) <= 7) ? (p) : (((p) <= 13) ? ((p) - 8) : ((p) - 14)))

और भी हैं, लेकिन मैं उन्हें यहाँ नहीं दिखाऊँगा।

मेरा मानना ​​है कि आपका कार्यक्रम 14 को 999 से घटा देगा, जो अभी भी ब्रूग्राम के लिए बहुत बड़ा होगा। यह फिर digital_pn_to_bit_mask_PGMसरणी के 985 वें तत्व को इंगित करने की कोशिश करेगा , जिसमें केवल 20 तत्व शामिल हैं। यह सबसे अधिक संभावना है कि प्रोगेम में एक यादृच्छिक स्थान की ओर इशारा करके Arduino को खराब कर दिया जाएगा।

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