একটি মাইক্রোকন্ট্রোলার দেওয়া যা নিম্নলিখিত কোডটি চালাচ্ছে:
volatile bool has_flag = false;
void interrupt(void) //called when an interrupt is received
{
clear_interrupt_flag(); //clear interrupt flag
has_flag = true; //signal that we have an interrupt to process
}
int main()
{
while(1)
{
if(has_flag) //if we had an interrupt
{
has_flag = false; //clear the interrupt flag
process(); //process the interrupt
}
else
sleep(); //place the micro to sleep
}
}
ধরুন if(has_flag)
শর্তটি মিথ্যা হিসাবে মূল্যায়ন করে এবং আমরা ঘুমের নির্দেশ কার্যকর করতে চলেছি। রাইট আগে আমরা ঘুম নির্দেশ চালানো, আমরা একটি বিঘ্ন পাবেন। আমরা বাধা ছাড়ার পরে, আমরা ঘুমের নির্দেশ কার্যকর করি।
এই মৃত্যুদন্ডের ক্রমটি কাম্য নয় কারণ:
- মাইক্রোকন্ট্রোলার ঘুম থেকে ওঠার পরিবর্তে ঘুম থেকে যায়
process()
। - এরপরে কোনও বাধা না পেলে মাইক্রোকন্ট্রোলার কখনই জাগতে পারে না।
- কলটি
process()
পরবর্তী বাধা না দেওয়া পর্যন্ত স্থগিত করা হয়েছে।
এই রেসের শর্তটি যাতে না ঘটে সে জন্য কোডটি কীভাবে লেখা যেতে পারে?
সম্পাদন করা
এটিএমতেগায় কিছু মাইক্রোকন্ট্রোলারদের একটি স্লিপ সক্ষম বিট থাকে যা এই অবস্থার সৃষ্টি হতে বাধা দেয় (এটি নির্দেশ করার জন্য আপনাকে কেভেগোরোকে ধন্যবাদ)। জে রবার্টস একটি উদাহরণ প্রয়োগের প্রস্তাব করে যা এই আচরণটির উদাহরণ দেয়।
অন্যান্য মাইক্রো, যেমন পিআইসি 18 তে রয়েছে, এই বিটটি নেই, এবং সমস্যাটি এখনও ঘটে। যাইহোক, এই মাইক্রোগুলি এমনভাবে তৈরি করা হয়েছে যে গ্লোবাল ইন্টারপ্যান্ট সক্ষম বিট সেট হয়েছে কিনা তা বিবেচনা না করেই বাধা এখনও জেগে উঠতে পারে (এটি নির্দেশ করার জন্য আপনাকে সুপারক্যাটকে ধন্যবাদ)। এই জাতীয় স্থাপত্যগুলির জন্য সমাধান হ'ল ঘুমানোর আগে বৈশ্বিক বাধা নিষ্ক্রিয় করা। ঘুমের নির্দেশ কার্যকর করার আগে যদি কোনও বিঘ্ন ঘটে তবে বাধা হ্যান্ডলার কার্যকর হবে না, মূলটি জেগে উঠবে এবং একবার বিশ্বব্যাপী বাধা পুনরায় সক্ষম হয়ে গেলে, বাধা হ্যান্ডলারটি কার্যকর করা হবে। সিউডো-কোডে, বাস্তবায়নটি দেখতে এরকম হবে:
int main()
{
while(1)
{
//clear global interrupt enable bit.
//if the flag tested below is not set, then we enter
//sleep with the global interrupt bit cleared, which is
//the intended behavior.
disable_global_interrupts();
if(has_flag) //if we had an interrupt
{
has_flag = false; //clear the interrupt flag
enable_global_interrupts(); //set global interrupt enable bit.
process(); //process the interrupt
}
else
sleep(); //place the micro to sleep
}
}
interrupt_flag
হিসাবে করব int
এবং প্রতিবার বাধাগ্রস্থ হওয়ার সাথে সাথে এটি বাড়িয়ে তুলব । তারপর পরিবর্তন if(has_flag)
করার জন্য while (interrupts_count)
এবং তারপর ঘুম। তবুও, আপনি যখন লুপটি প্রস্থান করেছেন তখন বাধা সৃষ্টি হতে পারে। যদি এটি কোনও সমস্যা হয়, তবে প্রক্রিয়াটি নিজেই বাধা হয়ে যায়?