परमाणु पहुंच सुनिश्चित करने के लिए आपको इंटरप्ट अक्षम करने की आवश्यकता है। आप किसी अन्य प्रक्रिया को एक्सेस नहीं करना चाहते हैं और जब आप इसे पढ़ रहे हों तो उस चर को संभावित रूप से संशोधित करना चाहते हैं।
Introduction to Embedded Computing से
:
परमाणु पहुँच की आवश्यकता
इस परिदृश्य की कल्पना कीजिए: एक 16-बिट चर जांच करने के लिए अग्रभूमि कार्यक्रम, एक 8 बिट यू सी, जरूरतों पर चल रहा है, इसे कहते एक्स इसलिए यह उच्च बाइट लोड करता है और फिर कम बाइट लोड करता है (या दूसरी तरफ, आदेश कोई फर्क नहीं पड़ता), और उसके बाद 16-बिट मान की जांच करता है। अब एक एक संबंधित आईएसआर के साथ बाधा डालें जो 16-बिट चर को संशोधित करता है। आगे कल्पना करें कि चर के मूल्य 0x1234 पर प्रोग्राम निष्पादन में दिए गए समय के साथ होता है। ,
- अग्रभूमि भार उच्च बाइट (0x12)
- ISR होता 0xABCD
- अग्रभूमि भार कम बाइट (0xCD)
- अग्रभूमि कार्यक्रम देखता है को संशोधित करता है एक्स: यहाँ वेरी बैड बात कि हो सकता है है 0x12CD का 16-बिट मान।
समस्या यह है कि डेटा की एक माना जाता है कि अविभाज्य टुकड़ा, हमारे चर एक्स, वास्तव में यह, तक पहुँचने क्योंकि चर का उपयोग करने के सीपीयू निर्देश विभाज्य थे करने की प्रक्रिया में संशोधित किया गया था है। और इस प्रकार वेरिएबल एक्स का हमारा भार दूषित हो गया है। आप देख सकते हैं कि परिवर्तनीय पढ़ने के क्रम से कोई फर्क नहीं पड़ता। अगर ऑर्डर हमारे उदाहरण में उलट दिया गया था, तो वैरिएबल को 0x12CD के बजाय 0xAB34 के रूप में गलत तरीके से पढ़ा गया होगा। किसी भी तरह से, मान पढ़ा गया है न तो पुराना मान्य मान (0x1234) और न ही नया मान्य मान (0xABCD)।
लेखन आईएसआर-संदर्भित डेटा बेहतर नहीं है। इस बार मान लें कि अग्रभूमि कार्यक्रम आईएसआर के लाभ के लिए लिखा गया है, पिछले मान 0x1234, और उसके बाद एक नया मान 0xABCD लिखना होगा। में इस मामले में, VBT इस प्रकार है:
- अग्रभूमि भंडार नए उच्च बाइट (0xAB)
- ISR होता है, 0xAB34 के रूप में पढ़ता एक्स
- अग्रभूमि भंडार नए कम बाइट (0xCD)
एक बार फिर कोड (इस बार आईएसआर) न तो 0x1234 का वैध मान, न ही 0xABCD का नया मान्य मान, बल्कि 0xAB34 का अमान्य मान देखता है।
जबकि spiTxRxByteCount &= ~0x0100;
सी में एक ही निर्देश की तरह दिख सकता है, यह वास्तव में सीपीयू के लिए कई निर्देश हैं। जीसीसी में संकलित, विधानसभा सूची तो दिखाई देता है: एक अवरोध के बीच उन निर्देशों में से किसी में आता है और डेटा को संशोधित करता
57:atomic.c **** spiTxRxByteCount &= ~0x0100;
68 .loc 1 57 0
69 004d A1000000 movl _spiTxRxByteCount, %eax
69 00
70 0052 80E4FE andb $254, %ah
71 0055 A3000000 movl %eax, _spiTxRxByteCount
71 00
तो अपना पहला ISR संभावित गलत मान पढ़ सकते हैं। इसलिए आपको उस पर काम करने से पहले इंटरप्ट को अक्षम करने की आवश्यकता है और वेरिएबल volatile
घोषित करें।
यदि आपके पास आरटीओएस है, तो mutex का उपयोग क्यों न करें? –
@ [ओएस के तहत इस तरह से लागू सैमफोर ऑपरेशन] (http://www.mpi-sws.org/~druschel/courses/os/lectures/proc4.pdf) –