यह स्पष्ट रूप से प्रलेखित है कि जब वैश्विक डेटा को आईएसआर और मुख्य कार्यक्रम के साथ साझा किया जाता है, तो volatile
मेमोरी दृश्यता की गारंटी देने के लिए डेटा को घोषित करने की आवश्यकता होती है (और यह केवल 1-बाइट डेटा के लिए पर्याप्त है; कुछ बड़ी चीजों को भी परमाणुता की गारंटी के लिए विशेष व्यवस्था की आवश्यकता होती है) । यहाँ हमारे पास अच्छे नियम हैं:
- केवल ISR के बाहर उपयोग किए जाने वाले चर अस्थिर नहीं होने चाहिए।
- केवल एक ISR के अंदर उपयोग किए जाने वाले चर अस्थिर नहीं होने चाहिए।
- एक ISR के अंदर और बाहर दोनों का उपयोग किया जाने वाला चर अस्थिर होना चाहिए।
लेकिन volatile
जरूरत तब होती है जब वैरिएबल को> 1 ISRs से एक्सेस किया जाता है, लेकिन ISRs के बाहर साझा नहीं किया जाता है? उदाहरण के लिए, मेरे पास एक फ़ंक्शन है जो एक static
चर का उपयोग करके आंतरिक स्थिति को बनाए रखता है :
void func() {
static volatile long counter; // volatile or not?
// Do stuff with counter etc.
}
उस फ़ंक्शन को दो तरीकों से कहा जाता है: पिन इंटरप्ट से, और टिमरऑन लाइब्रेरी से :
attachInterrupt(0, func, CHANGE);
Timer1.attachInterrupt(func);
कोई भी एटमॉसिटी समस्याएं नहीं हैं, जब एक ISR में प्रवेश किया जाता है, तो व्यवधान स्वचालित रूप से अक्षम हो जाते हैं , लेकिन यह volatile
एक संकलक का सवाल है: कैश्ड क्या है और क्या नहीं है।
सॉरी से बेहतर सुरक्षित, निश्चित रूप से ...
volatile
, क्योंकि यह कोड उत्पन्न होने के अलावा और कुछ भी संशोधित नहीं होता है; संकलक "मान सकता है" कि ISR रैखिक रूप से निष्पादित करता है, और यह तब तक करता है, जब तक कि बीच में घोंसला नहीं बनता। यह समझ आता है। धन्यवाद!