STM32F429-DISCO 学习之FreeRTOS协程

/ 0评 / 2

FreeRTOS内有croutine这个驱动,但是,这个怎么翻译,我也不太明白,暂且脑补成协程,就是co-routine,这个用起来跟任务比较类似,只不过他调用每个东西,都像一个函数一样,不像一个任务,就是说,任务是Cortex-A的话,这协程能做的就是Cortex-M的,他们并不能吃多少内存,也不能干太多什么事.但是协程一样要调度的,受任务控制,一般在IDLE任务里面搞.通常的表达是这样的.

 void vApplicationIdleHook( void )
 {
    for( ;; )
    {
        vCoRoutineSchedule();
    }
 }

当然,如果Idle里面还有别的任务,可就不能死循环了.当然,其他任务也把时间片全用了,那我自然也没机会执行.当然,要做这个,需要打开configUSE_CO_ROUTINES开关.协程时间准确性也比较差.比如我闪烁一个LED灯.

void vFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
{
    crSTART( xHandle );
    for( ;; )
    {
        if(uxIndex == 0)
        {
            GPIO_ToggleBits(GPIOG, GPIO_Pin_13);
            crDELAY( xHandle, 500 );
        }
        else if(uxIndex == 1)
        {
            GPIO_ToggleBits(GPIOG, GPIO_Pin_14);
            crDELAY( xHandle, 1000 );
        }
    }
    crEND();
}

发现,这个程序必须有两个参数,一个是xHandle,自己的句柄,另一个是uxIndex,传入的参数.是Index,所以,只能按数字传.协程必须以crSTART开始,以crEND结束,协程内的延迟,使用crDELAY.实验效果就是,主任务Task并不受干扰,LED还能正常闪烁.完整程序如下,忽略IO初始化.

#include "FreeRTOS.h"
#include "task.h"
#include "croutine.h"
void vApplicationIdleHook( void )
{
    vCoRoutineSchedule();
}
static void vTask1( void *pvParameters )
{
    portTickType xLastWakeTime;
    xLastWakeTime = xTaskGetTickCount();
    for( ;; )
    {
        printf("Hello 3000!");
        vTaskDelayUntil( &xLastWakeTime, ( 3000 / portTICK_RATE_MS ) );
    }
}
static void vTask2( void *pvParameters )
{
    portTickType xLastWakeTime;
    xLastWakeTime = xTaskGetTickCount();
    for( ;; )
    {
        printf("Hello 2000!");
        vTaskDelayUntil( &xLastWakeTime, ( 1000 / portTICK_RATE_MS ) );
    }
}
void vFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
{
    crSTART( xHandle );
    for( ;; )
    {
        if(uxIndex == 0)
        {
            GPIO_ToggleBits(GPIOG, GPIO_Pin_13);
            crDELAY( xHandle, 500 );
        }
        else if(uxIndex == 1)
        {
            GPIO_ToggleBits(GPIOG, GPIO_Pin_14);
            crDELAY( xHandle, 1000 );
        }
    }
    crEND();
}
int main(void)
{
    xTaskCreate( vTask1, ( const char * ) "vTask1", 1000, NULL, 1, NULL );
    xTaskCreate( vTask2, ( const char * ) "vTask2", 1000, NULL, 1, NULL );
    xCoRoutineCreate( vFlashCoRoutine, 0, 0 );
    xCoRoutineCreate( vFlashCoRoutine, 0, 1 );
    vTaskStartScheduler();
    for(;;);
}

协程非常简单,而且优先级很低,适合做后台应用.

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注