"Entropy ، مصدر ergodic ، مساحة رسائل متعددة الأبعاد ، بتات ، polysemy ، عملية Markov - كل هذه الكلمات تبدو مؤثرة للغاية ، في أي ترتيب يتم وضعها. إذا قمت بترتيبها بالترتيب الصحيح ، فإنها تحصل على محتوى نظري معين. ويمكن لأخصائي حقيقي في بعض الأحيان إيجاد حل للمشاكل العملية اليومية بمساعدتهم. "
جون بيرس "لا أرى أي شر"
هذا المنشور مليء بالمناقشات حول التحسين الدقيق للعمليات الرياضية على MK بموارد محدودة ، وكذلك التقييمات الذاتية لمختلف جوانب تطوير البرامج المدمجة.
أولئك الذين لم يخيف هذا التحذير ، وأنا أسأل تحت القط.
قبل أن ننتقل إلى وصف الإجراء الخاص باستخراج الجذر التربيعي من عدد صحيح ، فإن العملية معكوسة التربيع ، وبالتالي ، الضرب ، دعنا نتحدث عن الأخير.
افترض أن لدينا الفرصة لمضاعفة عدد 8 بت برقم 8 بت ، والحصول على نتيجة 16 بت (8 * 8 = 16) ، كيف يمكننا الحصول على تنفيذ العملية 16 * 16 = 32 بناءً على هذه العملية. الطريقة الواضحة هي تمثيل 16 كمجموع اثنين 8 ، ثم نحصل عليه
(16)*(16)=(1(8)*256+2(8))*1(8)*256+2(8)) =1*1*256*256+1*2*256+2*1*256+2*2
إذا استبدلنا الضرب الناتج في الضرب الناتج ب 256 بضربته اليسرى بثمانية أرقام ، فسوف نحصل على خوارزمية تعمل بشكل كامل. دعونا نقدر الوقت المستغرق في التنفيذ - نحتاج إلى 4 ضربات من 8 * 8 = 16 و 4 إضافات من 4 أرقام بايت 32 + 32 = 32. بالنسبة إلى النوع MK AVR ، نحصل على 4 * 2 + 4 * 4 = 24 دورة ، ولكن هذا من أجل حل "الجبين". دعنا نحاول تحسين النتيجة. حقيقة أننا لا نحتاج إلى 4 ، ولكن 3 إضافات وتعيين واحد ، تعمل على تبسيط الموقف إلى حد ما ، حيث أن التصفير الأولي للنتيجة غير مطلوب ، لكننا لم نأخذ ذلك في الاعتبار ، على الرغم من أنه كان ضروريًا ويجب أن يكون الوقت الإجمالي 24 + 4 = 28 دورة. ولكن ، إذا أخذنا في الاعتبار وجود تحول في المصطلحات الثلاثة الأولى (على التوالي ، لدينا أن انخفاض (وحدتي بايت منخفضة) هو صفر وليس هناك نقطة في إضافته إلى النتيجة) ، ثم سيتعين علينا إضافة ليس 4 بايت ، ولكن ثلاثة واثنين ، مما سيقلل وقت التنفيذ ل 1 * 2 + 2 = 4 تدابير والحصول على 20 التدابير. علاوة على ذلك ، يمكننا الانتباه إلى حقيقة أن المصطلحين الأول والأخير لا يتقاطعان على الإطلاق ، مما يسمح لنا باستبدال الصفر في النصف العلوي من النتيجة بتعيين المدة الأولى وتقليل وقت التنفيذ بدورتين على مدار الساعة إلى 18. بالإضافة إلى ذلك ، باستخدام ميزات الهندسة المعمارية ، أي وجود نقل السجل أزواج ، حفظ اثنين من التدابير الأخرى والنتيجة النهائية - 16 تدابير بدلا من 28 الأصلي - تافه ، ولكن لطيفة.
تعمل طرق التحسين المماثلة للعملية 32 * 32 = 32 ، والتي يمكنك تقليل وقت التنفيذ من 4 * 4 * (2 + 4) + 4 = 100 دورات على مدار الساعة إلى (3 + 5 + 4 + 3) + (5 + 3) +3) + (4 + 3) + 3 = 36 مقاييس ، وهي ليست سيئة على الإطلاق. حسنًا ، في نهاية دراسة الخيارات المختلفة للضرب ، نلاحظ أنه يمكن الحصول على 16 * 16 = 16 في 3 + 3 + 3 = 9 دورات. لاحظ أن جميع هذه الاعتبارات صالحة فقط في ظل افتراض وجود عملية 8 * 8 = 16 للقياسين ، وإذا لم تكن موجودة على الهدف المستهدف ، فلن يكون وقت التنفيذ لجميع الإصدارات الأخرى من العملية أسرع.
دعونا نلخص الوقت اللازم لأداء الضرب (8 * 8 = 8 2 ، 8 * 8 = 16 9 ، 16 * 16 = 16 16 ، 16 * 16 = 32 36) وننظر الآن في المشكلة الأصلية.
نحن بحاجة إلى استخراج الجذر الصحيح التربيعي من الرقم 32 بت H ، أي العثور على أكبر عدد 16 بت n بحيث n * n <= H. كل واحد منا من دورة المدرسة الثانوية يعرف طريقة التقريب المتتالي للجذر التربيعي (n = (N / n '+ n) / 2) ، ولكن عند استخدامه ، يتعين علينا تقسيم الأعداد الصحيحة ، وهذه عملية تستغرق وقتًا طويلاً للغاية.
لذلك ، تم تطوير أنظمة حسابية أخرى ، أحدها هو طريقة التقريب في اتجاه البت ، والتي تبدو في الكود الزائف كما يلي:
- القيم الأولية -> ن = 0 ؛ ب = 0x8000 ؛
- أداء 16 مرة -> إذا ((n + b) * (n + b)> = H) n = n + b؛ ب = ب >> 1 ؛
يمكنك على الفور تقدير الوقت المستغرق في هذا الخيار 16 (عدد بتات النتيجة) * (2 (تنظيم الدورة) +2 (إضافة) + X (الضرب) +5 (المقارنة والحل) +2 (تعديل النتيجة) / 2 (متوسط نصف الوقت) +2 (التحول قليلا)) = 16 * (12 + X). أنت تسأل عن السبب في الصيغة X بدلاً من الرقم 16 ، واتضح أن الكمين كان ينتظرنا ، لأننا نكتب في C ، وليس في مجمّع. الحقيقة هي أنه لا توجد عملية مضاعفة في المكتبة القياسية مع تغيير في عمق البت ولا يمكننا تطبيق 16 * 16 = 32 ، لكننا مضطرون إلى استخدام 32 * 32 = 32 ، مما يؤدي إلى X = 36 بدلاً من X = 16 والرقم النهائي هو 16 * 48 = 768 دورات على مدار الساعة لاستخراج قيمة عدد صحيح من الجذر التربيعي لعدد 32 بت.
بالطبع ، هذا أفضل بكثير من طريقة نيوتن ، لكن قليلاً ، دعنا نرى ما يمكن القيام به.
لذلك ، من الواضح أن معظم الوقت يقضي في حساب نتيجة الضرب التالية. بالطبع ، يمكنك إعادة كتابته في المجمّع واستخدام الإصدار الأقل تكلفة من الضرب ، والحصول على 16 * (12 + 16) = 448 علامة ، لكننا سنترك هذه الطريقة كحل أخير. فكر في العملية بعناية أكبر ونرى أننا لا نحسب ضرب عدد عشوائي بمفرده ، بل بضرب القيمة السابقة مع بعض الزيادة ، ومربع القيمة السابقة معروف. لذلك ، يمكننا اللجوء إلى نظام فرق يستند إلى الصيغة (n + b) * (n + b) = n * n + 2 * n * b + b * b. للوهلة الأولى ، يبدو الأمر مستهزئًا - فبدلاً من الضرب ، نحتاج إلى القيام بأربع قطع وحتى إثنين من الأعداد الطويلة (32 بت). لكن لنبدأ في فهم: لدينا بالفعل n * n ، b * b مع مراعاة أن b = b '/ 2 يسهل الحصول عليها ، مثل b' * b '/ 4 ، وبالمثل 2 * n * b = 2 * n * ب / 2.
يظهر مخطط الحساب التالي:
- القيم الأولية -> nn = 0؛ ن = 0 ؛ ب = 0x8000 ؛ bb = ب * ب ؛
- كرر 16 مرة -> إذا (nn + n + bb> = H) {n = n + b؛ nn = nn + bb + n} ؛ ب ب >> 2 ؛ ب> 1 ؛
نحن نقدر تكاليف التنفيذ 16 * (2 (تنظيم الدورة) +12 (المهمة واثنين من الإضافات) +5 (المقارنة والحل) + (2 (الإضافة) +8 (الإضافتان)) / 2 (متوسط نصف الوقت) +8 (انتقل إلى اليمين بمقدار 2) +2 (تحول إلى اليمين) = 16 * 34 = 544 دورات على مدار الساعة. أفضل من الضرب غير الصحيح 32 * 32 ، ولكن لا يزال لدينا احتياطيات.
ما هي - دعنا ننتبه إلى أغلى عملية - إضافة ومقارنة ما مجموعه 17 دورة على مدار الساعة وإعادة الحلقة الرئيسية للخوارزمية:
2. كرر 16 مرة -> T = H-bb-n ؛ إذا (T> = 0) {H = T؛ n = n + b)؛}؛ ب ب >> 2 ؛ ب> 1 ؛
ثم سيكون وقت تنفيذ الدورة 16 * (2 (تنظيم الدورة) +12 (حساب الفرق الجديد) +1 (مقارنة وحل) + ((4 (مهمة) +2 (إضافة)) / 2 (متوسط نصف الوقت) +8 +2) = 16 * 28 = 448 دورة ، إذا كنت تأخذ في الاعتبار خصوصيات الهندسة المعمارية ، يمكنك حفظ 2 + 2 = 4 * 16 = 64 دورة والاحتفاظ بها في أقل من 400 دورة.
نحصل على نتيجة أفضل قليلاً ، كما هو الحال عند استخدام الضرب الصحيح 16 * 16 = 32 ، ولكن بدون المجمّع ، "في C النقي". ومع ذلك ، هناك ناقص كبير - إذا كان كل شيء بديهيًا في الإصدار مع الضرب ، فإن المتغير ذو مخطط الاختلاف بدون تعليقات يعطي انطباعًا بجلسة السحر الأسود ، يجب أن تختار. لاحظ أيضًا أننا تبادلنا عددًا من المقاييس للذاكرة الإضافية للمتغيرات المتوسطة ، والتي تحدث عادة.
ملاحظة ضرورية - لم نحقق مكسبًا كبيرًا (في بعض الأحيان) بالمقارنة مع الضرب ، نظرًا لأن لدينا تنفيذ سريع قدره 8 * 8 = 16. إذا لم يكن موجودًا في MK (وهذا يحدث) أو لم يكن سريعًا جدًا (وهذا يحدث أيضًا) ، يصبح مخطط الفرق أسرع عدة مرات ، لأنه يستخدم عمليات الإضافة والتغيير القياسية فقط ، والتي يُضمن أن تكون في أي MK.
يبدو أنه لن يعمل بشكل أفضل ، ولكن ، كما يبدو ، لا تزال هناك احتياطيات لزيادة أداء الخوارزمية. دعونا نحاول استخدام طريقة كلاسيكية أخرى للتسارع - فرق تسد. ماذا لو قمت أولاً باستخراج الجذر التربيعي من النصف الأقدم للحجة ، ثم صقلها؟ بادئ ذي بدء ، نظهر أن هذا ممكن بشكل أساسي. في الواقع ، نقدم الوسيطة في النموذج H = H '<< 16 + H' 'والنتيجة في النموذج n = n' << 8 + n ''. نظرًا لأن n '' <256 ، فمن الواضح أن المربع الخاص بها سيكون أقل من مربع العدد n = n '<< 8 + 256 = (n' + 1) << 8. يتبع ذلك أن الجزء الأعلى من النتيجة لا يتجاوز الجذر التربيعي للجزء الأعلى من الوسيطة.
يتم ترك تنفيذ هذا النهج للقارئ الفضولي.
ما الذي سوف يعطينا هذا النهج ، لأن إجمالي عدد التكرارات سيبقى دون تغيير - يمكننا تنفيذ النصف الأول من التكرار بأرقام أقصر طولًا ، وهذا يؤدي إلى انخفاض في تكاليف الوقت. يمكن تطبيق هذا النهج على المتغير مع الضرب ومتغير الاختلاف ، وسيصل إجمالي المكسب إلى ربع إجمالي وقت التنفيذ.
ملاحظة ضرورية - إن قابلية تطبيق هذا النهج ليست واضحة على الإطلاق ، عند التنفيذ لأعضاء الكنيست مثل AVR ، يحدث تسريع التنفيذ ، ولكن بالنسبة لبعض الهياكل ، على سبيل المثال بالنسبة إلى x86 ، ظهر تباطؤ العملية بشكل غير متوقع. على ما يبدو ، يعد العمل مع البيانات غير الأصلية (16 بت) في هذه البنية أكثر تكلفة في الوقت المناسب مقارنة مع البيانات الأصلية (32 بت). لم أقم بإجراء دراسة عميقة ، لكن الحقيقة حدثت ، ويجب أن أبلغ عنها لتجنب سوء الفهم.
لكن هذا ليس كل شيء. نظرًا لأننا شرعنا بالفعل في طريق الانفصال والهيمنة ، فلماذا لا نمضي قدمًا إلى أبعد من ذلك - استخرج الجذر من البتات خطوة بخطوة ، بدءًا من الأقدم منها (بدءًا بالأصغر سناً هو نتائج عكسية في حالتنا). نظام الخوارزمية هو نفسه - نضيف الجزء التالي من البتات في النتيجة الحالية ونحاول إضافة البتة التالية إلى النتيجة ، ونتحقق مما إذا كنا قد تجاوزنا قيمة الجذر. الخصوصية هي أنه يمكننا فقط التحقق من البتات العالية للحجة ، حتى نصل إلى البتات المنخفضة.
عند التنفيذ ، نستخدم خدعة أخرى - بدلاً من نقل أرقامنا المخصومة إلى اليمين ، سننقل حجتنا المتناقصة إلى اليسار ، ولن يتغير المعنى ، وتزداد السرعة. يزداد بسبب عاملين - 1) يكفي أن نطرح فقط أرقام 16 بت (هناك خصوصية واحدة ، ويجب أخذها في الاعتبار ، لكننا نفكر في دراسة حالة ، التصويت) و 2) لسنا بحاجة إلى تحويل مربع البت التالي ، لأنه سيكون دائمًا يساوي واحد. لكن عليك أن تدفع ثمن كل شيء في هذا العالم ، وسنتحول من الفارق الموسع (6 بايت) إلى اليسار ، وبمقدار 2 بت لكل ساعة. نحن ننظر إلى رمز الزائفة
- القيم الأولية -> ن = 0 ؛ H1 = 0 ؛
- كرر 16 مرة -> (H1 ، H) << 2 ؛ T = H1-n-1 ؛ if (T> 0) {H1 = T؛ n = n + 2} ؛ ن << 1 ؛
وتقييم وقت التنفيذ ، الحصول على 16 * (12 (التحول الموسّع) +4 (حساب الفرق) +1 (الحل) +2 (الاحالة) +1 (الزيادة) +2 (التحول)) = 16 * 22 = 352 مقاييس ، ربما والنتيجة قريبة من الكمال. عند تنفيذ هذا الخيار ، هناك عيوب صغيرة ، أترك هذا مرة أخرى للقارئ الفضولي (حسنًا ، يحصل على الوظيفة).
حسنًا ، في ختام القسم الذي دفعني إلى كتابة هذا المنشور. هناك مكتبة McuCpp رائعة تمامًا ، تأليف أنتون تشيزوف ، والتي ، استنادًا إلى فئة التأليف loki ، تعد Andriescu أنيقة بشكل غير عادي (أيضًا ، بقدر ما يمكن تطبيق الأناقة على قوالب C ++) ، يمكنك العمل باستخدام دبابيس <a «
github.com/KonstantinChizhov/ Mcucpp »لدي احترام كبير للمؤلف المذكور (كلاهما) ومؤخراً ، فيما يتعلق بالظروف التي
سأناقشها لاحقًا ، نظرت إلى مصادر هذه المكتبة وأعجبت بها مرة أخرى.
ومع ذلك ، من بين الملفات الأخرى رأيت template_utils.h ، حيث تم تنفيذ بعض الإجراءات الروتينية ، ومن بينها جذر صحيح لعدد 32 بت. حقيقة أنه يستخدم أبسط خوارزمية تقريب تسلسلي مع الضرب ليست مخيفة ، لأن هذه الخوارزمية لا تفقد الكثير في السرعة ، ولكن في الفهم فإنه يعطي الكثير من النقاط في المستقبل ولا يزال يفوز. لكنني لا أحب حقيقة أنه تم تنفيذه بشكل غير دقيق إلى حد ما (من حيث الأداء) ، لأن "الأطفال يمكنهم رؤيته". يتمثل عدم الدقة في تمثيل الرقم المحدد بـ 32 بت ، لأننا نعلم تمامًا أن جذر رقم 32 بت لن يتجاوز 16 بت ، فلماذا نحتاج إلى تحويل صفر بايت. وهذا هو الحال تمامًا عندما لا يفكر المترجم نفسه في إجراء التحسين وينبغي أن يساعده.
تحويل وظيفة واضحة
static inline uint32_t sqrt(uint32_t value) { uint16_t result = 0; uint16_t add = 0x8000; for (uint8_t i = 16; i !=0; ++i) { uint32_t rootGuess = result | add; uint32_t guess = rootGuess * rootGuess; if (value >= guess) { result = rootGuess; } add >>= 1; } return result; }
يسمح لنا بحفظ دورتين على إزاحة بت و دورتين على إنشاء العامل التالي في كل دورة ، وتنظيم الدورة في النموذج المحدد هو 4 دورات أخرى (أعرف أن المترجم يمكنه القيام بهذا التحسين بالنسبة لنا ، لكن لماذا لا تساعده بشكل صريح ) ، وهو أمر جيد جدًا بالنسبة لتغييرات الأكواد التجميلية البحتة التي لا تؤثر على شموليتها على الأقل.
ملاحظة لاحقة - تعليق واحد جعلني أعتقد أنه سيكون أكثر صحة
for (uint_fast8_t i= ...)
شكرا لك أوليغ للمساعدة.
الكرز الموجود على الكعكة هو وظيفة استخراج الجذر التربيعي بأكمله من رقم الإشارة الموجود أدناه ، والذي يدعي أن √-1 = 65635 = -1 ، ومن ناحية أخرى ، لماذا لا ، ما هو أسوأ من أي نتيجة أخرى ، ليس لدينا استثناء تسبب في MK ، والجذر التربيعي بأكمله من رقم سالب غير موجود.
حسنًا ، الاستنتاج حول سبب التفت إلى مكتبة أنطون تشيزوف. تمت مطالبتي بنشر منشور حديث بخصوص RTOS المحلي لـ MK تحت اسم MAX (MultiAgent Coherent System) - راجع الرسم البياني للنشر الذي تم الإعلان عنه من قِبل منشئوه ، والذي تم نقله إلى MK الذي أنتجته Milander. ملاحظة - هذه المشاركة ليست بأي حال من الأحوال مواد ترويجية وستتضح قريبًا للقراء. من mcucpp السابق ذكره ، استخدم مؤلفو OS تطبيق المخزن المؤقت الحلقي (دون التقليل على الإطلاق من مزايا مكتبة Anton ، لا بد لي من القول إن هذا الجزء منه ليس مرجعًا ، ولا تزال هذه الصيغة ضعيفة ، والتي كتبت عنها في منشور آخر لم أكن نشره على الإطلاق). نظرًا لأنني أعمل عن قرب مع مرافق الإنتاج في Milander ، فإن المادة تهتم بي وقد تابعت الرابط إلى موقع المطورين.
هنا تبدأ صرخة ياروسلافنا القادمة.
في العام الماضي ، عندما تم الإعلان عن إنشاء RTOS المحلي لأول مرة ، قمت بتنزيل وصف لمنتج البرنامج من هذا الموقع ، لكن بطريقة ما لم تصل يدي إلى الدراسة. حسب طبيعة نشاطي ، يجب أن أتعامل مع المكونات المحلية (أفهم ما يكفي ...) ، لذلك سيكون من الجيد امتلاك البرنامج المناسب. تذكر أنه في إصدار العام الماضي ، تحدث مدير الشركة عن ملايين الروبل التي تم إنفاقها على التطوير والفريق الكبير الذي يعمل على إنشاء منتج البرنامج هذا ، قررت أن أرى الإصدار التجريبي متاحًا للتنزيل مجانًا ، وأنا هنا أشارك النتائج.
بادئ ذي بدء ، انخفض الوصف لمدة نصف عام تقريبًا في الحجم (من 115 إلى 55 صفحة) ، وإذا كان اختفاء التطبيقات التي تحتوي على لقطات شاشة تصف عملية إطلاق المنتجات الثالثة من "وصف البرنامج" مرحبًا به ، فليس مظهر هذه المواد (الذي تم إنشاؤه باستخدامه) لقد أمضيت ، رغم أنني لست مهمًا للغاية ، لكنني لا أزال أتحمل الوقت والمال) في وثيقة مثل "دليل المشغل" فأنا شخصياً أشعر بالحيرة. علاوة على ذلك ، في الجملة الأولى من المستند ، نرى انحرافًا صريحًا عن الحقيقة ، لأن RTOS نفسه لا يُقصد به "إنشاء برامج" بأي شكل من الأشكال ، لسبب ما لم يسمح المؤلفون لأنفسهم مثل هذه العبارات في الإصدار السابق من المستند ، فإن تأثير خدمة التسويق محسوس. إنه يسلم أيضًا أنه إذا كان الوصف موجودًا في مجلد / docs الخاص بدليل الجذر ، وكان هذا منطقيًا ، فقد تم إخفاؤه الآن في / toolchain / macs / docs ، كما قالوا في شبابي ، "الجميع غاضبون بطريقته الخاصة" ، ننتقل.
أبدأ في إلقاء نظرة على الوصف ، والنظر إلى الكود المصدري (يتم تضمينه في الإصدار التجريبي) ، وفي الحيرة ، أجد عدم وجود أي برامج تشغيل للأجهزة الطرفية مهيأة للعمل مع نظام التشغيل هذا. أولاً ، اقترحت أن هذه ميزة للتجربة ، ثم في المنتدى في المعلومات من المطورين أجد أنه لا يوجد بالفعل أي برامج تشغيل ، لكنهم يعملون عليها. أكثر من ستة أشهر (ستة أشهر ، كارل ، في الواقع ما يقرب من عام) منذ أن تم إصدار نظام التشغيل لنظام التشغيل MK ، ويعملون على برامج التشغيل. بطبيعة الحال ، أو كما يقولون ، من نافلة القول أنه لا يمكن الحديث عن أي منتجات ثالثة (نظام الملفات ، مكدس الشبكة ، كومة USB). فكرة مضحكة من المؤلفين حول متطلبات تطوير البرمجيات لـ MK ، حسنًا ، قادت مرة أخرى.
بمعنى أن نظام التشغيل المعلن ، والذي تتمثل الميزة البارزة فيه في تنظيم التفاعل داخل نظام متعدد وحدات التحكم ، ليس لديه وسائل أصلية لتنظيم هذا التفاعل. ما لدينا في الخلاصة - ولدينا إدارة المهام ، في الواقع sheduler ، خدمة الحد الأدنى من الوقت ووسائل مزامنة المهام ، وهذا كل شيء - مضحك ، على أقل تقدير. حسنًا ، سوف ننظر إلى أبعد من ذلك ، حتى في مثل هذه المجموعة من المكونات ، من الممكن إيجاد حلول مثيرة للاهتمام ، خاصةً عندما ترى أنه في موقع واحد (وليس الشركة المصنعة) رأيت "فحصًا" للكود المصدر لنظام التشغيل هذا بالرجوع إليه. قال هذا المستند أن منتج البرنامج لا يستخدم مكونات (استيراد) جهة خارجية وأنه أصلي ، وسيكون من الضروري التأكد من ذلك.
الملاحظة الأولى هي أنه إذا كنت تستخدم ملفات ARM الأصلية المضمنة في حزمة التعليمات البرمجية المصدر للانتقال إلى بنية Cortex-M0 (1986 BE1T) ، فهذا يشبه إلى حد بعيد استخدام أجزاء النص الخارجية (المستوردة) - أعتقد شخصياً أن هذا هو الاستخدام ، ولكن ربما لا أعرف كل شيء. حسنًا ، وثانيًا ، الكود الأصلي لمصطلح sheduler وعناصر إدارة المهام ذات الصلة أصلي وليس له نظائر (على الأقل لا أعرف أيًا) ، ولكن هذا هو نوع الأصالة عندما أتذكر عبارة الشامان القديمة من فيلم "The Evil Spirit of Yambuya" حول الصياد العظيم: "اقطع الأذنين ، طهي وأكلت - هل كنت ستخمن؟"
سأحاول شرح - في تصميم نظام التشغيل بشكل عام وفي RTOS على وجه الخصوص ، إحدى المشكلات الصعبة هي مشكلة ضمان وصول جميع العمليات في النظام إلى وقت تشغيل مورد مشترك. , ( ) , . ( , , MPU), .
, , , , . (1) , , FREE-RTOS 20 , ( , , ).
, , 60 ( ). , . ( ) , (, ) ,
- (n)
- — , 20*(3*4)=240 . , , , .
, , ( , , ) . , ( , ). mcucpp ( — ), .
— - , .
(, , ) - — . ( , , ), , ( 2013) 1 , 2019 .
, :
- ( , ) ( , , , , ),
- ( ),
- () 2,
- HAL, CMSIS (- ),
- ,
- ,
- (3rd part), ,
- ,
- ,
- , (, , ..) « »,
- , , ( , , MIT , « »), , (?).
, , , 5 ( , , 10, IDE). , , .
, , , .
, , () .