• FreeRTOS 任务挂起和恢复


    在使用RTOS的时候一个实时应用可以作为一个独立的任务。每个任务都有自己的运行环境, 不依赖于系统中其他的任务或者RTOS调度器。 任何一个时间点只能有一个任务运行,具体运行哪个任务是由RTOS调度器来决定的, RTOS调度器因此就会重复的开启、关闭每个任务

    任务状态
    运行态
    当一个任务正在运行时,那么就说这个任务处于运行态,处于运行态的任务就是当前正在
    使用处理器的任务

    就绪态
    可以运行的任务。有一个同优先级或者更高优先级的任务正在运行

    阻塞态
    一个任务当前正在等待某个外部事件

    挂起态
    进入挂起态以后也不能被调度器调用。任务进入和退出挂起态通过调用函数vTaskSuspend()和xTaskResume()

    任务状态转换
    1

    任务创建

    BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, //函数指针
                                const char * const pcName,
                                const uint16_t usStackDepth, //堆栈大小
                                void * const pvParameters, //给任务传递参数
                                UBaseType_t uxPriority, //任务的优先级
                                TaskHandle_t * const pxCreatedTask /*任务句柄*/) PRIVILEGED_FUNCTION;

    pxTaskCode:任务函数
    pcName:任务名字
    usStackDepth:任务堆栈大小
    pvParameters:传递给任务函数的参数
    uxPriority:任务优先级
    pxCreatedTask:任务句柄

    TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode,
                                        const char * const pcName,
                                        const uint32_t ulStackDepth,
                                        void * const pvParameters,
                                        UBaseType_t uxPriority,
                                        StackType_t * const puxStackBuffer,
                                        StaticTask_t * const pxTaskBuffer ) PRIVILEGED_FUNCTION;

    puxStackBuffer:任务堆栈。一般为数组
    pxTaskBuffer:任务控制块

    任务删除

    void vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION;

    xTaskToDelete:任务句柄

    挂起任务

    void vTaskSuspend( TaskHandle_t xTaskToSuspend )

    恢复任务

    void vTaskResume( TaskHandle_t xTaskToResume )

    中断服务函数中恢复任务运行

    BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume )

    举例

    TaskHandle_t pxCreatedTask;
    
    void TIM4_IRQHandler()
    {
        if(TIM_GetITStatus(TIM4, TIM_IT_Update) == 1)
        {
            xTaskResumeFromISR(pxCreatedTask); //中断服务函数中恢复任务运行
        }
    
        TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
    } 
    
    void key()
    {
        static u8 flag = 1;
    
        if(flag == 1 && key_up == 1)
        {
            vTaskDelay(10);
            if(key_up == 1)
            {
                flag = 0;
                vTaskSuspend(pxCreatedTask); //挂起任务
            }
        }
        else if(key_up == 0)
        {
            vTaskDelay(10);
            if(key_up == 0)
            {
                flag = 1;
            }
        }
    }
    
    void vTask_key(void *t)
    {
        while(1)
        {
            key();
        }
    }
    
    int main(void)
    {
        TIM4_init(10000, 36000-1); //初始化定时器(详见定时器章节)
    
        xTaskCreate(vTask, "vTask", 50, NULL, 1, &pxCreatedTask);  
        xTaskCreate(vTask_key, "vTask_key", 50, NULL, 2, NULL); 
        vTaskStartScheduler(); 
    }

    实验现象:当按键按下,挂起任务。当定时器中断产生,恢复任务运行

  • 相关阅读:
    C#博客随笔之四:使用C#模拟办公网登录HttpClient的使用
    C#博客随笔之三:Linq in C#
    C#博客随笔之二:wp开发之弹出对话框
    C#博客随笔之一:使用C#的第一个WP程序
    Fedora15命令速查手册
    乐观是一种智慧
    完全教程 Aircrackng破解WEP、WPAPSK加密利器
    FreeBSD常用命令大全
    Linux 网络管理员指南——前言
    API
  • 原文地址:https://www.cnblogs.com/zhangxuechao/p/11709533.html
Copyright © 2020-2023  润新知