আমি যখন একটি অবৈধ পিন নম্বর ব্যবহার করব তখন কী হবে?


9

সম্পর্কিত: রানটাইম ত্রুটি হলে কী হবে?

এই প্রশ্নটি উপরের মত একই, তবে এটি একটি বিকল্প পরিস্থিতি:

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

এই উদাহরণস্বরূপ কি ঘটবে? সংকলকটি এটি ধরতে পারে তবে আপনি যদি একটি এলোমেলো নম্বর ব্যবহার করেন তবে আইডিই তা ধরতে পারে?

উত্তর:


9

সংকলকটি কোনও ত্রুটি সনাক্ত করবে না এবং কোডটি সংকলন এবং সম্পাদন করবে। সুতরাং, কী ঘটেছিল তা দেখার জন্য আমাদের নেপথ্যে পর্দার যাদুটি অন্বেষণ করতে হবে। একটি সংক্ষিপ্তসার জন্য, শেষ এড়িয়ে যান।


আপনার কোডের দ্বিতীয় লাইনটি হল যেখানে যাদুটি ঘটবে এবং সেখানে আমাদের ফোকাস করা দরকার ts

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
}

(সম্পূর্ণ বাস্তবায়ন তারের_ডিজিটালসি-তে পাওয়া যাবে )

সুতরাং, এখানে, digitalPinToBitMaskমনে হয় pinএকটি মধ্যবর্তী বিট গণনা করতে ব্যবহার করা হয়। আরও অন্বেষণ, digitalPinToBitMaskএকটি ম্যাক্রো সংজ্ঞায়িত করা হয়েছে Arduino.hযার সংজ্ঞা এই ওয়ান-লাইনার:

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

এই অদ্ভুত সন্ধানকারী এক লাইনার একটি খুব সাধারণ কাজ করে। এটি অ্যারেতে পি থিম উপাদানকে সূচক করে 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) ) )

এখন, আমরা পি থিম উপাদানটি সূচক করি digital_pin_to_port_PGMযার পিন মানচিত্রে একটি অ্যারে সংজ্ঞায়িত করা হয়:

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

এই অ্যারেতে 20 টি উপাদান রয়েছে তাই 999 আবার সীমার বাইরে। আবার, এই আদেশটি ফ্ল্যাশ মেমরির কাছ থেকে যার মান আমরা নিশ্চিত হতে পারি না তার একটি মান পড়ে এবং ফিরিয়ে দেয়। এটি আবার এখান থেকে অবিশ্বাস্য আচরণের দিকে পরিচালিত করবে।

প্রতিরক্ষা একটি শেষ লাইন এখনও আছে। এটির রিটার্ন মূল্যের ifচেক ইন :pinModedigitalPinToPort

if (port == NOT_A_PIN) return;

NOT_A_PIN0 ইন হিসাবে সংজ্ঞায়িত করা হয় Arduino.h। সুতরাং, যদি থেকে ফিরে আসা বাইটটি digitalPinToPortশূন্য হয়, তবে pinModeনিঃশব্দে ব্যর্থ হয়ে ফিরে আসবে।

যাই হোক pinModeনা কেন , অরাজকতা থেকে আমাদের বাঁচাতে পারে না। 999 এর পরিণাম পরিণতিতে নিয়তিযুক্ত।


টিএল; ডিআর, কোডটি কার্যকর করবে এবং এর ফলাফলটি অবিশ্বাস্য হবে। সম্ভবত, কোনও পিন সেট করা হবে না OUTPUTএবং digitalWriteব্যর্থ হবে। যদি আপনার খুব দুর্ভাগ্য হয়, তবে একটি এলোমেলো পিন সেট হয়ে যেতে পারে OUTPUTএবং digitalWriteসেট করতেও পারে HIGH


এটি আকর্ষণীয় যে কোনও সীমা পরীক্ষা করা নেই। ডিজিটাল রাইটটি যাইহোক এতটা ধীর এবং বিশাল, এটি কোনও সময় সংকলন করা বা সময় চেক চালানো অদ্ভুত হবে না।
সাইবারবিবন্স

যদি সমস্ত আরডুইনো পিনগুলি একটি স্বল্প পরিসরে থাকে তবে তারা পোর্টটি == একটি পিনের সাথে একটি পিন চেক নয়> BOARD_MAX_PIN চেকটি প্রতিস্থাপন করতে পারে, যেখানে বোর্ড সর্বাধিক পিন বোর্ডকে সনাক্ত করে এমন কিছু ifdef এর উপর ভিত্তি করে কিছু শিরোনাম ফাইলে সংজ্ঞায়িত করা হয়?
অনন্তকালীন

আপনি ভুলে যাচ্ছেন যে 999 টি তে প্রতিনিধিত্ব করা যায় না uint8_tতাই এটি কোডিংয়ের মাধ্যমে প্রথমে 231 এ রূপান্তরিত হবে pinMode। শেষ ফলাফল একই: pinModeএবং digitalWriteঅনির্দেশ্য আচরণ করতে হবে এবং মেমরি র্যান্ডম অংশের পরাস্ত পারে যদি তাদের একটি খারাপ পিন আর্গুমেন্ট সহ কল করুন।
ডেভিড গ্রেসন

3

স্ট্যান্ডার্ড লাইব্রেরিতে পিনগুলিকে পোর্টগুলিতে রূপান্তর করার জন্য ডিজাইন করা ম্যাক্রোগুলি রয়েছে যা সমাবেশে ব্যবহৃত হয়। এখানে তারা আরডোইনো 1.0.5 থেকে ইউনোর হয়ে আছেন:

#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)))

আরও আছে, তবে আমি এখানে তাদের দেখাব না।

আমি বিশ্বাস করি আপনার প্রোগ্রামটি 999 থেকে 14 টি বিয়োগ করবে, যা ব্রোগ্রামের জন্য এখনও খুব বড় হবে। এরপরে এটি digital_pn_to_bit_mask_PGMঅ্যারের 985 তম উপাদানটির দিকে নির্দেশ করার চেষ্টা করবে , যেখানে কেবল 20 টি উপাদান রয়েছে। এটি সম্ভবত প্রগেমের এলোমেলো স্পটের দিকে ইশারা করে আরডুইনোকে স্ক্রু করে ফেলতে পারে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.