एम्बेडेड सिस्टम के लिए थ्रेड विकल्प
मैं वर्तमान में इलेक्ट्रिकल इंजीनियरिंग की पढ़ाई कर रहा हूं। महामारी के कारण, मेरी कक्षाएं निलंबित कर दी गईं और मैं इस समय का उपयोग इलेक्ट्रॉनिक्स और प्रोग्रामिंग के बारे में अधिक जानने के लिए कर रहा हूं।
मैं वर्तमान में Pic16f628a
कुछ सुविधाओं के साथ एक डिजिटल घड़ी बनाने के लिए एक और सामान्य डिजिटल डिस्प्ले का उपयोग करने की कोशिश कर रहा हूं । बात यह है कि, मुझे निष्पादन समय में एक बटन दबाने वाले मेनू तक पहुंचना होगा, जबकि घड़ी प्रदर्शित की जा रही है। आम तौर पर मैं घड़ी प्रदर्शन के लिए एक थ्रेड कहता हूं और मुख्य थ्रेड इनपुट के लिए देख रहा होगा, लेकिन पिक कंट्रोलर की सादगी के कारण मैं संसाधन का उपयोग नहीं कर सकता।
तो, मेरा C कोड (अभी तक विशेष रूप से लागू नहीं किया गया है pic) कुछ इस तरह है:
void display_timer(){
static struct current_time timer;
static int is_time_set = 0;
set_current_time(&timer, &is_time_set);
while (is_time_set){
system("clear");
printf("########\n");
printf("%d:%d:%d\n", timer.HOURS, timer.MINUTES, timer.SECONDS);
printf("########\n");
sleep(1);
update_timer(&timer, &is_time_set);
}
}
int main ()
{
while (1){
display_menu();
}
}
नींद के दौरान (), नियंत्रक को नए इनपुट के लिए देखने और इसके अनुरूप कार्य करने में सक्षम होना चाहिए।
एक विकल्प हालांकि मैं एक बटन दबाने के लिए राज्य मशीन का उपयोग करना था, नींद समारोह को 4 या 8 अंतराल में विभाजित करना, कुछ इस तरह से:
while (is_time_set){
system("clear");
printf("########\n");
printf("%d:%d:%d\n", timer.HOURS, timer.MINUTES, timer.SECONDS);
printf("########\n");
for (int i = 0; i<8; i++){
if (state_machine_input == 1){state_machine_input = 0; break;}
sleep(1/8);
}
update_timer(&timer, &is_time_set);
यह किया जा सकता है, लेकिन मैं इस बात की सराहना करता हूं कि यदि मुझे परियोजना में अधिक जटिलता नहीं डालनी है, उदाहरण के लिए एक और राज्य मशीन को जोड़ना होगा। इस कार्यक्षमता को लागू करने के लिए मैं सॉफ्टवेयर के थर्मस में क्या कर सकता हूं?
जवाब
थ्रेडिंग माइक्रोकंट्रोलर प्रोग्रामिंग की तुलना में उच्च स्तर की अवधारणा है। सीधे शब्दों में, थ्रेड्स को एक अनुसूचक के रूप में कार्यान्वित किया जाता है जो टाइमर इंटरप्ट का उपयोग करता है, जो बदले में प्रोग्राम काउंटर + स्टैक पॉइंटर आदि को बचाता है और उन्हें विभिन्न स्थानों पर सेट करता है। इसलिए इंटरप्रिट्स का उपयोग करके एक समान अवधारणा को लागू करना काफी संभव और आसान है - इस लाभ के साथ कि आप सामान्य मल्टी-थ्रेडिंग के बजाय विशेष इंटरप्ट प्राप्त करते हैं।
यह PIC की तरह प्रतिबंधित विरासत 8 कड़वे के साथ ऐसा करने का एकमात्र समझदार तरीका है, जो स्टैक उपयोग के लिए बेहद सीमित है। माइक्रोकंट्रोलर्स के लिए लिखे गए थ्रेड लिबास का उपयोग करने के बारे में भी भूल जाएं। यह केवल अत्यधिक ब्लोट और जटिलता को जोड़ देगा, कुछ भी नहीं प्राप्त करने के लिए। पीसी प्रोग्रामिंग अवधारणाओं को एम्बेडेड दुनिया में खींचना सामान्य रूप से एक बुरा विचार है।
आपको क्या करना चाहिए, अपने बटन को एक चक्रीय टाइमर अवरोध के अंदर स्कैन करना है जिसे एक बार प्रति 10ms या तो निष्पादित किया जाता है। अंतरायन के अंदर से, आप बटनों को पराग करते हैं और पिछले उद्देश्यों के साथ पढ़े गए बटन की तुलना, उद्देश्यों की पूर्ति के लिए करते हैं। इसका परिणाम मुख्य कार्यक्रम के साथ साझा किए गए एक चर में संग्रहीत किया जाता है, जिसे volatile
दौड़ की स्थिति से संरक्षित और घोषित किया जाता है । चूंकि आप केवल इंटरप्ट से अंदर के वेरिएबल को लिखते हैं, इसलिए यह सुनिश्चित करने के लिए पर्याप्त सुरक्षा हो सकती है कि रीड्स 8 बिट्स हों, लेकिन आप सुनिश्चित होने के लिए डिसाइड करें। इसके बारे में अधिक जानकारी यहाँ है: एम्बेडेड सी विकास में वाष्पशील का उपयोग करना ।
इंटरप्ट का उपयोग करें
बटन दबाते ही आप कुछ कोड चलाना चाहते हैं? पिन-चेंज-इंटरप्ट का उपयोग करें
आप एक निश्चित अंतराल पर कुछ करना चाहते हैं? टाइमर-अवरोध का उपयोग करें
एक तरह से, माइक्रोकंट्रोलर का हार्डवेयर एक 'थ्रेड' चलाता है जो बीच के स्रोतों की निगरानी करता है, और प्रत्येक घटना के लिए एक 'कॉलबैक' या इंटरप्ट-रूटीन चलाता है।
व्यवधान को निष्पादित करते समय मुख्य कार्यक्रम स्वचालित रूप से रोक दिया जाता है।
इंटरप्ट और मुख्य कोड के बीच डेटा साझा करने का एक सामान्य तरीका volatile
वैश्विक चर के माध्यम से है और इन ग्लोबल्स से डेटा पढ़ने पर अस्थायी रूप से बाधित होता है जब वे नियंत्रक के शब्द-आकार से अधिक होते हैं (लगभग हमेशा 8 बिट नियंत्रक पर)
मैं शायद एक सहकारी मल्टीटास्किंग लाइब्रेरी का सुझाव दूंगा। एक जो मैंने अतीत में इस्तेमाल किया है वह है प्रोटोथ्रेड्स:http://www.dunkels.com/adam/pt/
कोई भी सभ्य सहकारी मल्टीटास्किंग लाइब्रेरी चीजों की निगरानी रखने के लिए आवश्यक अंतर्निहित राज्य मशीन को दूर करने में मदद करेगी।
सौभाग्य।
जब यह एम्बेडेड सिस्टम की बात आती है, तो मल्टीटास्किंग के साथ सामान्य रूप से अलग-अलग दृष्टिकोण होते हैं:
- पोलिंग या कोऑपरेटिव मल्टीटास्किंग : सब कुछ एक अनंत लूप में किया जाता है और कार्यों को न्यूनतम समय के लिए संभव होने के लिए डिज़ाइन किया गया है और देरी से बचने के लिए जितनी जल्दी हो सके मुख्य निष्पादन पर लौटना है। ध्यान दें कि इस वास्तुकला के लिए उपयुक्त कार्य वह नहीं हो सकते हैं जो आप उच्च-स्तरीय अवधारणा के संदर्भ में सोचेंगे, उदाहरण के लिए आपके आवेदन में एक कार्य हो सकता है
update_display
और दूसरा कार्य हो सकता हैcheck_button
और आप एक लूप का निर्माण करेंगे:
while(1){
check_buttons();
update_display();
sleep(0.1); //seconds
}
रुकावट : हार्डवेयर से जुड़े सभी संभावित आदानों को बाधित किया जाता है और मुख्य निष्पादन उन चीजों के लिए छोड़ दिया जाता है जिन्हें बीच में नहीं रखा जा सकता है (ऐसा कुछ भी नहीं हो सकता है, जिसमें आमतौर पर माइक्रोकंट्रोलर को बिजली की खपत को कम करने के लिए स्लीप मोड में रखा जाता है। आमतौर पर उपयोग किए जाने वाले विशेष माइक्रोकंट्रोलर और कंपाइलर पर निर्भर होता है।
RTOS : माइक्रोकंट्रोलर कितनी शक्ति प्रदान करता है, इसके आधार पर, रियल-टाइम ऑपरेटिंग सिस्टम (RTOS) चलाना संभव हो सकता है, जो कार्य या थ्रेड बनाने के लिए API प्रदान कर सकता है। यह एप्लिकेशन और हार्डवेयर क्षमताओं पर निर्भर करता है, और शैक्षिक उदाहरणों के लिए आवश्यक नहीं होना चाहिए (या सलाह, इमो)
इस बात पर भी विचार करें कि आवेदन की समग्र वास्तुकला को तय करने में एक और महत्वपूर्ण हिस्सा कार्यों में विभाजन है और वे कैसे सहयोग करते हैं। उपयोग किए जाने वाले प्रतिमानों में से एक स्टेट मशीन्स है (लिंक सामान्य विकिपीडिया पृष्ठ पर है जो भारी हो सकता है, एम्बेडेड प्रोग्रामिंग के लिए विशिष्ट सरल संसाधन आपकी पाठ्यपुस्तक या Google पर पाया जा सकता है)।
अधिकतर, 8-बिट डिवाइसों में सीमित स्रोत होते हैं। मुझे लगता है कि सरल समाधान 8-बिट PICs में बेहतर समाधान है।
आप 2 अलग-अलग कार्यों के लिए हार्डवेयर टाइमर बना सकते हैं। एक ध्वज सेट करें और अपने अनंत लूप में ध्वज की जांच करें, कार्य करें और ध्वज को रीसेट करें। देरी का उपयोग न करें। यह विधि आपके अनंत लूप में आपके कार्यों को करने की गारंटी देती है, अगर आपके झंडे ऊपर हैं।
लेकिन, आपको यह जानना होगा कि झंडों को ठीक करते समय कार्यों का निष्पादन नहीं किया जाता है। यदि एक ही समय में दो झंडे लगाए गए हों, तो आप यह नहीं जान सकते हैं कि कौन सा पहले निष्पादित किया गया है। क्योंकि तुम नहीं जानते कि अनंत पाश में कहां है। लेकिन, यह महत्वपूर्ण नहीं है कि समय के लिए महत्वपूर्ण इंटरफेसिंग अनुप्रयोग हों।