operating system फ्री रोटोस में राज्य मशीन प्रोग्राम डिजाइन-स्विच स्टेटमेंट में vTaskStartScheduler




operating-system embedded (2)

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

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

वैकल्पिक रूप से, आप एड किंग द्वारा उल्लिखित श्रेष्ठ कार्य बना सकते हैं, उच्च प्राथमिकता के साथ

ईमानदारी से, सब कुछ इस बात पर निर्भर करता है कि कार्य वास्तव में क्या कर रहा है।

मेरे पास फ्रीआरटीओएस में एक प्रोग्राम डिज़ाइन प्रश्न है:

मेरे 4 राज्यों और 6 कार्यों के साथ एक राज्य मशीन है I प्रत्येक राज्य में, टास्क 1 को छोड़कर, विभिन्न कार्यों को निष्पादित किया जाना चाहिए, जो हमेशा सक्रिय होता है:

राज्य 1: टास्क 1, टास्क 2, टास्क 3
राज्य 2: टास्क 1, टास्क 2, टास्क 3, टास्क 4
राज्य 3: कार्य 1, कार्य 5
राज्य 4: कार्य 1, टास्क 6

कार्य 1, टास्क 3, टास्क 4, टास्क 5 और टास्क 6 आवधिक हैं, और प्रत्येक एक अलग संवेदक पढ़ता है।
टास्क 2 aperiodic है, यह एक GPRS अलार्म भेजता है केवल अगर एक दहलीज पर पहुंच गया है

राज्यों के बीच स्विचिंग प्रत्येक कार्य के सेंसर इनपुट से होने वाली घटनाओं द्वारा निर्धारित की जाती है।

मुख्य () डिजाइन के लिए प्रारंभिक दृष्टिकोण राज्यों को नियंत्रित करने के लिए एक स्विच होना है, और राज्य के आधार पर, संबंधित कार्यों को निलंबित करना और सक्रिय करना है:

void main ()
{
    /* initialisation of hw and variables*/
    system_init(); 

    /* creates FreeRTOS tasks and suspends all tasks except Task1*/
    task_create();

    /* Start the scheduler so FreeRTOS runs the tasks */
    vTaskStartScheduler(); 

    while(true)
    {
        switch STATE:
            case 1:
                suspend(Task4, Task5, Task6);
                activate(Task2, Task3);
                break;
            case 2:
                suspend(Task5, Task6);
                activate(Task2, Task3, Task4);
                break;
            case 3:
                suspend(Task2, Task3, Task4, Task6); 
                activate(Task5);
                break;
            case 4: 
                suspend(Task2, Task3, Task4, Task5);
                activate(Task6);
                break;
    }
}

मेरा प्रश्न यह है कि स्विच के संबंध में मुझे vTaskStartScheduler () कहां चाहिए? मुझे लगता है कि इस कोड में, एक बार vTaskStartScheduler कहा जाता है, कार्यक्रम स्विच स्टेटमेंट कभी नहीं दर्ज करेंगे।

क्या मैं एक अन्य कार्य को हमेशा राज्य मशीन को नियंत्रित करने के लिए सक्रिय कर सकता हूं, जिसमें पिछला समय और स्विच स्टेटमेंट अंदर है, जैसे कि निम्न छद्मोकोड?

task_control()
{
    while(true)
    {
        switch STATE:
            case 1: 
                   suspend(Task4, Task5, Task6);  
                   execute(Task2, Task3); 
            and so on...
    }
}  

किसी भी सलाह कि बहुत सराहना की जाएगी...


आपके प्रश्न का उत्तर देने के लिए, vTaskStartScheduler() , जैसा कि नाम से पता चलता है, अनुसूचक शुरू करें किसी भी कोड के बाद केवल निष्पादित होगा जब शेड्यूलर बंद हो जाता है, जो ज्यादातर मामलों में जब कार्यक्रम समाप्त होता है, इसलिए कभी नहीं। यही कारण है कि आपका switch नहीं होगा

जैसा कि आप पहले से ही बच चुके हैं, आपके डिजाइन के लिए आप दूसरों को नियंत्रित करने के लिए एक 'मुख्य' कार्य का उपयोग कर सकते हैं। आपको यह बना दिया है और vTaskStartScheduler() कॉल करने से पहले उसे शेड्यूलर के साथ पंजीकृत करना होगा।

एक तरफ ध्यान दें, यदि आप इस दृष्टिकोण से आगे बढ़ते हैं, तो आप केवल अपने कार्य को एक राज्य में पहली प्रविष्टि पर निलंबित / पुनरारंभ करना चाहते हैं, न कि 'मुख्य' कार्य के हर चलन पर।

उदाहरण के लिए:

static bool s_first_state_entry = true;

task_control()
{
    while (true)
    {
        switch (STATE)
        {
        case 1:
            if (s_first_state_entry)
            {  
                // Only do this stuff once              
                s_first_state_entry = false;
                suspend(Task4, Task5, Task6);  
                execute(Task2, Task3); 
            }
            // Do this stuff on every iteration
            // ...
            break;
        default:
            break;
        }
    }
}  

void set_state(int state)
{
    STATE = state;
    s_first_state_entry = true;
}