FreeRTOS API参考——内核控制

Modules

 

taskYIELD

task.h

taskYIELD()用于请求将上下文切换到另一个任务。 但是,如果没有其他任务比调用taskYIELD()的任务具有更高或更高的优先级,则RTOS调度程序将简单地选择名为taskYIELD()的任务以再次运行。

如果configUSE_PREEMPTION设置为1,则RTOS调度程序将始终运行能够运行的最高优先级任务,因此调用taskYIELD()将永远不会导致切换到更高优先级的任务。

 

taskDISABLE_INTERRUPTS()

task.h

如果使用中的端口支持configMAX_SYSCALL_INTERRUPT_PRIORITY常量(或configMAX_API_CALL_INTERRUPT_PRIORITY)常量,则taskDISABLE_INTERRUPTS将禁用所有中断,或者屏蔽(禁用)中断,直到configMAX_SYSCALL_INTERRUPT_PRIORITY设置。 检查正在使用的端口的taskDISABLE_INTERRUPTS的实现。

如果使用的端口不支持configMAX_SYSCALL_INTERRUPT_PRIORITY常量,则taskDISABLE_INTERRUPTS()将全局禁用所有可屏蔽中断。

通常,不会直接调用此宏,而应在其位置使用taskENTER_CRITICAL()和taskEXIT_CRITICAL()。

 

taskENABLE_INTERRUPTS()

task. h

启用微控制器中断的宏。

通常,不会直接调用此宏,而应在其位置使用taskENTER_CRITICAL()和taskEXIT_CRITICAL()。

 

taskENTER_CRITICAL()

taskEXIT_CRITICAL()

task. h
void taskENTER_CRITICAL( void );
void taskEXIT_CRITICAL( void );

通过调用taskENTER_CRITICAL()输入关键部分,然后通过调用taskEXIT_CRITICAL()退出关键部分。

taskENTER_CRITICAL()和taskEXIT_CRITICAL()宏提供了一个基本的临界区实现,可以通过简单地全局禁用中断或最高特定中断优先级来禁用中断。有关在不禁用中断的情况下创建关键部分的信息,请参见vTaskSuspendAll()RTOS API函数。

如果正在使用的FreeRTOS端口未使用configMAX_SYSCALL_INTERRUPT_PRIORITY内核配置常量(也称为configMAX_API_CALL_INTERRUPT_PRIORITY),则调用taskENTER_CRITICAL()将使中断全局禁用。如果使用的FreeRTOS端口确实使用了configMAX_SYSCALL_INTERRUPT_PRIORITY内核配置常量,则调用taskENTER_CRITICAL()将使中断处于configMAX_SYSCALL_INTERRUPT_PRIORITY设置的中断优先级及以下,并禁用所有优先级较高的中断。

抢占式上下文切换仅在中断内部发生,因此在禁用中断时不会发生。因此,除非任务显式尝试阻止或屈服(它不应在关键部分内部执行此操作),否则确保称为taskENTER_CRITICAL()的任务将保持在运行状态,直到退出关键部分为止。

对taskENTER_CRITICAL()和taskEXIT_CRITICAL()的调用被设计为嵌套。因此,仅当对taskENTER_CRITICAL()的每个先前调用都执行了对taskEXIT_CRITICAL()的调用时,才会退出关键部分。

关键部分必须保持很短,否则将对中断响应时间产生不利影响。每次对taskENTER_CRITICAL()的调用都必须与对taskEXIT_CRITICAL()的调用紧密配对。

不得从关键部分调用FreeRTOS API函数。

不得从中断服务程序(ISR)调用taskENTER_CRITICAL()和taskEXIT_CRITICAL()–有关等效的中断安全信息,请参阅taskENTER_CRITICAL_FROM_ISR()和taskEXIT_CRITICAL_FROM_ISR()。

用法示例:

/* A function that makes use of a critical section. */
void vDemoFunction( void )
{
    /* Enter the critical section.  In this example, this function is itself called
    from within a critical section, so entering this critical section will result
    in a nesting depth of 2. */
    taskENTER_CRITICAL();

    /* Perform the action that is being protected by the critical section here. */


    /* Exit the critical section.  In this example, this function is itself called
    from a critical section, so this call to taskEXIT_CRITICAL() will decrement the
    nesting count by one, but not result in interrupts becoming enabled. */
    taskEXIT_CRITICAL();
}


/* A task that calls vDemoFunction() from within a critical section. */
void vTask1( void * pvParameters )
{
    for( ;; )
    {
        /* Perform some functionality here. */


        /* Call taskENTER_CRITICAL() to create a critical section. */
        taskENTER_CRITICAL();



        /* Execute the code that requires the critical section here. */


        /* Calls to taskENTER_CRITICAL() can be nested so it is safe to call a
        function that includes its own calls to taskENTER_CRITICAL() and
        taskEXIT_CRITICAL(). */
        vDemoFunction();


        /* The operation that required the critical section is complete so exit the
        critical section.  After this call to taskEXIT_CRITICAL(), the nesting depth
        will be zero, so interrupts will have been re-enabled. */
        taskEXIT_CRITICAL();
    }
}

 

taskENTER_CRITICAL_FROM_ISR()

taskEXIT_CRITICAL_FROM_ISR()

task. h

UBaseType_t taskENTER_CRITICAL_FROM_ISR( void );
void taskEXIT_CRITICAL_FROM_ISR( UBaseType_t uxSavedInterruptStatus );

可以在中断服务程序(ISR)中使用的taskENTER_CRITICAL()和taskEXIT_CRITICAL()的版本。

在ISR中,通过调用taskENTER_CRITICAL_FROM_ISR()进入关键部分,然后通过调用taskEXIT_CRITICAL_FROM_ISR()退出关键部分。

taskENTER_CRITICAL_FROM_ISR()和taskEXIT_CRITICAL_FROM_ISR()宏提供了一个基本的临界区实现,可以通过简单地全局禁用中断或最高特定中断优先级来禁用中断。

如果所使用的FreeRTOS端口支持中断嵌套,则调用taskENTER_CRITICAL_FROM_ISR()将在configMAX_SYSCALL_INTERRUPT_PRIORITY(或configMAX_API_CALL_INTERRUPT_PRIORITY)内核配置设置的中断优先级及以下禁用中断,并使所有其他中断优先级保持启用状态。如果使用的FreeRTOS端口不支持中断嵌套,则taskENTER_CRITICAL_FROM_ISR()和taskEXIT_CRITICAL_FROM_ISR()将无效。

对taskENTER_CRITICAL_FROM_ISR()和taskEXIT_CRITICAL_FROM_ISR()的调用被设计为嵌套,但是如何使用宏的语义与taskENTER_CRITICAL()和taskEXIT_CRITICAL()等效。

关键部分必须保持非常短,否则它们将对优先级较高的中断的响应时间产生不利影响,否则该中断将嵌套。每次对taskENTER_CRITICAL_FROM_ISR()的调用都必须与对taskEXIT_CRITICAL_FROM_ISR()的调用紧密配对。

不得从关键部分调用FreeRTOS API函数。

参数:

 uxSavedInterruptStatus

taskEXIT_CRITICAL_FROM_ISR()将uxSavedInterruptStatus作为其唯一参数。 用作uxSavedInterruptStatus参数的值必须是从对taskENTER_CRITICAL_FROM_ISR()的匹配调用返回的值。

 

taskENTER_CRITICAL_FROM_ISR()不接受任何参数。

返回值:

taskENTER_CRITICAL_FROM_ISR()返回中断屏蔽状态,与调用宏之前一样。 在对taskEXIT_CRITICAL_FROM_ISR()的匹配调用中,必须将taskENTER_CRITICAL_FROM_ISR()返回的值用作uxSavedInterruptStatus参数。

taskEXIT_CRITICAL_FROM_ISR()不返回值。

用法示例:

/* A function called from an ISR. */
void vDemoFunction( void )
{
UBaseType_t uxSavedInterruptStatus;


    /* Enter the critical section.  In this example, this function is itself called from
    within a critical section, so entering this critical section will result in a nesting
    depth of 2. Save the value returned by taskENTER_CRITICAL_FROM_ISR() into a local
    stack variable so it can be passed into taskEXIT_CRITICAL_FROM_ISR(). */
    uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR();


    /* Perform the action that is being protected by the critical section here. */


    /* Exit the critical section.  In this example, this function is itself called from a
    critical section, so interrupts will have already been disabled before a value was
    stored in uxSavedInterruptStatus, and therefore passing uxSavedInterruptStatus into
    taskEXIT_CRITICAL_FROM_ISR() will not result in interrupts being re-enabled. */
    taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus );
}


/* A task that calls vDemoFunction() from within an interrupt service routine. */
void vDemoISR( void )
{
UBaseType_t uxSavedInterruptStatus;


    /* Call taskENTER_CRITICAL_FROM_ISR() to create a critical section, saving the
    returned value into a local stack variable. */
    uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR();


    /* Execute the code that requires the critical section here. */


    /* Calls to taskENTER_CRITICAL_FROM_ISR() can be nested so it is safe to call a
    function that includes its own calls to taskENTER_CRITICAL_FROM_ISR() and
    taskEXIT_CRITICAL_FROM_ISR(). */
    vDemoFunction();


    /* The operation that required the critical section is complete so exit the
    critical section.  Assuming interrupts were enabled on entry to this ISR, the value
    saved in uxSavedInterruptStatus will result in interrupts being re-enabled.*/
    taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus );
}

 

vTaskStartScheduler

task. h

void vTaskStartScheduler( void );

启动RTOS调度程序。 调用RTOS内核后,可以控制执行哪些任务以及何时执行。

启动RTOS调度程序时,会自动创建空闲任务以及可选的计时器守护程序任务。

仅当没有足够的RTOS堆来创建空闲或计时器守护程序任务时,vTaskStartScheduler()才会返回。

所有RTOS演示应用程序项目都包含使用vTaskStartScheduler()的示例,通常在main.c的main()函数中。

用法示例:

void vAFunction( void )
{
     // Tasks can be created before or after starting the RTOS scheduler
     xTaskCreate( vTaskCode,
                  "NAME",
                  STACK_SIZE,
                  NULL,
                  tskIDLE_PRIORITY,
                  NULL );

     // Start the real time scheduler.
     vTaskStartScheduler();

     // Will not get here unless there is insufficient RAM.
}

 

vTaskEndScheduler

task. h

void vTaskEndScheduler( void );

注意:这仅适用于x86实模式PC端口。

停止RTOS内核滴答。 所有创建的任务将被自动删除,并且多任务处理(抢占式或协作式)将停止。 然后,从调用vTaskStartScheduler()的点继续执行,就好像vTaskStartScheduler()刚刚返回一样。

请参阅演示应用程序文件主体。 有关使用vTaskEndScheduler()的示例,请参见demo / PC目录中的c。

vTaskEndScheduler()要求在可移植层中定义退出功能(有关PC端口,请参见端口c中的vPortEndScheduler())。 这将执行特定于硬件的操作,例如停止RTOS内核滴答。

vTaskEndScheduler()将导致释放RTOS内核分配的所有资源-但不会释放应用程序任务分配的资源。

用法示例:

void vTaskCode( void * pvParameters )
{
     for( ;; )
     {
         // Task code goes here.

         // At some point we want to end the real time kernel processing
         // so call ...
         vTaskEndScheduler ();
     }
}


void vAFunction( void )
{
     // Create at least one task before starting the RTOS kernel.
     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );

     // Start the real time kernel with preemption.
     vTaskStartScheduler();


     // Will only get here when the vTaskCode () task has called
     // vTaskEndScheduler ().  When we get here we are back to single task
     // execution.
}

vTaskSuspendAll

task. h

void vTaskSuspendAll( void );

在不禁用中断的情况下挂起调度程序。 调度程序挂起时不会发生上下文切换。 调度程序挂起时发生的RTOS滴答将保持挂起状态,直到通过调用xTaskResumeAll()取消调度程序为止。

挂起调度程序时,不得调用可能导致上下文切换的API函数(例如vTaskDelayUntil(),xQueueSend()等)。

用法示例:

void vTask1( void * pvParameters )
{
     for( ;; )
     {
         // Task code goes here.

         // ...

         // At some point the task wants to perform a long operation during
         // which it does not want to get swapped out.  It cannot use
         // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
         // operation may cause interrupts to be missed - including the
         // ticks.

         // Prevent the RTOS kernel swapping out the task.
         vTaskSuspendAll ();

         // Perform the operation here.  There is no need to use critical
         // sections as we have all the microcontroller processing time.  
         // During this time interrupts will still operate and the RTOS kernel
         // tick count will be maintained.

         // ...

         // The operation is complete.  Restart the RTOS kernel.
         xTaskResumeAll ();
     }
}

 

xTaskResumeAll

task. h

BaseType_t xTaskResumeAll( void );

使用对vTaskSuspendAll()的调用在挂起调度程序后继续。

xTaskResumeAll()仅恢复调度程序。 它不会取消暂停先前通过调用vTaskSuspend()而暂停的任务。

返回值:

     如果恢复调度程序导致上下文切换,则返回pdTRUE,否则返回pdFALSE。

用法示例:

void vTask1( void * pvParameters )
{
     for( ;; )
     {
         /* Task code goes here. */


         /* ... */


         /* At some point the task wants to perform a long operation
         during which it does not want to get swapped out.  It cannot
         use taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length
         of the operation may cause interrupts to be missed -
         including the ticks.
         Prevent the RTOS kernel swapping out the task. */
         vTaskSuspendAll();

         /* Perform the operation here.  There is no need to use critical
         sections as we have all the microcontroller processing time.
         During this time interrupts will still operate and the real
         time RTOS kernel tick count will be maintained. */


         /* ... */


         /* The operation is complete.  Restart the RTOS kernel.  We want to force
         a context switch - but there is no point if resuming the scheduler
         caused a context switch already. */
         if( !xTaskResumeAll () )
         {
              taskYIELD ();
         }
     }
}

 

vTaskStepTick

task.h

void vTaskStepTick( TickType_t xTicksToJump );

如果将RTOS配置为使用无滴答空闲功能,则只要空闲任务是唯一能够执行的任务,滴答中断就会停止,微控制器进入低功耗状态。 退出低功耗状态后,必须校正滴答计数值,以说明停止时经过的时间。

如果FreeRTOS端口包括默认的portSUPPRESS_TICKS_AND_SLEEP()实现,则内部将使用vTaskStepTick()来确保维护正确的滴答计数值。 vTaskStepTick()是一个公共API函数,它允许覆盖默认的portSUPPRESS_TICKS_AND_SLEEP()实现,如果使用的端口不提供默认值,则可以提供portSUPPRESS_TICKS_AND_SLEEP()。

必须将configUSE_TICKLESS_IDLE配置常量设置为1,vTaskStepTick()才可用。

参数:

  xTicksToJump

自滴答中断停止以来已过去的RTOS滴答次数。 为了正确操作,该参数必须小于或等于portSUPPRESS_TICKS_AND_SLEEP()参数。

返回值:

    无

用法示例:

该示例显示了对多个函数的调用。 只有vTaskStepTick()是FreeRTOS API的一部分。 其他功能特定于正在使用的硬件上可用的时钟和省电模式,因此必须由应用程序编写器提供。

/* First define the portSUPPRESS_TICKS_AND_SLEEP().  The parameter is the time,
in ticks, until the kernel next needs to execute. */
#define portSUPPRESS_TICKS_AND_SLEEP( xIdleTime ) vApplicationSleep( xIdleTime )


/* Define the function that is called by portSUPPRESS_TICKS_AND_SLEEP(). */
void vApplicationSleep( TickType_t xExpectedIdleTime )
{
unsigned long ulLowPowerTimeBeforeSleep, ulLowPowerTimeAfterSleep;


    /* Read the current time from a time source that will remain operational
    while the microcontroller is in a low power state. */
    ulLowPowerTimeBeforeSleep = ulGetExternalTime();


    /* Stop the timer that is generating the tick interrupt. */
    prvStopTickInterruptTimer();


    /* Configure an interrupt to bring the microcontroller out of its low power
    state at the time the kernel next needs to execute.  The interrupt must be
    generated from a source that is remains operational when the microcontroller
    is in a low power state. */
    vSetWakeTimeInterrupt( xExpectedIdleTime );

    /* Enter the low power state. */
    prvSleep();


    /* Determine how long the microcontroller was actually in a low power state
    for, which will be less than xExpectedIdleTime if the microcontroller was
    brought out of low power mode by an interrupt other than that configured by
    the vSetWakeTimeInterrupt() call.  Note that the scheduler is suspended
    before portSUPPRESS_TICKS_AND_SLEEP() is called, and resumed when
    portSUPPRESS_TICKS_AND_SLEEP() returns.  Therefore no other tasks will
    execute until this function completes. */
    ulLowPowerTimeAfterSleep = ulGetExternalTime();


    /* Correct the kernels tick count to account for the time the microcontroller
    spent in its low power state. */
    vTaskStepTick( ulLowPowerTimeAfterSleep - ulLowPowerTimeBeforeSleep );

    /* Restart the timer that is generating the tick interrupt. */
    prvStartTickInterruptTimer();
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值