1ms القرار الموقت تحت لينكس الطريقة الموصى بها

StackOverflow https://stackoverflow.com/questions/240058

  •  04-07-2019
  •  | 
  •  

سؤال

أنا بحاجة إلى توقيت وضع علامة مع 1ms القرار تحت لينكس.يتم استخدامه لزيادة توقيت القيمة التي بدورها هي تستخدم لمعرفة ما إذا كان مختلف الأحداث ينبغي تشغيلها.POSIX timerfd_create ليس خيارا لأن من سي العمومية المطلب.حاولت timer_create و timer_settimer ، ولكن أفضل أحصل منها هو 10ms القرار أصغر تبدو القيمة الافتراضية إلى 10ms القرار.Getittimer و setitimer يكون 10 ms القرار وفقا manpage.

الطريقة الوحيدة للقيام بذلك الموقت أستطيع حاليا التفكير في استخدام clock_gettime مع CLOCK_MONOTONIC في حلقة الرئيسي وهو اختبار إذا كانت السيدة قد مرت على زيادة العداد (ثم تحقق إذا كان مختلف الأحداث يجب أن النار).

هل هناك طريقة أفضل للقيام بذلك من أجل باستمرار الاستعلام الرئيسي في الحلقة ؟ ما هو الحل الموصى بها هذا ؟

اللغة أستخدمه هو سهل القديمة ج

التحديث
أنا باستخدام 2.6.26 النواة.وأنا أعلم أنك يمكن أن يكون ذلك يقطع في 1kHz ، POSIX timer_* وظائف ثم يمكن برمجتها يصل الى 1ms ولكن يبدو أن هذا ليس موثوق بها و لا تريد استخدام هذا لأنه قد تحتاج إلى نواة جديدة على بعض الأنظمة.بعض الأسهم نواة يبدو أن لا يزال لديك 100Hz تكوينه.وأنا في حاجة إلى الكشف عن ذلك.التطبيق قد تكون تعمل على شيء آخر من نظام بلدي :)

أنا لا أستطيع النوم على 1ms لأنه قد يكون هناك أحداث الشبكة يجب أن تتفاعل.

كيف حلها لأنه ليس هذا المهم أنا ببساطة أعلنت العالمية موقت 100ms القرار.جميع الأحداث الخاصة بهم باستخدام الموقت يجب أن تحدد على الأقل 100ms عن توقيت انتهاء الصلاحية.كنت أكثر أو أقل أتساءل عما إذا كان سيكون هناك طريقة أفضل ، ومن ثم السؤال.

لماذا قبلت الجواب أعتقد أن الإجابة من freespace أفضل وصف السبب في أنه ليس من الممكن حقا دون الوقت الحقيقي نظام لينكس.

هل كانت مفيدة؟

المحلول

الاقتراع في حلقة الرئيسية لا إجابة أيضا - العملية الخاصة بك قد لا تحصل على الكثير من الوقت وحدة المعالجة المركزية ، حتى أكثر من 10ms سوف تنقضي قبل رمز يحصل لتشغيل, جعلها موضع نقاش.

10ms عن معيار توقيت القرار غير معظمالحقيقي أنظمة التشغيل (RTOS).وإنما هو موضع نقاش في غير RTOS - سلوك جدولة و المرسل سوف تؤثر إلى حد كبير على كيفية بسرعة يمكنك الرد على توقيت تنتهي.على سبيل المثال حتى افترض أنك قد الفرعية 10ms القرار الموقت لا يمكنك الرد على توقيت تنتهي إذا كان الرمز لا يعمل.منذ كنت لا يمكن التنبؤ عندما التعليمات البرمجية الخاصة بك هو الذهاب الى تشغيل لا يمكنك الرد على توقيت انتهاء الصلاحية بدقة.

هناك بالطبع الحقيقي لينكس حبات, انظر http://www.linuxdevices.com/articles/AT8073314981.html للحصول على قائمة.أ RTOS ويوفر مرافق حيث يمكنك الحصول على لينة أو صلبة ضمانات حول عندما التعليمات البرمجية الخاصة بك هو الذهاب الى تشغيل.هذا هو السبيل الوحيد موثوق والاستجابة بدقة توقيت تنتهي.... الخ

نصائح أخرى

للحصول على 1ms القرار توقيت تفعل ما libevent لا.

تنظيم أجهزة ضبط الوقت الخاص بك إلى مين كومة, هذا هو الجزء العلوي من كومة الموقت مع أقرب انتهاء (المطلق) مرة (rb-شجرة سوف تعمل أيضا ولكن مع المزيد من النفقات العامة).قبل استدعاء select() أو epoll() في الحدث الرئيسي حلقة حساب دلتا في ميلي ثانية بين انتهاء وقت أبكر توقيت الآن.استخدام هذا الدلتا المهلة إلى select(). select() و epoll() مهلة يكون 1ms القرار.

لدي جهاز توقيت القرار الاختبار الذي يستخدم آلية موضح أعلاه (ولكن ليس libevent).الاختبار يقيس الفرق بين المطلوب توقيت انتهاء الوقت الفعلي انتهاء 1ms, 5ms و 10ms توقيت:

1000 deviation samples of  1msec timer: min=  -246115nsec max=  1143471nsec median=   -70775nsec avg=      901nsec stddev=    45570nsec
1000 deviation samples of  5msec timer: min=  -265280nsec max=   256260nsec median=  -252363nsec avg=     -195nsec stddev=    30933nsec
1000 deviation samples of 10msec timer: min=  -273119nsec max=   274045nsec median=   103471nsec avg=     -179nsec stddev=    31228nsec
1000 deviation samples of  1msec timer: min=  -144930nsec max=  1052379nsec median=  -109322nsec avg=     1000nsec stddev=    43545nsec
1000 deviation samples of  5msec timer: min= -1229446nsec max=  1230399nsec median=  1222761nsec avg=      724nsec stddev=   254466nsec
1000 deviation samples of 10msec timer: min= -1227580nsec max=  1227734nsec median=    47328nsec avg=      745nsec stddev=   173834nsec
1000 deviation samples of  1msec timer: min=  -222672nsec max=   228907nsec median=    63635nsec avg=       22nsec stddev=    29410nsec
1000 deviation samples of  5msec timer: min= -1302808nsec max=  1270006nsec median=  1251949nsec avg=     -222nsec stddev=   345944nsec
1000 deviation samples of 10msec timer: min= -1297724nsec max=  1298269nsec median=  1254351nsec avg=     -225nsec stddev=   374717nsec

اختبار ركض مثل عملية في الوقت الحقيقي على فيدورا 13 نواة 2.6.34 أفضل تحقيق الدقة من 1ms الموقت كان avg=22nsec stddev=29410nsec.

أنا غير متأكد من أنه أفضل حل ، ولكن قد تفكر في كتابة نواة صغيرة وحدة يستخدم نواة عالية الدقة توقيت توقيت.في الأساس كنت إنشاء ملف الجهاز الذي يقرأ فقط العائد على 1ms فترات.

مثال على هذا النوع من النهج المستخدمة في النجمة مقسم, عن طريق ztdummy وحدة.إذا كنت جوجل ztdummy يمكنك العثور على التعليمات البرمجية التي تفعل ذلك.

أعتقد سيكون لديك صعوبة تحقيق 1 ms الدقة القياسية لينكس حتى مع ثابت الاستعلام في حلقة الرئيسية ، لأن النواة لا ضمان التطبيق الخاص بك سوف تحصل على وحدة المعالجة المركزية في كل وقت.على سبيل المثال ، يمكن أن يكون وضع النوم على عشرات من الميلي ثانية بسبب وقائية تعدد المهام و هناك الكثير يمكنك القيام به حيال ذلك.

قد ترغب في النظر في في الوقت الحقيقي لينكس.

إذا كنت تستهدف x86 يجب أن تحقق HPET توقيت.هذه الأجهزة الموقت كبيرة من الدقة.يجب أن تكون معتمدة من قبل motherbord (الآن كل منهم الدعم) و النواة يجب أن يحتوي على سائق أنها كذلك.لقد استخدمت عدة مرات دون أي مشاكل و كان قادرا على تحقيق أفضل بكثير القرار من 1ms.

هنا بعض الوثائق و الأمثلة على ذلك:

أذكر الحصول على موافق النتائج مع gettimeofday/usleep على أساس الاقتراع-لا تحتاج إلى 1000 توقيت ثانية أو أي شيء, ولكن كنت تحتاج إلى دقة جيدة مع توقيت القراد لم نحتاج بلدي التطبيق كان MIDI طبل آلة تحكم أتذكر الحصول على sub-دقة ميلي ثانية واحدة التي تحتاج آلة الطبل إذا كنت لا تريد أن يبدو سيئا جدا الطبال (esp.عد MIDI المدمج في الإختفاء) -- iirc (كان عام 2005 حتى ذاكرتي هو غامض قليلا) لقد كنت على بعد 200 ميكروثانية الهدف مرات مع usleep.

ومع ذلك كنت لا تعمل أي شيء آخر في النظام.إذا كان لديك بيئة تسيطر عليها قد تكون قادرة على الابتعاد مع حل مثل هذا.إذا كان هناك أكثر تسير على نظام (مشاهدة كرون إطلاق النار حتى فرص التوظيف وإسداء المشورة ، إلخ.) ثم الأشياء قد ينهار.

هل يعمل على لينكس kernel 2.4?

من VMware مقالة #1420 (http://kb.vmware.com/kb/1420).

لينكس أنظمة التشغيل الضيف تبقى الوقت عن طريق عد المقاطعات جهاز ضبط الوقت.غير المصلحة 2.4 في وقت سابق حبات برنامج نظام الظاهري الموقت طلب المقاطعات ساعة في 100Hz (100 يقطع في الثانية الواحدة).2.6 الألباب ، من جهة أخرى, طلب يقطع في 1000Hz - عشر مرات كما في كثير من الأحيان.بعض 2.4 حبات تعديل توزيع البائعين تحتوي على 2.6 الميزات أيضا طلب 1000Hz المقاطعات أو في بعض الحالات المقاطعات في معدلات أخرى ، كما 512Hz.

هناك ktimer التصحيح نواة لينكس:

http://lwn.net/Articles/167897/

http://www.kernel.org/pub/linux/kernel/projects/rt/

HTH

أولا الحصول على نواة المصدر و ترجمة ذلك مع تعديل هرتز المعلمة.

  • إذا HZ=1000, المقاطعات جهاز ضبط الوقت 1000 مرة في الثانية.أنها على ما يرام لاستخدام HZ=1000 بالنسبة i386 آلة.
  • على جزءا لا يتجزأ من آلة ، هرتز قد تكون محدودة إلى 100 أو 200.

لحسن العملية ، PREEMPT_KERNEL الخيار ينبغي أن يكون على.هناك حبات التي لا تدعم هذا الخيار بشكل صحيح.يمكنك التحقق منها من قبل البحث.

الأخيرة حبات ، أي2.6.35.10, يدعم NO_HZ الخيارات التي يتحول على ديناميكية القراد.وهذا يعني أنه لن يكون هناك توقيت القراد عندما تكون في الخمول ، ولكن توقيت القراد سيتم إنشاؤها في لحظة محددة.

هناك RT التصحيح إلى النواة ، ولكن دعم الأجهزة محدودة جدا.

عموما RTAI هو القاتل حل المشكلة, ولكن دعم الأجهزة محدودة جدا.ولكن جيدة باستخدام الحاسب الآلي جهاز تحكم, مثل emc2 استخدام RTAI أجل قطع مسافة السباق ربما 5000 هرتز ، ولكن يمكن من الصعب العمل على تثبيته.

إذا كنت تستطيع ، يمكنك إضافة أجهزة توليد نبضات.التي من شأنها أن تجعل وهو النظام الذي يمكن أن تتكيف مع أي إصدار نظام التشغيل.

يمكنك استخدام ما لا يقل عن nanosleep في حلقة الخاص بك إلى النوم 1ms?أو هو أن سي العمومية الشيء ؟

تحديث: لا يهم, أنا انظر من صفحة "يمكن أن يستغرق ما يصل إلى 10 مللي ثانية أطول من المحدد حتى تصبح العملية runnable مرة أخرى"

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

هناك طريقتان يمكنك أن تأخذ مع هذا:

1) التطبيق الخاص بك هو فقط تشغيل آلة الدولة و لا شيء آخر.لينكس هو ببساطة "محمل التمهيد." إنشاء نواة الكائن الذي يثبت حرف الجهاز.على الإدراج في النواة ، إعداد طبيبك الموقت لتشغيل بشكل مستمر.تعرف على تردد انها تعمل في.الآن في النواة, صراحة تعطيل الوكالة الدولية للطاقة.الآن تعطيل المقاطعات (الأجهزة والبرامج) على واحدة وحدة المعالجة المركزية نواة لينكس ، داعيا spin_lock() إنجاز هذا (ترك ذلك.) وحدة المعالجة المركزية هو لك.مشغول حلقة, التحقق من قيمة GPT حتى المطلوبة # القراد مرت ، عندما يكون لديهم مجموعة قيمة من أجل المقبل مهلة وأدخل تجهيز حلقة.فقط تأكد من أن تنفجر الوقت للحصول على التعليمات البرمجية الخاصة بك تحت 1ms

2) الخيار 2.هذا يفترض تشغيل وقائية نواة لينكس.إعداد غير المستخدمة GPT جنبا إلى جنب مع الخاص بك تشغيل نظام التشغيل.الآن إنشاء يقطع إلى النار بعض شكلي الهامش قبل 1ms يحدث المهلة (أقول 50-75 يوسيك.) عندما يقطع الحرائق على تعطيل المقاطعات و تدور في انتظار 1ms نافذة يحدث ، ثم إدخال آلة الدولة وبالتالي تمكين المقاطعات على الانتظار.وهذا يفسر حقيقة أن كنت تتعاون مع أشياء أخرى في النواة الذي تعطيل المقاطعات.هذا يفترض أن هناك نواة النشاط الذي أقفال خارج المقاطعات لفترة طويلة (أكثر من 100us.) الآن يمكنك قياس دقة الخاص بك إطلاق الحدث وجعل نافذة أكبر حتى يلتقي حاجتك.

أما إذا كنت تحاول تعلم كيف RTOS عمل...أو إذا كنت تحاول حل مشكلة السيطرة مع أكثر من واحد في الوقت الحقيقي المسؤولية...ثم استخدام RTOS.

ماذا عن استخدام "/dev/rtc0" (أو "/dev/rtc") الجهاز و ioctl() واجهة ؟ أعتقد أنه ذو دقة توقيت العداد.ليس من الممكن تعيين معدل فقط إلى 1 مللي ثانية ، ولكن إلى إغلاق قيمة أو 1/1024sec (1024Hz) ، أو إلى تردد أعلى ، مثل 8192Hz.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top