0Pricing
C++ Academy · درس

الإدخال والإخراج المعتمدان على خرائط الذاكرة وvolatile

تواصل مع سجلات العتاد بأمان باستخدام volatile والإدخال والإخراج المعتمدين على خرائط الذاكرة.

الإدخال والإخراج المعتمدان على خرائط الذاكرة وvolatile درس مجاني في C++ Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C++ Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C++ Academy 4 دروس في المجموع.

الإدخال والإخراج المعينان على الذاكرة

في المتحكمات الدقيقة والأنظمة المضمّنة، تظهر سجلات العتاد على هيئة عناوين ذاكرة. اقرأها أو اكتبها مثل الذاكرة العادية، لكن يجب منع المصرّف من تحسين عمليات الوصول وإلغائها.

لماذا volatile؟

تخبر مؤهلة volatile المصرّف بأن قيمة المتغير قد تتغير خارج البرنامج، مثلما يحدث بسبب المقاطعات أو العتاد. ويجب تنفيذ كل عملية وصول تمامًا كما كُتبت.

volatile uint32_t* GPIO = (uint32_t*)0x40020000;
*GPIO = 0x01;     // write must happen
uint32_t v = *GPIO;

ما الذي تمنعه volatile؟

لا يستطيع المصرّف:

  • تخزين القيمة مؤقتًا في سجل بين عمليات القراءة
  • إعادة ترتيب عمليات الوصول
  • إزالة عمليات القراءة والكتابة «المكررة»

النمط المعتاد للسجلات

عرّف بنية تطابق خريطة سجلات العتاد، ثم حوّل عنوانًا ثابتًا إلى مؤشر.

struct GpioRegs {
    volatile uint32_t MODER;
    volatile uint32_t OTYPER;
    volatile uint32_t OSPEEDR;
    volatile uint32_t IDR;
    volatile uint32_t ODR;
};

auto* GPIOA = reinterpret_cast<GpioRegs*>(0x40020000);
GPIOA->ODR = 0x01;

محاذير القراءة-التعديل-الكتابة

حتى مع volatile، لا تكون عمليات RMW ذرّية. وفي الأنظمة متعددة النوى أو عند الوصول المتزامن من ISR، تحتاج إلى ذريات صريحة أو إلى تعطيل المقاطعات.

volatile ليست لتعدد خيوط التنفيذ

هذا اعتقاد شائع خاطئ. لا توفر volatile ترتيبًا للذاكرة بين خيوط التنفيذ. استخدم std::atomic للوصول الآمن بين الخيوط، حتى مع الأعلام المشتركة.

معالجة السجلات باستخدام العمليات على مستوى البتات

اضبط البتات أو امسحها أو بدّلها باستخدام معاملات على مستوى البتات.

GPIOA->ODR |= (1 << 5);    // set bit 5
GPIOA->ODR &= ~(1 << 5);   // clear bit 5
GPIOA->ODR ^= (1 << 5);    // toggle bit 5

حقول البتات

للوصول إلى البتات المسماة، عرّف union من نوع uint32 وبنية تحتوي على حقول بتات. انتبه إلى أن ترتيب حقول البتات يحدده التنفيذ.

حواجز الذاكرة

على المنصات ذات نماذج الذاكرة الضعيفة (ARM)، استخدم __DMB() أو __DSB() أو std::atomic_thread_fence لفرض الترتيب بين عمليات الوصول.

اعتبارات التخزين المؤقت

إذا كانت وحدة MCU تحتوي على ذاكرة تخزين مؤقت، فيجب عادةً وضع علامة على ذاكرة الأجهزة الطرفية بأنها غير قابلة للتخزين المؤقت، وإلا فقد تقرأ بيانات قديمة. ويتولى إعداد MMU/MPU معالجة ذلك.

مخازن DMA المؤقتة

يجب أن تكون المخازن المؤقتة التي يستخدمها DMA بمحاذاة مناسبة وغير قابلة للتخزين المؤقت، وأن تُجرى عليها عمليات flush المناسبة على المنصات التي تستخدم التخزين المؤقت. راجع دليل CPU لديك.

اختبار التعليمات البرمجية الخاصة بالعتاد

اختبر وحديًا التعليمات البرمجية التي تتعامل مع العتاد، وذلك بتجريد الوصول إلى السجلات خلف واجهة — أنشئ نسخة وهمية منها في الاختبارات، وأنشئ النسخة الحقيقية على العتاد.

تحقق سريع

ماذا تضمن الكلمة المفتاحية volatile؟

خلاصة

استخدم volatile مع سجلات العتاد المعينة على الذاكرة، فهي تمنع المترجم من تحسين عمليات الوصول وإلغائها. لكنها ليست مخصصة لمزامنة الخيوط؛ استخدم std::atomic لهذا الغرض. واجمع بينها وبين حواجز الذاكرة على وحدات المعالجة المركزية ذات الذاكرة الضعيفة.

الأسئلة الشائعة

هل درس «الإدخال والإخراج المعتمدان على خرائط الذاكرة وvolatile» مجاني؟

نعم — نص درس «الإدخال والإخراج المعتمدان على خرائط الذاكرة وvolatile» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C++ Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C++ Academy 4 دروس في المجموع.

ماذا ستتعلم في «الإدخال والإخراج المعتمدان على خرائط الذاكرة وvolatile»؟

تواصل مع سجلات العتاد بأمان باستخدام volatile والإدخال والإخراج المعتمدين على خرائط الذاكرة. تتمرن على C++ Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ C++ Academy؟

لا تُشترط خبرة سابقة. C++ Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.

كم من الوقت يستغرق درس «الإدخال والإخراج المعتمدان على خرائط الذاكرة وvolatile»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس C++ Academy هذا؟

نعم. كل درس في C++ Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. القيود في الأنظمة المضمّنة: بلا RTTI أو استثناءات
  2. الإدخال والإخراج المعتمدان على خرائط الذاكرة وvolatile
  3. اعتبارات الزمن الحقيقي ووقت الاستجابة
  4. الترجمة المتقاطعة لأهداف ARM
← العودة إلى C++ Academy