Select your cookie preferences

We use essential cookies and similar tools that are necessary to provide our site and services. We use performance cookies to collect anonymous statistics, so we can understand how customers use our site and make improvements. Essential cookies cannot be deactivated, but you can choose “Customize” or “Decline” to decline performance cookies.

If you agree, AWS and approved third parties will also use cookies to provide useful site features, remember your preferences, and display relevant content, including relevant advertising. To accept or decline all non-essential cookies, choose “Accept” or “Decline.” To make more detailed choices, choose “Customize.”

已更新 2025年7月

FreeRTOS 协程

[更多关于协程的信息……]

局限和限制

与同等任务相比,协程的优势是使用的 RAM 较少,但代价是 使用协程时存在一些限制条件。与任务相比,协程的限制性更强,使用起来也更复杂 。

  • 共享堆栈

    当协程阻塞时,协程的堆栈无法维持。这意味着在堆栈上分配的变量 很可能丢失其值。要克服这一问题, 需将在阻塞调用中维持其值的变量声明为静态。例如:

    1void vACoRoutineFunction( CoRoutineHandle_t xHandle,
    2 UBaseType_t uxIndex )
    3{
    4 static char c = 'a';
    5
    6 // Co-routines must start with a call to crSTART().
    7 crSTART( xHandle );
    8
    9 for( ;; )
    10 {
    11 // If we set c to equal 'b' here ...
    12 c = 'b';
    13
    14 // ... then make a blocking call ...
    15 crDELAY( xHandle, 10 );
    16
    17 // ... c will only be guaranteed to still
    18 // equal 'b' here if it is declared static
    19 // (as it is here).
    20 }
    21
    22 // Co-routines must end with a call to crEND().
    23 crEND();
    24}

    共享堆栈的另一个结果是,能从协程函数本身调用可能导致协程阻塞的 API 函数, 而不能从协程调用的函数中调用 。例如:

    1void vACoRoutineFunction( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
    2{
    3 // Co-routines must start with a call to crSTART().
    4 crSTART( xHandle );
    5
    6 for( ;; )
    7 {
    8 // It is fine to make a blocking call here,
    9 crDELAY( xHandle, 10 );
    10
    11 // but a blocking call cannot be made from within
    12 // vACalledFunction().
    13 vACalledFunction();
    14 }
    15
    16 // Co-routines must end with a call to crEND().
    17 crEND();
    18}
    19
    20void vACalledFunction( void )
    21{
    22 // Cannot make a blocking call here!
    23}
  • switch 语句的使用

    FreeRTOS 下载中的默认协程实现不允许 在 switch 语句中进行阻塞调用。例如:

    1void vACoRoutineFunction( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
    2{
    3 // Co-routines must start with a call to crSTART().
    4 crSTART( xHandle );
    5
    6 for( ;; )
    7 {
    8 // It is fine to make a blocking call here,
    9 crDELAY( xHandle, 10 );
    10
    11 switch( aVariable )
    12 {
    13 case 1 : // Cannot make a blocking call here!
    14 break;
    15 default: // Or here!
    16 }
    17 }
    18
    19 // Co-routines must end with a call to crEND().
    20 crEND();
    21}