You are here

Quick Co-routine Example - Быстрый пример сопрограммы

Перевод может содержать ошибки. Читайте первоисточник: Quick Co-routine Example

Назад: [Сопрограммы во FreeRTOS] Вверх: [Сопрограммы во FreeRTOS] Вперёд: [Сопрограммы во FreeRTOS]

 

Этот быстрый пример (дурацкий перевод, а другого пока не знаю) демонстрирует использование сопрограмм.

  1. Создание простой сопрограммы для мигания светодиодом

    Приведённый ниже код определяет очень простую сопрограмму, которая не делает ничего кроме периодического мигания светодиодом.

    /*----------------------------------------------------------------------------*/
    void vFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
    {
        /* Сопрограмма должна начинаться с вызова макроса crSTART(). */
        crSTART( xHandle );
    
        for( ;; )
        {
            /* Задержка на фиксированное время. */
            crDELAY( xHandle, 10 );
    
            /* Мигание светодиодом. */
            vParTestToggleLED( 0 );
        }
    
        /* Сопрограмма должна заканчиваться вызовом макроса crEND(). */
        crEND();
    }
    
    

    И всё!

  2. Планирование сопрограмм

    Сопрограммы планируются повторяющимся вызовом vCoRoutineSchedule(). Наиболее подходящее место для этого - вызывать из задачи простоя, написав функцию-ловушку задачи простоя. Сначала убедитесь, что configUSE_IDLE_HOOK установлен в 1 в файле FreeRTOSConfig.h. Затем напишите ловушку задачи простоя следующим образом:

    /*----------------------------------------------------------------------------*/
    void vApplicationIdleHook( void )
    {
        vCoRoutineSchedule( void );
    }
    
    

    Другой способ, если задача простоя не выполняет никаких других функций, может быть более эффективным. Для этого нужно вызывать vCoRoutineSchedule() из цикла:

    /*----------------------------------------------------------------------------*/
    void vApplicationIdleHook( void )
    {
        for( ;; )
        {
            vCoRoutineSchedule( void );
        }
    }
    
    
  3. Создание сопрограммы и запуск планировщика ОС

    Сопрограмма может быть создана внутри функции main().

    /*----------------------------------------------------------------------------*/
    #include "task.h"
    #include "croutine.h"
    
    #define PRIORITY_0 0
    
    void main( void )
    {
        /* В этом случае индекс не используется, и функцию передаётся значение 0. */
        xCoRoutineCreate( vFlashCoRoutine, PRIORITY_0, 0 );
    
        /* Замечание: Здесь же могут быть созданы задачи ОС! */
    
        /* Запуск планировщика ОС. */
        vTaskStartScheduler();
    }
    
    
  4. Усложняем пример: использование параметра index

    Теперь предположим, что мы хотим создать восемь таких сопрограмм из одной и той же функции. Каждая сопрограмма будет мигать разными светодиодами с разной скоростью. Параметр index может быть использован для различения сопрограмм внутри самой функции сопрограммы.

    На этот раз мы создаём 8 сопрограмм и передаём в каждую свой индивидуальный индекс.

    /*----------------------------------------------------------------------------*/
    #include "task.h"
    #include "croutine.h"
    
    #define PRIORITY_0        0
    #define NUM_COROUTINES    8
    
    void main( void )
    {
    int i;
    
        for( i = 0; i < NUM_COROUTINES; i++ )
        {
            /* На этот раз значение i передаётся в качестве параметра index. */
            xCoRoutineCreate( vFlashCoRoutine, PRIORITY_0, i );
        }
    
        /* Замечание: Здесь же могут быть созданы задачи ОС! */
    
        /* Запуск планировщика ОС. */
        vTaskStartScheduler();
    }
    
    

    Функция сопрограммы теперь также усложняется, т.к. использует различные светодиоды и различную частоту мигания.

    /*----------------------------------------------------------------------------*/
    const int iFlashRates[ NUM_COROUTINES ] = { 10, 20, 30, 40, 50, 60, 70, 80 };
    const int iLEDToFlash[ NUM_COROUTINES ] = { 0, 1, 2, 3, 4, 5, 6, 7 }
    
    void vFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
    {
        /* Сопрограмма должна начинаться с вызова макроса crSTART(). */
        crSTART( xHandle );
    
        for( ;; )
        {
            /* Задержка на фиксированный период. uxIndex используется как индекс */ 
            /* в таблице iFlashRates[]. Поскольку сопрограммы создавались с */
            /* различными индексами, каждая будет задерживаться на своё время. */
            crDELAY( xHandle, iFlashRate[ uxIndex ] );
    
            /* Мигание светодиодом. Снова uxIndex используется как индекс */
            /* в массиве, но на этот раз для того, чтобы определить светодиод, */
            /* состояние которого нужно изменить. */
            vParTestToggleLED( iLEDToFlash[ uxIndex ] );
        }
    
        /* Сопрограмма должна завершаться вызовом макроса crEND(). */
        crEND();
    }
    
    

 

Hobby's category: