الفرق بين المراجعتين ل"Arduino/volatile"

من موسوعة حسوب
اذهب إلى التنقل اذهب إلى البحث
(أنشأ الصفحة ب'تصنَّف الكلمة volatile المفتاحية من «مقيدات المتغيرات» (variable qualifier)، وتُستعمَل عادةً قبل نوع الم...')
 
سطر 1: سطر 1:
تصنَّف الكلمة volatile المفتاحية من «مقيدات المتغيرات» (variable qualifier)، وتُستعمَل عادةً قبل نوع المتغير عند تعريفه لتعديل الطريقة التي يعامل فيها المصرِّف والبرنامج اللاحق هذا المتغير.
+
تصنَّف الكلمة <code>volatile</code> المفتاحية ضمن «مقيدات المتغيرات» (variable qualifier)، وتُستعمَل عادةً قبل نوع المتغير عند تعريفه لتعديل الطريقة التي يعامل فيها المصرِّف والبرنامج اللاحق هذا المتغير.
  
تمثِّل الكلمة volatile المفتاحية عند استعمالها في تعريف متغير توجيهًا (directive) للمصرِّف نفسه. المصرِّف هو برنامج وظيفته تحويل الشيفرة المكتوبة بلغة ++C/C إلى شيفرة تنفيذية يفهمها العتاد؛ تحوي هذه الشيفرة التنفيذية على أوامر فعلية للمتحكم الموجود على لوحة أردينو تخبره بما يتوجب عليه فعله.
+
تمثِّل الكلمة <code>volatile</code> المفتاحية عند استعمالها في تعريف متغير توجيهًا (directive) للمصرِّف نفسه. المصرِّف هو برنامج وظيفته تحويل الشيفرة المكتوبة بلغة ++C/C إلى شيفرة تنفيذية يفهمها العتاد؛ تحوي هذه الشيفرة التنفيذية أوامر فعلية للمتحكم الموجود على لوحة أردوينو تخبره بما يتوجب عليه فعله.
  
 
الأمر الذي تفعله الكلمة <code>volatile</code> المفتاحية مع المتغير هو توجيه المصرِّف إلى تحميل المتغير من الذاكرة RAM وليس من سجلات التخزين للذاكرة المؤقتة (الذاكرة flash) حيث تُخزَّن جميع متغيرات البرنامج. في بعض الحالات، القيمة المخزَّنة في المسجلات لمتغيرٍ ما قد تكون غير دقيقة.
 
الأمر الذي تفعله الكلمة <code>volatile</code> المفتاحية مع المتغير هو توجيه المصرِّف إلى تحميل المتغير من الذاكرة RAM وليس من سجلات التخزين للذاكرة المؤقتة (الذاكرة flash) حيث تُخزَّن جميع متغيرات البرنامج. في بعض الحالات، القيمة المخزَّنة في المسجلات لمتغيرٍ ما قد تكون غير دقيقة.
  
يجب أن يعرَّف المتغير مع الكلمة volatile المفتاحية متى ما كان بالإمكان تغيير قيمته عبر شيء يتجاوز تحكم جزء الشيفرة الذي يظهر هذا المتغير ضمنه، مثل تنفيذ خيط في وقت واحد. في أردوينو، المكان الوحيد الذي يحتمل أن يحدث فيه هذا الأمر هو أجزاء الشيفرة المرتبطة بالمقاطعات والتي تدعى ببرامج خدمة المقاطعة الفرعية (ISR).
+
يجب أن يعرَّف المتغير مع الكلمة <code>volatile</code> المفتاحية متى ما كان بالإمكان تغيير قيمته عبر شيء يتجاوز تحكم جزء الشيفرة الذي يظهر هذا المتغير ضمنه، مثل تنفيذ خيط في وقت واحد. في أردوينو، المكان الوحيد الذي يحتمل أن يحدث فيه هذا الأمر هو أجزاء الشيفرة المرتبطة [[Arduino/interrupts|بالمقاطعات]] والتي تدعى [[Arduino/interrupts/attachinterrupt|ببرامج خدمة المقاطعة الفرعية]] (ISR).
  
== الأعداد الصحيحة المتطايرة أم الطويل المتطايرة؟ ==
+
== الأعداد الصحيحة المتطايرة أم الطويلة المتطايرة؟ ==
إن استعملت الكلمة volatile مع متغير يزيد حجمه عن بايت واحد (2 بايت مثل العدد الصحيح، أو 4 بايت مثل العدد الطويل ...إلخ.)، فلن يتمكن المتحكم من قراءته في خطوة واحدة لأنَّ معمارية المتحكم هي 8 بت. هذا يعني أنَّه بينما يقرأ جزء الشيفرة (مثل الجزء loop()) أول ثمانية بتات من المتغير، قد تكون المقاطعة قد غيِّرت مسبقًا البتات الثمانية الأخرى (في حال كان حجم المتغير 16 بت). سيؤدي هذا إلى الحصول على قيمة عشوائية للمتغير.
+
إن استعملت الكلمة <code>volatile</code> مع متغير يزيد حجمه عن بايت واحد (2 بايت مثل [[Arduino/int|العدد الصحيح]]، أو 4 بايت مثل [[Arduino/long|العدد الطويل]] ...إلخ.)، فلن يتمكن المتحكم من قراءته في خطوة واحدة لأنَّ معمارية المتحكم هي 8 بت غالبًا (تأكد من معمارية المتحكم في لوحتك). هذا يعني أنَّه بينما يقرأ جزء الشيفرة (مثل الجزء <code>[[Arduino/loop|()loop]]</code>) أول ثمانية بتات من المتغير، قد تكون المقاطعة قد غيِّرت مسبقًا البتات الثمانية الأخرى (في حال كان حجم المتغير 16 بت). سيؤدي هذا إلى الحصول على قيمة عشوائية للمتغير.
  
حلُّ هذه المشكلة هو تعطيل المقاطعات أثناء قراءة قيم المتغيرات، وبذلك لا تتغير قيمة بتات المتغير آثناء قراءتها. يوجد عدة طرق لفعل ذلك منها:
+
حلُّ هذه المشكلة هو تعطيل المقاطعات أثناء قراءة قيم المتغيرات، وبذلك لا تتغير قيم بتات المتغير أثناء قراءتها. توجد عدة طرق لفعل ذلك منها:
* استعمال الدالة noInterrupts، أو
+
* استعمال الدالة <code>[[Arduino/interrupts/nointerrupts|()noInterrupts]]</code> لتعطيل المقاطعات، أو
* استعمال ATOMIC_BLOCK، إذ العمليات الذرية (atomic operations) هي عمليات مفردة يجريها المتحكم (MCU) وتمثِّل أصغر وحدة محتملة.
+
* استعمال الكتلة <code>[https://www.nongnu.org/avr-libc/user-manual/group__util__atomic.html ATOMIC_BLOCK]</code>، إذ العمليات الذرية (atomic operations) هي عمليات مفردة يجريها المتحكم (MCU) وتمثِّل أصغر وحدة محتملة.
  
 
== أمثلة ==
 
== أمثلة ==

مراجعة 13:35، 27 أكتوبر 2018

تصنَّف الكلمة volatile المفتاحية ضمن «مقيدات المتغيرات» (variable qualifier)، وتُستعمَل عادةً قبل نوع المتغير عند تعريفه لتعديل الطريقة التي يعامل فيها المصرِّف والبرنامج اللاحق هذا المتغير.

تمثِّل الكلمة volatile المفتاحية عند استعمالها في تعريف متغير توجيهًا (directive) للمصرِّف نفسه. المصرِّف هو برنامج وظيفته تحويل الشيفرة المكتوبة بلغة ++C/C إلى شيفرة تنفيذية يفهمها العتاد؛ تحوي هذه الشيفرة التنفيذية أوامر فعلية للمتحكم الموجود على لوحة أردوينو تخبره بما يتوجب عليه فعله.

الأمر الذي تفعله الكلمة volatile المفتاحية مع المتغير هو توجيه المصرِّف إلى تحميل المتغير من الذاكرة RAM وليس من سجلات التخزين للذاكرة المؤقتة (الذاكرة flash) حيث تُخزَّن جميع متغيرات البرنامج. في بعض الحالات، القيمة المخزَّنة في المسجلات لمتغيرٍ ما قد تكون غير دقيقة.

يجب أن يعرَّف المتغير مع الكلمة volatile المفتاحية متى ما كان بالإمكان تغيير قيمته عبر شيء يتجاوز تحكم جزء الشيفرة الذي يظهر هذا المتغير ضمنه، مثل تنفيذ خيط في وقت واحد. في أردوينو، المكان الوحيد الذي يحتمل أن يحدث فيه هذا الأمر هو أجزاء الشيفرة المرتبطة بالمقاطعات والتي تدعى ببرامج خدمة المقاطعة الفرعية (ISR).

الأعداد الصحيحة المتطايرة أم الطويلة المتطايرة؟

إن استعملت الكلمة volatile مع متغير يزيد حجمه عن بايت واحد (2 بايت مثل العدد الصحيح، أو 4 بايت مثل العدد الطويل ...إلخ.)، فلن يتمكن المتحكم من قراءته في خطوة واحدة لأنَّ معمارية المتحكم هي 8 بت غالبًا (تأكد من معمارية المتحكم في لوحتك). هذا يعني أنَّه بينما يقرأ جزء الشيفرة (مثل الجزء ()loop) أول ثمانية بتات من المتغير، قد تكون المقاطعة قد غيِّرت مسبقًا البتات الثمانية الأخرى (في حال كان حجم المتغير 16 بت). سيؤدي هذا إلى الحصول على قيمة عشوائية للمتغير.

حلُّ هذه المشكلة هو تعطيل المقاطعات أثناء قراءة قيم المتغيرات، وبذلك لا تتغير قيم بتات المتغير أثناء قراءتها. توجد عدة طرق لفعل ذلك منها:

  • استعمال الدالة ()noInterrupts لتعطيل المقاطعات، أو
  • استعمال الكتلة ATOMIC_BLOCK، إذ العمليات الذرية (atomic operations) هي عمليات مفردة يجريها المتحكم (MCU) وتمثِّل أصغر وحدة محتملة.

أمثلة

تبديل حالة رجل متصلة مع ضوء ليد عند حدوث مقاطعة على الرجل 2:

int pin = 13;
volatile byte state = LOW;

void setup()
{
  pinMode(pin, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(2), blink, CHANGE);
}

void loop()
{
  digitalWrite(pin, state);
}

void blink()
{
  state = !state;
}

انظر أيضًا

مصادر