بسم الله الرحمن الرحيم.
بعد أن تحدثنا عن موضوعات المعالج والذاكرة، سنتحدث في هذا المقال عن الجزء الأساسي الثالث في الحاسب: نظام الإدخال والإخراج I/O.
نظام الإدخال والإخراج (I/O)
كما ذكرنا سابقاً، تتألف بنية الحاسوب من المعالج والذاكرة والأجهزة الطرفية الخارجية. تعمل الأجهزة الطرفية — مثل لوحة المفاتيح والطابعة — على استقبال البيانات من البيئة الخارجية وإرسالها إليها، وتكون مرتبطة بالمعالج عبر وحدات واجهة خاصة.
تنشأ هذه الوحدات (I/O Modules) لمعالجة الفروقات الأساسية بين المعالج والأجهزة الطرفية، مثل:
- اختلاف نوع الإشارات: كهربائية/إلكترونية في المعالج مقابل ميكانيكية في الأجهزة الطرفية.
- معدلات النقل: فالأجهزة بطبيعتها أبطأ من المعالج.
- وحدات المعلومات: فالأجهزة تتعامل بالبايت بينما يعالج المعالج بالوورد Word.
- أوضاع التشغيل: فالأجهزة غير متزامنة Asynchronous على عكس المعالج المتزامن.
ولمعالجة هذه الفروقات توجد وحدات واجهة (Interfaces) تربط المعالج بالأجهزة الطرفية، ويتعامل معها نظام التشغيل.
كيف يتعرّف المعالج على الأجهزة الطرفية ليتواصل معها؟
هناك طريقتان لعنونة الأجهزة:
• الذاكرة المحجوزة (Memory-Mapped I/O):
يُستخدم فضاء العناوين نفسه للذاكرة وللأجهزة، فيستطيع أوامر المعالج العادية مثل mov الوصول إلى مواقع تمثل سجلات الأجهزة.
• المنافذ المحجوزة (Port-Mapped I/O):
يمتلك كل جهاز فضاء عناوين منفصلاً، وتستخدم تعليمات خاصة مثل IN وOUT في معالجات x86 للتواصل بين المعالج والأجهزة.
مثال:
mov dx, 0x3F8 ; عنوان المنفذ (منفذ COM1 التسلسلي)
mov al, 'A'
out dx, al ; إرسال الحرف 'A' إلى الجهاز عبر المنفذ
وظيفة واجهات الإدخال والإخراج
ما وظيفة واجهات الإدخال والإخراج؟ وظيفتان أساسيتان: التزامن بين سرعة المعالج والأجهزة الطرفية، وتوفير آلية مشتركة لمبادلة البيانات.
على سبيل المثال: تنفذ واجهة الإدخال/الإخراج إشارات التحكم والتوقيت Control & Timing لإدارة تدفق البيانات، وتعدّل فارق السرعة بين الذاكرة والجهاز الطرفي عبر حجز البيانات Buffering، وتكشف أخطاء النقل Error Detection مثل انحشار الورق في الطابعة أو تشويش البتات:
شكل (1): وحدة الإدخال والإخراج ووظائفها
الأجهزة الطرفية الخارجية (External Devices)
هي كل ما يتصل بالحاسوب لأغراض الإدخال والإخراج دون أن يكون جزءاً أساسياً من بنية المعالج.
ويحتوي كل جهاز طرفي على مكونات أساسية:
• إشارات التحكم (Control Signals): تخبر الجهاز بما يجب فعله (مثل إرسال البيانات إلى واجهة I/O أو الاستقبال منها).
• إشارات الحالة (State Signals): تشير إلى حالة الجهاز (جاهزيته أو انشغاله).
• بتات البيانات (Data Bits): تحمل المعلومات الفعلية المتبادلة بين الجهاز والمعالج.
على سبيل المثال: لدينا لوحة مفاتيح لها إشارة جاهزية، وعند ضغط مفتاح ينتج بايت يرسل عبر ناقل البيانات إلى المعالج. يتم هذا الإرسال عبر وحدة I/O التي ترصد حالة اللوحة وتنسق عملية النقل.
وحدات الإدخال والإخراج (I/O Modules)
ما هي وحدات الإدخال والإخراج؟ هي مكوّن مادي خاص يربط الأجهزة الطرفية بالمعالج والذاكرة. وتقوم الوحدة بوظيفتين رئيسيتين:
• الواجهة مع المعالج/الذاكرة: تتصل بالناقل Bus الرئيسي للمعالج، حيث تستقبل أوامر المعالج وترجع إليه البيانات.
• الواجهة مع الأجهزة الطرفية: تحوي وصلات مخصصة للأجهزة، وتتعامل مع فروق السرعة وخصائص بياناتها.
الوظائف التفصيلية
• التحكم والتوقيت (Control & Timing): تنسق تدفق البيانات بين الذاكرة والأجهزة. مثلاً: يرسل المعالج أمر قراءة إلى وحدة I/O للتحقق من جهاز معين، فترد الوحدة بإشارة حالة تعبّر عن وضع الجهاز؛ فإن كان جاهزاً يطلب المعالج نقل البيانات، فتحصل الوحدة على البايت من الجهاز وتنقله إلى المعالج.
• اتصال المعالج (Processor Communication): يشمل استقبال الأوامر من المعالج (مثل أوامر القراءة/الكتابة)، وإرسال البيانات والحالة إليه عبر الناقل.
• اتصال الجهاز (Device Communication): يشمل معالجة الأوامر الموجهة للجهاز، وتبادل البيانات والحالة بين الوحدة والجهاز.
• التخزين المؤقت للبيانات (Data Buffering): يعالج تباين السرعات بين الذاكرة والجهاز: إذا كان الجهاز أسرع من الذاكرة تجمع الوحدة البيانات مؤقتاً قبل نقلها دفعة واحدة، وإذا كان أبطأ خزّنتها مؤقتاً حتى لا ينشغل المعالج والذاكرة بالعمليات البطيئة.
• كشف الأخطاء (Error Detection): تتحقق من الأخطاء الميكانيكية أو الكهربائية في الجهاز (مثل انحشار ورقة في الطابعة).
وتتصل وحدات I/O بالناقل بواسطة خطوط العناوين والبيانات والتحكم. لإرسال أمر إلى جهاز ما، يضع المعالج عنوان الجهاز على خطوط العناوين، ويشمل خط التحكم نوع العملية، ثم تفحص وحدة I/O هذا العنوان وتفعّل مسار نقل البيانات مع الجهاز المناسب.
أساليب الإدخال والإخراج (I/O Techniques)
في الحواسيب الحديثة توجد ثلاثة أساليب رئيسية لمزامنة عملية نقل البيانات بين المعالج والأجهزة الطرفية:
الإدخال/الإخراج المبرمَج (Programmed I/O)
تدار كافة عمليات النقل بواسطة تعليمات في برنامج المعالج: يصدر البرنامج أمر قراءة أو كتابة، ثم يجلس المعالج في حلقة انتظار يراقب خلالها حالة الجهاز باستمرار حتى يصبح جاهزاً. هذه الطريقة بسيطة من ناحية العتاد لكنها غير فعالة من ناحية الأداء؛ لأن المعالج يظل مشغولاً بفحص حالة الجهاز بدلاً من تنفيذ تعليمات أخرى.
مثال: استطلاع جهاز عبر منفذه حتى يصبح جاهزاً:
while (!(inb(STATUS_PORT) & 0x01)); // انتظر حتى تصبح الحالة READY
data = inb(DATA_PORT); // اقرأ البايت من المنفذ
الإدخال/الإخراج المعتمد على المقاطعة (Interrupt-Driven I/O)
هذا الأسلوب يحل مشكلة إهدار وقت المعالج في الانتظار: يصدر المعالج أمر I/O ويواصل تنفيذ تعليمات أخرى دون انتظار، بينما تبقى وحدة I/O تراقب الجهاز. عندما يصبح الجهاز جاهزاً تصدر وحدة I/O إشارة مقاطعة (IRQ) لتنبيه المعالج.
عند استلام المقاطعة يوقف المعالج البرنامج الحالي مؤقتاً وينقل التحكم إلى روتين خدمة المقاطعة (Interrupt Service Routine – ISR) لقراءة البيانات أو كتابتها، ثم يستأنف عمله السابق. وهذا الأسلوب أعلى كفاءة وتحسين واضح للأداء.
مثال:
push eax
in al, dx ; قراءة البيانات من منفذ جهاز طرفي إلى AL
pop eax
iret ; العودة من المقاطعة
الوصول المباشر إلى الذاكرة (Direct Memory Access – DMA)
يستخدم لنقل كتل ضخمة من البيانات بسرعة عالية (مثلاً من وإلى الأقراص الصلبة). في هذا الأسلوب يقوم المعالج بإعداد وحدة تحكم DMA — بكتابة عنوان الذاكرة وعدد البيانات المراد نقلها — ثم يتركها تنقل البيانات مباشرة بين الذاكرة والجهاز دون مشاركته في كل عملية نقل.
تحصل وحدة DMA على الناقل System Bus عبر آلية تحكيم: ترسل إشارة طلب الناقل (Bus Request) فيستجيب المعالج بإشارة المنح (Bus Grant)، ثم تقرأ أو تكتب الكتلة بسرعة الذاكرة الكاملة. وعند انتهاء النقل ترسل مقاطعة إلى المعالج لإعلامه.
ينتج عن DMA كفاءة عالية في النقل، وبقاء المعالج حراً للمهام الأخرى — فهو يتيح للجهاز الوصول إلى الذاكرة مباشرة بين يبقى الإعداد والمراقبة للمعالج:
شكل (2): نقل البيانات عبر وحدة DMA
أتمنى أن تتذكرونا بدعوة في ظهر الغيب، لعل أحدكم أقرب إلى الله منزلة وله دعوة لا ترد.