- FreeRTOS Arduino में एक कार्य को हटाना
- FreeRTOS में कतार क्या है?
- FreeRTOS में एक कतार बनाना
- सर्किट आरेख
- Arduino IDE में FreeRTOS कतार को लागू करना
पिछले ट्यूटोरियल में, हमने Arduino Uno में FreeRTOS पेश किया और निमिष एलईडी के लिए एक कार्य बनाया। अब, इस ट्यूटोरियल में, हम RTOS APIs की अग्रिम अवधारणाओं में अधिक गोता लगाएँगे और विभिन्न कार्यों के बीच संचार के बारे में जानेंगे। यहाँ हम कतार से डेटा को एक कार्य से दूसरे में स्थानांतरित करने के बारे में भी सीखते हैं और Arduino Uno के साथ 16x2 LCD और LDR को इंटर करके कतार APIs के कार्य को प्रदर्शित करते हैं ।
Queues के बारे में चर्चा करने से पहले, आइए एक और FreeRTOS API देखें जो असाइन किए गए कार्य के साथ समाप्त होने पर कार्यों को हटाने में सहायक है। आवंटित स्मृति को मुक्त करने के लिए कभी-कभी कार्य को हटाने की आवश्यकता होती है। पिछले ट्यूटोरियल की निरंतरता में, हम किसी कार्य को हटाने के लिए vTaskDelete () एपीआई फ़ंक्शन का उपयोग उसी कोड में करेंगे। कोई कार्य vTaskDelete () API फ़ंक्शन का उपयोग खुद को या किसी अन्य कार्य को हटाने के लिए कर सकता है।
इस API का उपयोग करने के लिए, आपको FreeRTOSConfig.h फ़ाइल को कॉन्फ़िगर करना होगा । इस फ़ाइल का उपयोग अनुप्रयोग के अनुसार FreeRTOS को टेलर करने के लिए किया जाता है। इसका उपयोग शेड्यूलिंग एल्गोरिदम और कई अन्य मापदंडों को बदलने के लिए किया जाता है। फ़ाइल को Arduino निर्देशिका में पाया जा सकता है जो आपके पीसी के दस्तावेज़ फ़ोल्डर में आम तौर पर उपलब्ध है। मेरे मामले में, यह नीचे दिखाए गए अनुसार \ Documents \ Arduino \ पुस्तकालयों \ FreeRTOS \ src में उपलब्ध है।
अब, किसी भी पाठ संपादक का उपयोग कर इस फ़ाइल को खोलने के लिए खोज और #define INCLUDE_vTaskDelete और '1' यह सुनिश्चित कर लें अपने मूल्य है (1 साधन सक्षम और 0 साधन अक्षम)। यह डिफ़ॉल्ट रूप से 1 है लेकिन इसके लिए जांच की जाती है।
हम पैरामीटर सेट करने के लिए अपने अगले ट्यूटोरियल्स में इस कॉन्फिग फाइल का अक्सर उपयोग करेंगे।
अब, देखते हैं कि किसी कार्य को कैसे हटाएं।
FreeRTOS Arduino में एक कार्य को हटाना
किसी कार्य को हटाने के लिए, हमें vTaskDelete () API फ़ंक्शन का उपयोग करना होगा। यह केवल एक तर्क लेता है।
vTaskDelete (TaskHandle_t pxTaskToDelete);
pxTaskToDelete: यह उस कार्य का हैंडल है जिसे हटाना है। यह xTaskCreate () एपीआई के 6 वें तर्क के समान है। पिछले ट्यूटोरियल में, यह तर्क NULL के रूप में सेट किया गया है, लेकिन आप किसी भी नाम का उपयोग करके कार्य की सामग्री का पता पास कर सकते हैं। मान लीजिए कि आप टास्क 2 के लिए टास्क हैंडल सेट करना चाहते हैं, जो कि घोषित किया गया है
TaskHandle_t any_name; उदाहरण: TaskHandle_t xTask2Handle;
अब, vTaskCreate में () एपीआई 6 वें तर्क के रूप में सेट है
xTaskCreate (TaskBlink2, "task2", 128, NULL, 1, & xTask2Handh);
इस कार्य की सामग्री को अब आपके द्वारा दिए गए हैंडल का उपयोग करके एक्सेस किया जा सकता है।
इसके अलावा, एक टास्क एक वैध टास्क हैंडल की जगह NULL को पास करके खुद को डिलीट कर सकता है।
यदि हम टास्क 3 को टास्क 3 से हटाना चाहते हैं, तो आपको vTaskDelete (NULL) लिखना होगा; टास्क 3 फंक्शन के अंदर लेकिन अगर आप टास्क 3 को टास्क 2 से हटाना चाहते हैं तो vTaskDelete (xTask3Handh) लिखें ; कार्य 2 फ़ंक्शन के अंदर।
पिछले ट्यूटोरियल कोड में टास्क 2 को टास्क 2 से हटाने के लिए, बस vTaskDelete (NULL) जोड़ें ; में शून्य TaskBlink2 (शून्य * pvParameters) समारोह। फिर उपरोक्त फ़ंक्शन इस तरह दिखेगा
शून्य TaskBlink2 (शून्य * pvParameters) { Serial.println ("Task2 चल रहा है और हटाने के बारे में है"); vTaskDelete (NULL); पिनमोड (7, OUTPUT); जबकि (1) { digitalWrite (7, उच्च); vTaskDelay (300 / portTICK_PERIOD_MS); digitalWrite (7, कम); vTaskDelay (300 / portTICK_PERIOD_MS); } }
अब, कोड अपलोड करें और एल ई डी और सीरियल मॉनिटर का निरीक्षण करें। आप देखेंगे कि दूसरी एलईडी अब ब्लिंक नहीं कर रही है और डिलीट एपीआई को एनकाउंटर करने के बाद टास्क 2 डिलीट हो जाता है।
तो इस एपीआई का उपयोग विशेष कार्य के निष्पादन को रोकने के लिए किया जा सकता है।
अब, कतार से शुरू करते हैं।
FreeRTOS में कतार क्या है?
कतार डेटा संरचना है जो निश्चित आकार के तत्वों की परिमित संख्या को धारण कर सकती है और इसे FIFO योजना (पहले-पहले-पहले) में संचालित किया जाता है। कार्य एक कार्य-से-कार्य, कार्य-से-व्यवधान और व्यवधान-से-कार्य संचार तंत्र प्रदान करते हैं।
तत्वों की अधिकतम संख्या को कतार में रखा जा सकता है, इसे "लंबाई" कहा जाता है। कतार बनाते समय प्रत्येक तत्व की लंबाई और आकार दोनों निर्धारित किए जाते हैं।
डेटा ट्रांसफर के लिए कतार का उपयोग कैसे किया जाता है इसका एक उदाहरण FreeRTOS प्रलेखन में अच्छी तरह से चित्रित किया गया है जो यहां पाया जा सकता है। आप दिए गए उदाहरण को आसानी से समझ सकते हैं।
कतारों को समझने के बाद, एक कतार बनाने की प्रक्रिया को समझने की कोशिश करते हैं और इसे हमारे फ्रीआरटीओएस कोड में लागू करने की कोशिश करते हैं।
FreeRTOS में एक कतार बनाना
सबसे पहले, समस्या कथन का वर्णन करें जो कि फ्रीआरटीओएस कतार और अरुडिनो उनो की मदद से लागू किया जाना है।
हम 16 * 2 एलसीडी पर LDR सेंसर के मूल्य को प्रिंट करना चाहते हैं । इसलिए अभी दो कार्य हैं
- टास्क 1 को LDR के अनुरूप मान मिल रहे हैं।
- टास्क 2 एलसीडी पर एनालॉग वैल्यू को प्रिंट कर रहा है।
इसलिए, यहां क्यू 1 अपनी भूमिका निभाता है क्योंकि टास्क 1 द्वारा उत्पन्न डेटा को टास्क 2 में भेजना है। कार्य 1 में, हम कतार में एनालॉग मूल्य भेजेंगे और कार्य 2 में, हम इसे कतार से प्राप्त करेंगे।
कतारों के साथ काम करने के लिए तीन कार्य हैं
- एक कतार बनाना
- कतार में डेटा भेजना
- कतार से डेटा प्राप्त करना
कतार बनाने के लिए, xQueueCreate () फ़ंक्शन API का उपयोग करें । यह दो तर्क लेता है।
xQueueCreate (UBaseType_t uxQueueLength, UBaseType_t uxItemSize);
uxQueueLength: कतार में बनाई जा रही वस्तुओं की अधिकतम संख्या किसी भी एक समय में पकड़ सकती है।
uxItemSize: प्रत्येक डेटा आइटम के बाइट्स में आकार जो कतार में संग्रहीत किया जा सकता है।
यदि यह फ़ंक्शन NULL देता है, तो अपर्याप्त स्मृति के कारण कतार नहीं बनाई जाती है और यदि यह एक गैर-NULL मान देता है, तो कतार सफलतापूर्वक बनाई जाती है। नीचे दिए गए अनुसार कतार तक पहुँचने के लिए एक हैंडल के रूप में उपयोग करने के लिए इस रिटर्न वैल्यू को एक वैरिएबल में स्टोर करें।
QueueHandle_t queue1; queue1 = xQueueCreate (4, sizeof (int));
यह अंतर आकार के ढेर स्मृति (प्रत्येक ब्लॉक के 2 बाइट्स) में 4 तत्व कतार बनाएगा और वापसी मान को कतार 1 हैंडल चर में संग्रहीत करेगा ।
2. फ्रीआरटीओएस में कतार में डेटा भेजना
मूल्यों को कतार में भेजने के लिए, फ्रीआरटीओएस के पास इस उद्देश्य के लिए एपीआई के 2 संस्करण हैं।
- xQueueSendToBack (): एक कतार के पीछे (पूंछ) में डेटा भेजने के लिए उपयोग किया जाता है।
- xQueueSendToFront (): एक कतार के सामने (सिर) को डेटा भेजने के लिए उपयोग किया जाता है।
अब , xQueueSend () के बराबर है, और बिल्कुल उसी तरह, जैसे xQueueSendToBack ()।
ये सभी API 3 तर्क देते हैं।
xQueueSendToBack (QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait);
xQueue: डेटा को भेजे जाने (लिखे जाने) के लिए कतार का हैंडल। यह चर xQueueCreate API के रिटर्न मान को स्टोर करने के लिए उपयोग किया जाता है।
pvItemToQueue: कतार में कॉपी किए जाने वाले डेटा का एक सूचक।
xTicksToWait: कतार में उपलब्ध होने के लिए स्थान की प्रतीक्षा करने के लिए कार्य की अधिकतम राशि अवरुद्ध अवस्था में रहना चाहिए।
XTicksToWait को portMAX_DELAY पर सेट करने से कार्य अनिश्चित काल तक प्रतीक्षा करने का कारण बनेगा (बशर्ते बाहर), बशर्ते INCLUDE_vTaskSuspend को FreeRTOSConWigig में 1 पर सेट किया जाए। इसके अलावा आप मिलीसेकेंड में निर्दिष्ट समय को परिवर्तित करने के लिए मैक्रो pdMS_TO_TICKS () का उपयोग कर सकते हैं ।
3. फ्रीआरटीओएस में कतार से डेटा प्राप्त करना
एक पंक्ति से एक आइटम प्राप्त करने (पढ़ने) के लिए, xQueueReceive () का उपयोग किया जाता है। प्राप्त होने वाली वस्तु को कतार से हटा दिया जाता है।
यह एपीआई तीन तर्क भी लेता है।
xQueueReceive (क्यूहैंडल_टी xQueue, void * const pvBuffer, TickType_t xTicksToWait);
पहले और तीसरे तर्क एपीआई भेजने के समान हैं। केवल दूसरा तर्क अलग है।
const pvBuffer: मेमोरी को एक पॉइंटर जिसमें प्राप्त डेटा को कॉपी किया जाएगा।
आशा है कि आप तीन एपीआई समझ गए होंगे। अब, हम Arduino IDE में इन API को कार्यान्वित करेंगे और ऊपर वर्णित समस्या कथन को हल करने का प्रयास करेंगे।
सर्किट आरेख
यह ब्रेडबोर्ड पर कैसा दिखता है:
Arduino IDE में FreeRTOS कतार को लागू करना
आइए हमारे आवेदन के लिए कोड लिखना शुरू करें।
1. सबसे पहले, Arduino IDE खोलें और Arduino_FreeRTOS.h हैडर फ़ाइल शामिल करें । अब, यदि कतार की तरह किसी भी कर्नेल ऑब्जेक्ट का उपयोग किया जाता है, तो उसमें हेडर फ़ाइल शामिल करें। जैसा कि हम 16 * 2 एलसीडी का उपयोग कर रहे हैं, इसलिए इसके लिए पुस्तकालय भी शामिल करें।
# अकेला छोड़ दो
2. कतार की सामग्री को संग्रहीत करने के लिए एक कतार हैंडल को प्रारंभ करें। इसके अलावा, एलसीडी पिन नंबरों को इनिशियलाइज़ करें।
QueueHandle_t queue_1; लिक्विड क्रिस्टल एलसीडी (7, 8, 9, 10, 11, 12);
3. शून्य सेटअप () में, 9600 बॉड दर के साथ एलसीडी और सीरियल मॉनिटर को इनिशियलाइज़ करें। संबंधित API का उपयोग करके एक कतार और दो कार्य बनाएं। यहां हम पूर्णांक प्रकार के साथ आकार 4 की एक कतार बनाएंगे। समान प्राथमिकताओं के साथ एक कार्य बनाएं और बाद में इस संख्या के साथ खेलने का प्रयास करें। अंत में, शेड्यूलर को नीचे दिखाए अनुसार शुरू करें।
शून्य सेटअप () { Serial.begin (9600); lcd.begin (16, 2); queue_1 = xQueueCreate (4, sizeof (int)); if (queue_1 == NULL) {Serial.println ("कतार बनाई नहीं जा सकती"); } xTaskCreate (TaskDisplay, "Display_task", 128, NULL, 1, NULL); xTaskCreate (टास्कएलडीआर, "LDR_task", 128, NULL, 1, NULL); vTaskStartScheduler (); }
4. अब, TaskDisplay और TaskLDR दो कार्य करें । में TaskLDR समारोह, एक चर में एनालॉग पिन A0 पढ़ के रूप में हम लीडर Arduino संयुक्त राष्ट्र संघ की A0 पिन से जुड़ा है। अब चर में संग्रहीत मूल्य को xQueueSend API में पास करके भेजें और vTaskDelay () API का उपयोग करते हुए 1 सेकंड के बाद राज्य को ब्लॉक करने के लिए कार्य भेजें ।
शून्य टास्कएलडीआर (शून्य * pvParameters) { int current_intensity; जबकि (1) { Serial.println ("टास्क 1"); current_intensity = analogRead (A0); सीरियल.प्रिंटलेन (करंट_इंटेंसिटी); xQueueSend (queue_1, और current_intensity, portMAX_DELAY); vTaskDelay (1000 / portTICK_PERIOD_MS); } }
5. इसी तरह, टास्कडिसेप्ले के लिए एक फ़ंक्शन बनाएं और एक चर में मान प्राप्त करें जो xQueueReceive फ़ंक्शन के पास है। इसके अलावा, xQueueReceive () pdPASS देता है यदि डेटा कतार से सफलतापूर्वक प्राप्त किया जा सकता है और एक कतार खाली होने पर irQUEUE_EMPTY देता है।
अब, lcd.print () फ़ंक्शन का उपयोग करके एलसीडी को मान प्रदर्शित करें ।
शून्य टास्कडिप्ले (शून्य * pvParameters) {इंटेंसिटी = 0; जबकि (1) { Serial.println ("Task2"); अगर (xQueueReceive (queue_1, & तीव्रता, portMAX_DELAY) == pdPASS) { lcd.clear (); lcd.setCursor (0, 0); lcd.print ("तीव्रता:"); lcd.setCursor (11, 0); lcd.print (तीव्रता); } } }
बस। हमने कतार कार्यान्वयन के कोडिंग भाग को समाप्त कर दिया है। एक काम कर रहे वीडियो के साथ पूरा कोड अंत में पाया जा सकता है।
अब, सर्किट आरेख के अनुसार कोड अपलोड करें एलसीडी और LDR को Arduino UNO के साथ कनेक्ट करें। सीरियल मॉनिटर खोलें और कार्यों का निरीक्षण करें। आप देखेंगे कि कार्य स्विच कर रहे हैं और LDR मान प्रकाश की तीव्रता के अनुसार बदल रहे हैं।
नोट: विभिन्न सेंसरों के लिए बनाए गए अधिकांश पुस्तकालयों को पुस्तकालयों के अंदर देरी से लागू होने के कारण फ्रीआरटीओएस कर्नेल द्वारा समर्थित नहीं किया गया है। विलंब सीपीयू को पूरी तरह से रोक देता है, इसलिए, फ्रीटोस कर्नेल भी काम करना बंद कर देता है और कोड आगे निष्पादित नहीं करेगा और यह दुर्व्यवहार शुरू कर देता है। इसलिए, हमें पुस्तकालयों को फ्रीआरटीओएस के साथ काम करने के लिए विलंब-मुक्त बनाना होगा।