PIC माइक्रोकंट्रोलर पर मल्टीटास्किंग


17

इन दिनों मल्टीटास्किंग महत्वपूर्ण है। मुझे आश्चर्य है कि हम इसे माइक्रोकंट्रोलर और एम्बेडेड प्रोग्रामिंग में कैसे प्राप्त कर सकते हैं। मैं एक प्रणाली डिजाइन कर रहा हूं जो कि PIC माइक्रोकंट्रोलर पर आधारित है। मैंने C का उपयोग करके MplabX IDE में इसका फ़र्मवेयर डिज़ाइन किया है और फिर इसके लिए विजुअल स्टूडियो में C # का उपयोग करके एक एप्लिकेशन डिज़ाइन किया है।

जब से मैंने समानांतर कार्यों को लागू करने के लिए डेस्कटॉप पर सी # प्रोग्रामिंग में थ्रेड्स का उपयोग करने के लिए उपयोग किया है, क्या मेरे माइक्रोकंट्रोलर कोड में ऐसा करने का एक तरीका है? MplabX IDE प्रदान करता है, pthreads.hलेकिन यह बिना किसी कार्यान्वयन के सिर्फ एक स्टब है। मुझे पता है कि FreeRTOS सपोर्ट है लेकिन इसके इस्तेमाल से आपका कोड और अधिक जटिल हो जाता है। कुछ फोरम का कहना है कि इंटरप्ट को मल्टी टास्किंग के रूप में भी इस्तेमाल किया जा सकता है, लेकिन मुझे नहीं लगता कि इंटरप्ट्स थ्रेड्स के बराबर हैं।

मैं एक सिस्टम डिजाइन कर रहा हूं, जो कुछ डेटा को UART को भेजता है और उसी समय उसे (वायर्ड) ईथरनेट के माध्यम से वेबसाइट पर डेटा भेजने की आवश्यकता होती है। एक उपयोगकर्ता वेबसाइट के माध्यम से आउटपुट को नियंत्रित कर सकता है लेकिन आउटपुट 2-3 सेकंड की देरी से चालू / बंद हो जाता है। तो वह समस्या है जिसका मैं सामना कर रहा हूं। क्या माइक्रोकंट्रोलर में मल्टी टास्किंग का कोई हल है?


थ्रेड्स का उपयोग केवल प्रोसेसर पर किया जा सकता है जो OS चलाता है, क्योंकि थ्रेड्स प्रक्रिया का हिस्सा हैं, और प्रक्रियाएं केवल OSes में उपयोग की जाती हैं।
टिकटैक ओट

@Zola हाँ तुम सही हो। लेकिन नियंत्रकों के मामले में क्या?
विमान


1
क्या आप बता सकते हैं कि आपको सही मल्टीटास्किंग की आवश्यकता क्यों है और एक राउंड-रॉबिन कार्य दृष्टिकोण या एक चयन () लूप या समान के आधार पर आपके सॉफ़्टवेयर को यथोचित रूप से लागू नहीं कर सकता है?
whatsisname 10

2
ठीक है, जैसा कि मैंने पहले ही कहा था, मैं डेटा भेज रहा हूं और प्राप्त कर रहा हूं और उसी समय ईथरनेट को डेटा भेज रहा हूं और प्राप्त कर रहा हूं। इसके अलावा मुझे समय के साथ एसडी कार्ड में डेटा को बचाने की भी आवश्यकता है, इसलिए हां DS1307 RTC शामिल है और EEPROM भी शामिल है। अब तक मेरे पास केवल 1 UART है लेकिन कुछ दिनों के बाद हो सकता है कि मैं 3 UART मॉड्यूल से डेटा भेज रहा / प्राप्त करूंगा। वेबसाइट दूरस्थ स्थान पर स्थापित 5 विभिन्न प्रणालियों से भी डेटा प्राप्त करेगी। यह सब समानांतर होना चाहिए, लेकिन इसके समानांतर नहीं बल्कि कुछ सेकंड की देरी के साथ। !
विमान

जवाबों:


20

मल्टीटास्किंग ऑपरेटिंग सिस्टम के दो मुख्य प्रकार हैं, प्रीमेप्टिव और कोऑपरेटिव। दोनों सिस्टम में कई कार्यों को परिभाषित करने की अनुमति देते हैं, अंतर यह है कि कार्य स्विचिंग कैसे काम करता है। बेशक एक ही कोर-प्रोसेसर के साथ केवल एक कार्य वास्तव में एक समय में चल रहा है।

दोनों प्रकार के मल्टीटास्किंग ओएस को प्रत्येक कार्य के लिए एक अलग स्टैक की आवश्यकता होती है। तो यह दो बातों का तात्पर्य करता है: पहला, कि प्रोसेसर रैम में कहीं भी स्टैक्स को रखने की अनुमति देता है और इसलिए स्टैक पॉइंटर (एसपी) को चारों ओर ले जाने के निर्देश हैं - यानी कोई विशेष उद्देश्य हार्डवेयर स्टैक नहीं है जैसे कि लो-एंड पर है पीआईसी की। यह PIC10, 12 और 16 श्रृंखला को छोड़ देता है।

आप लगभग पूरी तरह से सी में एक ओएस लिख सकते हैं, लेकिन टास्क स्विचर, जहां एसपी को घूमना पड़ता है, विधानसभा में होना चाहिए। कई बार मैंने PIC24, PIC32, 8051 और 80x86 के लिए टास्क स्विचर्स लिखे हैं। प्रोसेसर के आर्किटेक्चर के आधार पर हिम्मत बिल्कुल अलग है।

दूसरी आवश्यकता यह है कि कई ढेरों के लिए पर्याप्त रैम है। आमतौर पर एक स्टैक के लिए कम से कम कुछ सौ बाइट्स चाहिए; लेकिन प्रति कार्य सिर्फ 128 बाइट्स पर, आठ स्टैक के लिए 1K बाइट्स RAM की आवश्यकता होती है - आपको प्रत्येक कार्य के लिए समान आकार स्टैक आवंटित करने की आवश्यकता नहीं है। याद रखें कि आपको वर्तमान कार्य को संभालने के लिए पर्याप्त स्टैक की आवश्यकता है, और इसके नेस्टेड सबरूटीन्स के लिए किसी भी कॉल की आवश्यकता है, लेकिन एक बाधा कॉल के लिए भी स्टैक स्पेस है क्योंकि आप कभी नहीं जानते हैं कि कब क्या होने वाला है।

यह निर्धारित करने के लिए काफी सरल तरीके हैं कि आप प्रत्येक कार्य के लिए कितना स्टैक उपयोग कर रहे हैं; उदाहरण के लिए आप किसी विशेष मान के सभी स्टैक को इनिशियलाइज़ कर सकते हैं, 0x55 कह सकते हैं, और थोड़ी देर के लिए सिस्टम को चला सकते हैं और फिर मेमोरी को रोक और जांच सकते हैं।

आप यह नहीं कहते कि आप किस प्रकार के पीआईसी का उपयोग करना चाहते हैं। अधिकांश PIC24 और PIC32 में मल्टीटास्किंग OS चलाने के लिए बहुत जगह होगी; PIC18 (रैम में केवल 8-बिट PIC में स्टैक होने के लिए) की अधिकतम रैम 4K है। इतना सुंदर iffy है।

सहकारी मल्टीटास्किंग (दो का सरल) के साथ, कार्य स्विचिंग केवल तभी किया जाता है जब कार्य ओएस पर अपना नियंत्रण वापस देता है। यह तब होता है जब भी कार्य को कुछ फ़ंक्शन करने के लिए ओएस रूटीन को कॉल करने की आवश्यकता होती है, जिसके लिए वह प्रतीक्षा करेगा, जैसे कि I / O अनुरोध या टाइमर कॉल। यह ओएस को स्टैक स्विच करने के लिए आसान बनाता है, क्योंकि यह सभी रजिस्टरों और राज्य की जानकारी को बचाने के लिए आवश्यक नहीं है, एसपी को केवल किसी अन्य कार्य पर स्विच किया जा सकता है (यदि कोई अन्य कार्य चलाने के लिए तैयार नहीं हैं, तो एक निष्क्रिय स्टैक है) नियंत्रण दिया गया)। यदि वर्तमान कार्य के लिए OS कॉल करने की आवश्यकता नहीं है, लेकिन कुछ समय से चल रहा है, तो सिस्टम को उत्तरदायी बनाए रखने के लिए इसे स्वेच्छा से नियंत्रण छोड़ने की आवश्यकता है।

सहकारी मल्टीटास्किंग के साथ समस्या यह है कि यदि कार्य कभी नियंत्रण नहीं छोड़ता है, तो यह सिस्टम को हॉग कर सकता है। केवल यह और किसी भी रुकावट दिनचर्या जो नियंत्रण दिए जाने के लिए होती है, चल सकती है, इसलिए OS लॉक हो जाएगा। यह इन प्रणालियों का "सहकारी" पहलू है। यदि एक वॉचडॉग टाइमर लागू किया जाता है जो केवल तब होता है जब कोई कार्य स्विच किया जाता है, तो इन गलत कार्यों को पकड़ना संभव है।

विंडोज 3.1 और इससे पहले सहकारी ऑपरेटिव सिस्टम थे, जो आंशिक रूप से यही था कि उनका प्रदर्शन इतना बढ़िया क्यों नहीं था।

प्रीमेप्टिव मल्टीटास्किंग को लागू करना अधिक कठिन है। यहां, मैन्युअल रूप से नियंत्रण छोड़ने के लिए कार्यों की आवश्यकता नहीं होती है, लेकिन इसके बजाय प्रत्येक कार्य को चलाने के लिए अधिकतम समय दिया जा सकता है (जैसे 10 एमएस), और फिर एक होने पर एक कार्य स्विच अगले रन करने योग्य कार्य के लिए किया जाता है। इसके लिए मनमाने ढंग से किसी कार्य को रोकना, राज्य की सभी जानकारियों को सहेजना और फिर एसपी को किसी अन्य कार्य में लगाना और इसे शुरू करना है। यह कार्य स्विचर को अधिक जटिल बनाता है, इसके लिए अधिक स्टैक की आवश्यकता होती है, और सिस्टम को थोड़ा धीमा कर देता है।

सहकारी और प्रीमेप्टिव मल्टीटास्किंग दोनों के लिए, किसी भी समय व्यवधान उत्पन्न हो सकता है जो अस्थायी रूप से चल रहे कार्य को पूर्व निर्धारित करेगा।

जैसा कि सुपरकैट एक टिप्पणी में बताता है, एक लाभ सहकारी मल्टीटास्किंग है जो संसाधनों को साझा करना आसान है (जैसे बहु-चैनल एडीसी जैसे हार्डवेयर या लिंक की गई सूची को संशोधित करने जैसा सॉफ़्टवेयर)। कभी-कभी दो कार्य एक ही समय में एक ही संसाधन तक पहुँच चाहते हैं। प्रीमेप्टिव शेड्यूलिंग के साथ, ओएस के लिए एक संसाधन का उपयोग करके एक कार्य के बीच में कार्यों को स्विच करना संभव होगा। तो दूसरे कार्य को उसी संसाधन में आने और उस तक पहुंचने से रोकने के लिए ताले आवश्यक हैं। सहकारी मल्टीटास्किंग के साथ, यह आवश्यक नहीं है क्योंकि कार्य को नियंत्रित करता है जब यह ओएस पर स्वयं वापस जारी करेगा।


3
सहकारी मल्टीटास्किंग का एक फायदा यह है कि ज्यादातर मामलों में संसाधनों तक पहुंच को समन्वित करने के लिए ताले का उपयोग करना आवश्यक नहीं है। यह सुनिश्चित करने के लिए पर्याप्त होगा कि जब भी वे नियंत्रण से हटते हैं तो कार्य हमेशा संसाधनों को एक साझा स्थिति में छोड़ देते हैं। यदि कोई कार्य किसी अन्य कार्य के लिए आवश्यक संसाधन पर लॉक रखता है तो प्रीमेप्टिव मल्टीटास्किंग बहुत अधिक जटिल है। कुछ मामलों में, दूसरा कार्य एक सहकारी प्रणाली के तहत होने से अधिक समय के लिए अवरुद्ध हो सकता है, क्योंकि लॉक को पकड़े हुए कार्य सिस्टम को समर्पित कर रहा होगा ...
सुपरकैट

1
... कार्रवाई को पूरा करने की दिशा में पूर्ण संसाधन जो (पूर्व-खाली प्रणाली पर) ताला की आवश्यकता होती है, इस प्रकार पहरेदार वस्तु को दूसरे कार्य के लिए उपलब्ध कराती है।
सुपरकैट

1
जबकि सहकारी मल्टीटास्करों को अनुशासन की आवश्यकता होती है, यह सुनिश्चित करना कि समय की आवश्यकताओं को पूरा किया जा सकता है एक सहकारी मल्टीटास्कर के तहत कभी-कभी पूर्ववर्ती के तहत आसान हो सकता है। चूँकि बहुत कम तालों को एक टास्क स्विच में रखा जाना चाहिए, एक पाँच-टास्क राउंड-रॉबिन टास्क-स्विच सिस्टम, जहाँ कार्य की आवश्यकता होती है, बिना पैदावार के 10ms से अधिक नहीं, एक छोटे तर्क के साथ संयुक्त रूप से कहा जाता है कि "यदि कार्य X तत्काल इसे चलाने की जरूरत है, इसे आगे बढ़ाएं ", यह सुनिश्चित करेगा कि टास्क एक्स को कभी भी 10ms से अधिक इंतजार नहीं करना पड़ता है क्योंकि यह चलने से पहले सिग्नल करता है। इसके विपरीत, अगर किसी कार्य के लिए लॉक की आवश्यकता होती है जो कार्य X ...
सुपरकैट

1
... जरूरत है लेकिन इसे छोड़ने से पहले एक पूर्व-खाली स्विचर द्वारा स्विच किया जाता है, जब तक कि सीपीयू अनुसूचक पहले काम को चलाने के लिए चारों ओर हो जाता है, तब तक एक्स को कुछ भी उपयोगी नहीं मिल सकता है। जब तक कि शेड्यूलर में प्राथमिकता उलटा को पहचानने और संभालने के लिए तर्क शामिल नहीं है, तब तक कुछ समय लग सकता है जब तक कि वह अपने काम को पूरा करने से पहले अपने व्यवसाय को खत्म करने और ताला जारी करने की अनुमति नहीं देता। इस तरह की समस्याएं अकारण नहीं हैं, लेकिन उन्हें हल करने के लिए बहुत अधिक जटिलता की आवश्यकता होती है जिसे एक सहकारी प्रणाली में टाला जा सकता था। सहकारी प्रणालियाँ एक
गोत्र

3
यदि आप निरंतरता में कोड करते हैं, तो आपको सहकारी में कई स्टैक की आवश्यकता नहीं है। संक्षेप में, आपका कोड फ़ंक्शन में विभाजित void foo(void* context)है नियंत्रक तर्क (कर्नेल) कतार के एक पॉइंटर और फ़ंक्शन पॉइंटर जोड़ी को खींचता है और इसे एक बार में कॉल करता है। यह फ़ंक्शन संदर्भ को अपने चर और ऐसे स्टोर करने के लिए उपयोग करता है और फिर कतार में एक निरंतरता जोड़ सकता है। उन फ़ंक्शन को CPU में अन्य कार्यों को उनके क्षण के लिए जल्दी से वापस लौटना चाहिए। यह एक घटना आधारित विधि है जिसमें केवल एक स्टैक की आवश्यकता होती है।
शाफ़्ट सनकी

16

थ्रेडिंग एक ऑपरेटिंग सिस्टम द्वारा प्रदान की जाती है। एम्बेडेड दुनिया में हमारे पास आमतौर पर एक ओएस ("नंगे धातु") नहीं होता है। तो यह निम्नलिखित विकल्प छोड़ता है:

  • क्लासिक मुख्य मतदान पाश। आपके मुख्य कार्य में कुछ समय है (1) जो कार्य 1 करता है फिर कार्य 2 करता है ...
  • मुख्य लूप + आईएसआर झंडे: आपके पास एक आईएसआर है जो समय-महत्वपूर्ण कार्य करता है और फिर मुख्य लूप को एक ध्वज चर के माध्यम से अलर्ट करता है जिसे कार्य को सेवा की आवश्यकता होती है। शायद आईएसआर एक नया चरित्र एक परिपत्र बफर में डालता है, और फिर मुख्य लूप को डेटा को संभालने के लिए कहता है जब वह ऐसा करने के लिए तैयार होता है।
  • सभी ISR: यहाँ अधिकांश तर्क ISR से निष्पादित होते हैं। एआरएम जैसे आधुनिक नियंत्रक पर, जिसमें कई प्राथमिकता स्तर हैं। यह एक शक्तिशाली "थ्रेड-जैसी" योजना प्रदान कर सकता है, लेकिन डिबग करने के लिए भी भ्रमित हो सकता है, इसलिए इसे केवल महत्वपूर्ण समय की कमी के लिए आरक्षित किया जाना चाहिए।
  • आरटीओएस: एक आरटीओएस कर्नेल (एक टाइमर आईएसआर द्वारा सुविधा) निष्पादन के कई थ्रेड्स के बीच स्विच करने की अनुमति दे सकता है। आपने फ्रीआरटीओएस का उल्लेख किया है।

मैं आपको सलाह दूंगा कि उपरोक्त योजनाओं में से सबसे सरल का उपयोग करें जो आपके आवेदन के लिए काम करेगा। आप जो वर्णन करते हैं, उससे मेरे पास मुख्य लूप जनरेटिंग पैकेट होंगे और उन्हें परिपत्र बफ़र्स में रखा जाएगा। फिर एक UART ISR आधारित ड्राइवर होता है जो जब भी पिछली बाइट भेजता है तब तक फायर करता है जब तक कि बफर भेजा नहीं जाता है, तब किसी भी बफर सामग्री का इंतजार करता है। ईथरनेट के लिए समान दृष्टिकोण।


3
यह एक बहुत ही उपयोगी उत्तर है क्योंकि यह समस्या की जड़ (एक समाधान के रूप में थ्रेड्स के बजाय एक छोटे एम्बेडेड सिस्टम पर मल्टीटास्क कैसे करें) को संबोधित करता है। यह मूल प्रश्न पर कैसे लागू हो सकता है, इसके बारे में एक पैराग्राफ शानदार होगा, शायद परिदृश्य के लिए प्रत्येक के पेशेवरों और विपक्षों सहित।
डेविड

8

जैसा कि वास्तविक सॉफ्टवेयर मल्टीटास्किंग करने वाले किसी भी सिंगल-कोर प्रोसेसर में संभव नहीं है। इसलिए आपको एक से अधिक कार्यों के बीच स्विच करने का ध्यान रखना चाहिए। अलग-अलग RTOS इसका ख्याल रख रहे हैं। उनके पास एक शेड्यूलर है और एक सिस्टम टिक के आधार पर वे आपको मल्टीटास्किंग क्षमता देने के लिए विभिन्न कार्यों के बीच स्विच करेंगे।

ऐसा करने में शामिल अवधारणाएं (संदर्भ बचत और पुनर्स्थापना) काफी जटिल हैं, इसलिए मैन्युअल रूप से ऐसा करना मुश्किल है और आपके कोड को और अधिक जटिल बनाता है और क्योंकि आपने पहले कभी ऐसा नहीं किया है, इसमें त्रुटियां होंगी। यहाँ मेरी सलाह है कि FreeRTOS की तरह ही एक परीक्षण किया गया RTOS का उपयोग करें।

आपने उल्लेख किया कि इंटरप्ट मल्टीटास्किंग का एक स्तर प्रदान करते हैं। यह सत्य की तरह है। व्यवधान किसी भी बिंदु पर आपके वर्तमान कार्यक्रम को बाधित करेगा और वहां कोड को निष्पादित करेगा, यह दो कार्य प्रणाली के साथ तुलनीय है जहां आपके पास कम प्राथमिकता वाला 1 कार्य है और दूसरा उच्च प्राथमिकता वाला है जो अनुसूचक के एक समय-स्लाइस के अंदर समाप्त होता है।

तो आप एक आवर्ती टाइमर के लिए एक बाधा हैंडलर लिख सकते हैं जो UART के ऊपर कुछ पैकेट भेजेगा, तो चलिए आपके बाकी प्रोग्राम कुछ मिली सेकेंड के लिए निष्पादित करते हैं और अगले कुछ बाइट भेजते हैं। इस तरह आप एक सीमित मल्टीटास्किंग क्षमता प्राप्त करते हैं। लेकिन आपके पास एक लंबी रुकावट भी होगी जो एक बुरी बात हो सकती है।

एक ही-कोर MCU पर एक ही समय में कई कार्य करने का एकमात्र वास्तविक तरीका DMA और बाह्य उपकरणों का उपयोग करना है क्योंकि वे कोर से स्वतंत्र काम करते हैं (DMA और MCU एक ही बस को साझा करते हैं, इसलिए वे थोड़ा धीमा काम करते हैं जब दोनों सक्रिय हैं)। तो जबकि DMA UART को बाइट्स फेरबदल कर रहा है, आपके कोर को ईथरनेट पर सामान भेजने के लिए स्वतंत्र है।


2
धन्यवाद, डीएमए दिलचस्प लगता है। मैं निश्चित रूप से इसके लिए खोज करूँगा!
विमान

PICs की सभी श्रृंखला में DMA नहीं है।
मैट यंग

1
मैं PIC32 का उपयोग कर रहा हूं;)
विमान

6

अन्य उत्तर पहले से ही उपयोग किए गए विकल्पों (मुख्य लूप, आईएसआर, आरटीओएस) का वर्णन करते हैं। एक समझौता के रूप में यहां एक और विकल्प है: प्रोटोथ्रेड्स । यह मूल रूप से थ्रेड्स के लिए बहुत हल्का काम है, जो मुख्य लूप और कुछ सी मैक्रोज़ का उपयोग करता है, एक आरटीओएस को "अनुकरण" करने के लिए। बेशक यह कोई पूर्ण ओएस नहीं है, लेकिन "सरल" थ्रेड्स के लिए यह उपयोगी हो सकता है।


मैं विंडोज़ के लिए इसका स्रोत कोड कहाँ से डाउनलोड कर सकता हूँ? मुझे लगता है कि यह केवल लिनक्स के लिए उपलब्ध है।
विमान 10

@CZAbhinav यह ओएस स्वतंत्र होना चाहिए और आप यहां नवीनतम डाउनलोड प्राप्त कर सकते हैं
.bbos

मैं अभी विंडोज़ में हूँ और MplabX का उपयोग कर रहा हूँ, मुझे नहीं लगता कि यह यहाँ उपयोगी है। कोई बात नहीं धन्यवाद।!
विमान

प्रोटोथ्रेड्स के बारे में नहीं सुना, एक दिलचस्प तकनीक की तरह लगता है।
आर्सेनल

@CZAbhinav आप किस बारे में बात कर रहे हैं? यह C कोड है और इसका आपके ऑपरेटिंग सिस्टम से कोई लेना-देना नहीं है।
मैट यंग

3

कम से कम समय में कटा हुआ RTOS के लिए मेरा मूल डिजाइन कई सूक्ष्म परिवारों पर ज्यादा नहीं बदला है। यह मूल रूप से एक टाइमर बाधा है जो राज्य मशीन को चलाती है। इंटरप्ट सर्विस रूटीन OS कर्नेल है जबकि मुख्य लूप में स्विच स्टेटमेंट उपयोगकर्ता के कार्य हैं। डिवाइस ड्राइवर I / O इंटरप्ट के लिए सर्विस रूट बाधित कर रहे हैं।

मूल संरचना इस प्रकार है:

unsigned char tick;

void interrupt HANDLER(void) {
    device_driver_A();
    device_driver_B();
    if(T0IF)
    {
        TMR0 = TICK_1MS;
        T0IF = 0;   // reset timer interrupt
        tick ++;
    }
}

void main(void)
{
    init();

    while (1) {
        // periodic tasks:
        if (tick % 10 == 0) { // roughly every 10 ms
            task_A();
            task_B();    
        }
        if (tick % 55 == 0) { // roughly every 55 ms
            task_C();
            task_D();    
        }

        // tasks that need to run every loop:
        task_E();
        task_F();
    }
}

यह मूल रूप से एक सहकारी मल्टीटास्किंग प्रणाली है। कार्य एक अनंत लूप में प्रवेश करने के लिए कभी नहीं लिखे जाते हैं लेकिन हम परवाह नहीं करते हैं क्योंकि कार्य एक इवेंट लूप के भीतर चलते हैं इसलिए अनंत लूप निहित है। यह जावास्क्रिप्ट या गो जैसी भाषाओं को इवेंट-ओरिएंटेड / नॉनब्लॉकिंग करने के लिए प्रोग्रामिंग की एक समान शैली है।

आप मेरे RC ट्रांसमीटर सॉफ्टवेयर में वास्तुकला की इस शैली का एक उदाहरण देख सकते हैं (हां, मैं वास्तव में इसका उपयोग RC हवाई जहाज उड़ाने के लिए करता हूं, इसलिए यह कुछ सुरक्षा के लिए महत्वपूर्ण है कि मुझे मेरे विमानों को दुर्घटनाग्रस्त होने से बचाने और संभावित रूप से लोगों को मारने के लिए): https://github.com / slebetman / पिक-txmod । इसमें मूल रूप से 3 कार्य हैं - 2 वास्तविक समय के कार्यों को स्टेटफुल डिवाइस ड्राइवर के रूप में लागू किया गया (देखें ppmio सामान) और 1 बैकग्राउंड टास्क जो मिक्सिंग लॉजिक को लागू करता है। तो मूल रूप से यह आपके वेब सर्वर के समान है जिसमें इसके 2 I / O धागे हैं।


1
मैं वास्तव में 'कोऑपरेटिव मल्टीटास्किंग' नहीं कहूंगा, क्योंकि यह वास्तव में किसी भी अन्य माइक्रोकंट्रोलर प्रोग्राम की तुलना में काफी अलग नहीं है, जिसमें कई काम करने हैं।
whatsisname

2

जबकि मैं सराहना करता हूं कि प्रश्न विशेष रूप से एम्बेडेड आरटीओएस के उपयोग के बारे में पूछता है, यह मेरे लिए होता है कि पूछे जाने वाले व्यापक प्रश्न "एम्बेडेड प्लेटफॉर्म पर मल्टीटास्किंग कैसे प्राप्त करें"।

मैं आपको दृढ़ता से सलाह दूंगा कि आप कम से कम समय के लिए एक एम्बेडेड आरटीओएस का उपयोग करने के बारे में भूल जाएं। मैं इसकी सलाह देता हूं क्योंकि मुझे लगता है कि सबसे पहले यह सीखना आवश्यक है कि कैसे सरल कार्य अनुसूचियों और राज्य मशीनों से युक्त अत्यंत सरल प्रोग्रामिंग तकनीकों के माध्यम से कार्य 'संगामिति' को प्राप्त किया जाए।

बहुत संक्षेप में अवधारणा को समझाने के लिए, काम के प्रत्येक मॉड्यूल को करने की आवश्यकता होती है (यानी प्रत्येक 'कार्य') का एक विशेष कार्य होता है जिसे कुछ सामान करने के लिए उस मॉड्यूल के लिए समय-समय पर ('टिकटिक') कहा जाना चाहिए। मॉड्यूल अपनी वर्तमान स्थिति को बनाए रखता है। फिर आपके पास एक मुख्य अनंत लूप (शेड्यूलर) है जो मॉड्यूल फ़ंक्शन को कॉल करता है।

क्रूड चित्रण:

for(;;)
{
    main_lcd_ui_tick();
    networking_tick();
}


...

// In your LCD UI module:
void main_lcd_ui_tick(void)
{
    check_for_key_presses();
    update_lcd();
}

...

// In your networking module:
void networking_tick(void)
{
    //'Tick' the TCP/IP library. In this example, I'm periodically
    //calling the main function for Keil's TCP/IP library.
    main_TcpNet();
}

इस तरह सिंगल-थ्रेडेड प्रोग्रामिंग संरचना जिससे आप समय-समय पर मुख्य शेड्यूलर लूप से मुख्य स्टेट मशीन फ़ंक्शन को कॉल करते हैं, एम्बेडेड प्रोग्रामिंग में सर्वव्यापी है, और यही कारण है कि मैं ओपी को इसके उपयोग से पहले सीधे पहले परिचित और आरामदायक होने के लिए दृढ़ता से प्रोत्साहित करूंगा। RTOS कार्य / थ्रेड।

मैं एक प्रकार के एम्बेडेड डिवाइस पर काम करता हूं जिसमें एक हार्डवेयर एलसीडी इंटरफ़ेस, आंतरिक वेब सर्वर, ईमेल क्लाइंट, डीडीएनएस क्लाइंट, वीओआइपी और कई अन्य विशेषताएं हैं। यद्यपि हम एक RTOS (Keil RTX) का उपयोग करते हैं, लेकिन उपयोग किए जाने वाले अलग-अलग थ्रेड्स (कार्यों) की संख्या बहुत कम होती है और अधिकांश 'मल्टीटास्किंग' प्राप्त होती है जैसा कि ऊपर वर्णित है।

इस अवधारणा को प्रदर्शित करने वाले पुस्तकालयों के कुछ उदाहरण देने के लिए:

  1. केइल नेटवर्किंग लाइब्रेरी। पूरे टीसीपी / आईपी स्टैक को एकल-थ्रेडेड चलाया जा सकता है; आप समय-समय पर main_TcpNet () कहते हैं, जो TCP / IP स्टैक और किसी अन्य नेटवर्किंग विकल्प को लाइब्रेरी से संकलित करता है (जैसे वेब सर्वर)। Http://www.keil.com/support/man/docs/rlarm/rlarm_main_tcpnet.htm देखें । जाहिर है, कुछ स्थितियों में (संभवतः इस उत्तर के दायरे से बाहर) आप एक बिंदु तक पहुंचते हैं जहां यह थ्रेड्स का उपयोग करने के लिए फायदेमंद या आवश्यक होने लगता है (विशेषकर यदि अवरुद्ध बीएसडी सॉकेट्स का उपयोग करके)। (फ्यूचर नोट: नया V5 MDK-ARM वास्तव में एक समर्पित इथरनेट थ्रेड को जन्म देता है - लेकिन मैं सिर्फ एक दृष्टांत प्रदान करने की कोशिश कर रहा हूं।)

  2. लाइनफोन वीओआइपी लाइब्रेरी। लाइनफोन लाइब्रेरी स्वयं सिंगल-थ्रेडेड है। आप iterate()फ़ंक्शन को पर्याप्त अंतराल पर कहते हैं। Http://www.linphone.org/docs/liblinphone-javadoc/org/linphone/core/LinphoneCore.html#iterate () देखें । (एक गरीब उदाहरण के बिट क्योंकि मैं एक एम्बेडेड लिनक्स प्लेटफॉर्म और लाइनफ़ोन की निर्भरता पुस्तकालयों पर निस्संदेह थ्रेड्स का उपयोग करता था, लेकिन फिर से यह एक बिंदु को चित्रित करने के लिए है।)

ओपी द्वारा उल्लिखित विशिष्ट समस्या पर वापस जाने से, यह समस्या इस तथ्य से प्रतीत होती है कि UART संचार को उसी समय पर होना चाहिए जब कुछ नेटवर्किंग (टीसीपी / आईपी के माध्यम से पैकेट को प्रेषित कर रही हो)। मुझे नहीं पता कि आप वास्तव में कौन सी नेटवर्किंग लाइब्रेरी का उपयोग कर रहे हैं, लेकिन मुझे लगता है कि इसका एक मुख्य कार्य है जिसे अक्सर कहा जाना चाहिए। आपको अपना कोड लिखना होगा जो UART डेटा ट्रांसमिशन / रिसेप्शन के साथ एक समान तरीके से संरचित होता है, एक राज्य मशीन के रूप में जिसे एक मुख्य कार्य के लिए आवधिक कॉल द्वारा पुनरावृत्त किया जा सकता है।


2
इस अच्छी व्याख्या के लिए धन्यवाद, मैं माइक्रोचिप द्वारा प्रदान की गई टीसीपी / आईपी लाइब्रेरी का उपयोग कर रहा हूं और यह बहुत बड़ा जटिल कोड है। मैं किसी तरह इसे भागों में तोड़ने और अपनी आवश्यकताओं के अनुसार उपयोग करने में सफल रहा। मैं निश्चित रूप से आपके दृष्टिकोण में से एक कोशिश करूँगा।
विमान

मज़े करें :) आरटीओएस का उपयोग निश्चित रूप से कई स्थितियों में जीवन को आसान बनाता है। मेरे विचार में, थ्रेड (कार्य) का उपयोग करना एक अर्थ में प्रोग्रामिंग प्रयास को बहुत आसान बना देता है, क्योंकि आप अपने कार्य को राज्य मशीन में तोड़ने से बच सकते हैं। इसके बजाय, आप अपने कार्य कोड को ठीक उसी तरह लिखते हैं, जैसे आप अपने C # कार्यक्रमों में, अपने कार्य कोड के साथ बनाए जाते हैं जैसे कि यह केवल मौजूद चीज़ है। दोनों दृष्टिकोणों का पता लगाना आवश्यक है, और जैसा कि आप अधिक एम्बेडेड प्रोग्रामिंग करते हैं, आपको यह महसूस करना शुरू हो जाता है कि प्रत्येक स्थिति में कौन सा दृष्टिकोण सबसे अच्छा है।
ट्रेवर पेज

मैं थ्रेडिंग विकल्प का उपयोग करना भी पसंद करता हूं। :)
विमान
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.