مقدمة: لماذا قد "يجن" كودك في الفضاء؟
\n\nتخيل: لقد كتبت كودًا مثاليًا بلغة C++. اجتاز جميع اختبارات الوحدة، ويعمل كالساعة على حاسوبك المحمول القوي. تقوم بتحميله على الحاسوب الموجود على متن القمر الصناعي أو على جهاز يتحكم في مفاعل نووي. وهنا تبدأ الجحيم: المتغيرات تغير قيمها تلقائيًا، البرنامج يتعطل في أماكن عشوائية، ونظام التحكم يصدر أوامر خاطئة. قصة مألوفة؟
\n\nهذا ليس خطأ في كودك. هذا هو الفيزياء. الجسيمات عالية الطاقة (البروتونات، النيوترونات، الأيونات الثقيلة) تمر عبر السيليكون في الدائرة المتكاملة وتطرد الإلكترونات. فوتون واحد فقط يمكنه قلب بت في مسجل المعالج أو في خلية ذاكرة الوصول العشوائي. هذه الظاهرة تسمى Single Event Upset (SEU) — حدث عطل فردي. في مجتمع مطوري الأنظمة المضمنة وبرمجيات الفضاء، هذا الموضوع شائع جدًا لدرجة أن النقاش على Stack Overflow حصل على مئات الآلاف من المشاهدات. اليوم سنناقش كيفية تجميع وكتابة تطبيقات C++ للعمل في ظروف الإشعاع العالي، ولماذا لا تعمل الطرق التقليدية هنا.
\n\nالمشكلة: الإشعاع كـ"هاكر عشوائي" لذاكرتك
\n\nعندما نتحدث عن التجميع للبيئات المشعة، لا نعني علامة مترجم خاصة مثل -fradioactive. الإشعاع ليس متعلقًا بالبرمجيات، بل بالأجهزة. ومع ذلك، فإن كيفية كتابة وتجميع الكود هي التي تحدد ما إذا كان البرنامج سيتمكن من النجاة من "هجوم البتات".
التهديدات الرئيسية للكود في مثل هذه الظروف:
\n- \n
- SEU في مسجلات CPU: يمكن للجسيم تغيير القيمة في مسجل الأغراض العامة، مما يؤدي إلى حسابات خاطئة. \n
- SEU في الذاكرة المؤقتة: يمكن تنفيذ تعليمة "مقلوبة" كعملية مختلفة تمامًا. \n
- SEU في RAM: تغيير البيانات في المكدس أو الكومة. \n
- SEU في مسجلات التكوين: الأسوأ — يمكن للجسيم تغيير بت يتحكم في وضع تشغيل المعالج أو الأجهزة الطرفية. \n
مثال كلاسيكي من الفضاء الحقيقي: في عام 2003، تم تسجيل عطل على Mars Global Surveyor ناتج عن الإشعاع الكوني، مما أدى إلى تلف ذاكرة الفلاش وفقدان البيانات. وكم مرة "تعطلت" أفران الميكروويف المنزلية بالقرب من أجهزة إرسال قوية؟ لهذا السبب، حماية الكود من الإشعاع ليست ترفًا، بل ضرورة قاسية.
\n\nالنهج 1: الكود "الخرساني" (Radiation Hardening by Software)
\n\nالطريقة الأكثر سهولة هي كتابة كود يحمي نفسه بنفسه. المترجم هنا مجرد أداة، لكن يمكننا ضبطه.
\n\n1.1. Triple Modular Redundancy (TMR) — التكرار الثلاثي
\n\nهذه طريقة كلاسيكية. تقوم بعمل ثلاث نسخ من البيانات أو الحسابات الهامة، ثم "التصويت" بالأغلبية. إذا انقلب بت واحد، فإن الاثنين الآخرين "يتغلبان عليه بالتصويت".
\n\nنقوم بتنفيذ قالب بسيط بلغة C++ لحماية عدد صحيح واحد:
\n\n#include <array>\n#include <cstdint>\n#include <algorithm>\n\ntemplate<typename T>\nclass RadiationHardenedValue {\nprivate:\n std::array<T, 3> copies;\n\npublic:\n explicit RadiationHardenedValue(T initial_value) {\n copies.fill(initial_value);\n }\n\n // دالة "التصويت" بالأغلبية\n T get() const {\n // أبسط مرشح متوسطي لثلاث قيم\n if (copies[0] == copies[1] || copies[0] == copies[2]) {\n return copies[0];\n }\n if (copies[1] == copies[2]) {\n return copies[1];\n }\n // إذا كانت الثلاثة مختلفة — خطأ حرج\n // في الكود الحقيقي، يجب أن يكون هناك إنذار طارئ هنا\n return copies[0]; // نعيد شيئًا على الأقل\n }\n\n void set(const T& new_value) {\n copies[0] = new_value;\n copies[1] = new_value;\n copies[2] = new_value;\n }\n\n // عامل