• 【freertos】003-任务基础知识


    前言

    资源:

    3.1 任务概念

    进程:进程是程序执行的过程,是程序在执行过程中分配和管理资源的基本单位。拥有独立的虚拟地址空间。

    线程:线程是CPU调度和分派的基本单位。与其它同一进程的线程共享当前进程资源。

    协程:比线程更加轻量级的存在,不是由操作系统内核管理,而是由程序控制的。其实就是在同一线程内时分地执行不同的子程序。(注意:不是函数调用)

    还有管程、纤程。

    并发:多个任务看起来是同时进行, 这是一种假并行。

    并行:并行是指令同一时刻一起运行。

    对于目前主流的RTOS的任务,大部分都属于并发的线程。

    因为MCU上的资源每个任务都是共享的,可以认为是单进程多线程模型。

    3.2 任务状态

    freertos有四种状态,每种状态都有对应的状态链表管理。

    运行态:占用CPU使用权时的状态。

    就绪态:能够运行(没有被阻塞和挂起),但是当前没有运行的任务的状态。

    阻塞态:由于等待信号量、消息队列、事件标志组、调用延迟函数等而处于的状态被称之为阻塞态。

    挂起态:调用函数vTaskSuspend()对指定任务进行挂起,挂起后这个任务将不被执行。

    • 调用函数xTaskResume()可退出挂起状态。
    • 不可以指定超时周期事件(不可以通过设定超时事件而退出挂起状态)

    任务状态转换图:

    3.3 任务优先级

    每个任务被分配一个从0到(configMAX_PRIORITIES - 1)的优先级。

    configMAX_PRIORITIES 是在 FreeRTOSConfig.h文件中被定义。

    优先级数值越高,优先级越高。

    idle任务的优先级为0。

    多个任务可以共享一个任务优先级。

    如果在FreeRTOSConfig.h文件中配置宏定义configUSE_TIME_SLICING为1,或者没有配置此宏定义,时间片调度都是使能的。

    使能时间片后,处于就绪态的多个相同优先级任务将会以时间片切换的方式共享处理器。

    如果硬件架构支持CLZ指令,可以使用该特性,使能配置如下:

    1. FreeRTOSConfig.hconfigUSE_PORT_OPTIMISED_TASK_SELECTION设置为1;
    2. 最大优先级数目configMAX_PRIORITIES不能大于CPU位数。

    3.4 空闲任务和空闲任务钩子

    3.4.1 空闲任务

    空闲任务是启动RTOS调度器时由内核自动创建的任务,其优先级为0,确保系统中至少有一个任务在运行。

    空闲任务可用来释放RTOS分配给被删除任务的内存。

    3.4.2 空闲任务钩子

    空闲任务钩子是一个函数,每一个空闲任务周期被调用一次。

    空闲任务钩子应该满足一下条件:

    1. 不可以调用可能引起空闲任务阻塞的API函数;
    2. 不应该陷入死循环,需要留出部分时间用于系统处理系统资源回收。

    3.4.3 创建空闲钩子

    FreeRTOSConfig.h头文件中设置configUSE_IDLE_HOOK为1;

    定义一个函数,名字和参数原型如下所示:

    一般设置CPU进入低功耗模式都是使用空闲任务钩子函数实现的。

    3.5 创建任务

    任务的创建有两种:创建静态内存任务和创建动态内存任务。

    3.5.1 任务参数相关概念

    任务入口函数:即是任务函数,是该任务需要跑的函数。

    任务名称:即是任务名,主要用于调试。

    任务堆栈大小:即是任务栈大小,单位是word。

    任务入口函数参数:传递给任务入口函数的参数。在任务函数里,通过形参获得。

    任务控制块:主要用于内核管理任务,记录任务信息。

    任务句柄:用于区分不同的任务,用于找到该任务的任务控制块。

    3.5.2 创建静态内存任务

    xTaskCreateRestrictedStatic(),该函数不讲解,因为需要MPU,想研究的同学可以参考:freertos官网API

    3.5.2.1 配置静态内存

    创建静态内存任务需要先实现以下内容:

    1. 需要在FreeRTOSConfig.h打开configSUPPORT_STATIC_ALLOCATION宏,开启静态内存。

    2. 开启静态内存的同时需要实现两个函数:(使用静态内存分配任务堆栈和任务控制块内存)

      1. vApplicationGetIdleTaskMemory():空闲任务堆栈函数。
      2. vApplicationGetTimerTaskMemory():定时器任务堆栈函数。
    3. 注意静态内存对齐。

    3.5.2.2 实现空闲任务堆栈函数

    实现该函数是为了给内核提供空闲任务关于空闲任务控制块和空闲任务堆栈的相关信息。

    3.5.2.3 实现定时器任务堆栈函数

    实现该函数是为了给内核创建定时器任务时提供定时器任务控制块和定时器任务堆栈的相关信息。

    3.5.2.4 配置内存对齐

    内存对齐的配置在portmacro.h里面的portBYTE_ALIGNMENT宏,按自己需求配置即可。

    在任务堆栈初始化时会把栈顶指针纠正为内存对齐。参考下列代码:

    纠正后可以通过以下代码检查是否正确的代码如下:

    3.5.2.5 分配静态内存

    静态内存分配是有编译器决定的。

    在freertos中,创建任务需要分配的内存主要是任务控制块和任务堆栈。

    3.5.2.6 创建任务原型

    创建任务函数原型:

    3.5.2.7 创建任务

    3.5.3 创建动态内存任务

    3.5.3.1 配置动态内存

    动态内存配置是在FreeRTOSConfig.h配置的,这些内存主要供给FreeRTOS动态内存分配函数使用。

    而freertos的动态内存管理是有文件heap_x.c实现的,具体实现算法,后面讲到内存时会分析。

    3.5.3.2 任务句柄

    3.5.3.3 创建任务原型

    创建任务函数原型:

    3.5.3.4 创建任务

    3.6 删除任务

    3.6.1 配置删除任务

    在文件FreeRTOSConfig.h中,必须定义宏INCLUDE_vTaskDelete 为 1,删除任务的API才会失效。

    调用API删除任务后,将会从就绪、阻塞、暂停和事件列表中移除该任务。

    如果是动态内存创建任务,删除任务后,其占用的空间资源有空闲任务释放,所以删除任务后尽量保证空闲任务获取一定的CPU时间。

    如果是静态内存创建任务,删除任务后,需要自己处理释放任务占用的空间资源。

    3.6.2 删除任务原型

    注意:传入的参数为任务句柄,当出入的参数为NULL时,表示删除调用者当前的任务。

    3.7 实战

    源码:拉取 freertos_on_linux_task_01 文件夹

    结果:


    __EOF__

  • 本文作者: 李柱明
  • 本文链接: https://www.cnblogs.com/lizhuming/p/16065556.html
  • 关于博主: 嵌入式从业者。RTOS、Linux ...
  • 版权声明: 版权归博主所有
  • 声援博主: 学习笔记分享
  • 相关阅读:
    【Node.js】第七章 express路由与中间件
    Redis——》数据类型:zset(有序集合)
    手把手教你写Linux线程池
    【拖拖拖没烦恼;难难难睡不着】22届错过校招未就业|什么是校招?二本进不去大厂,校招不重要?
    EDA实验-----3-8译码器设计(QuartusII)
    Yocto系列讲解[实战篇]85 - 制作ubi镜像和自动挂载ubifs文件系统
    第五十八章 学习常用技能 - 查看查询缓存
    Xubuntu16.04系统中安装create_ap创建无线AP
    软件设计师冲刺:临考快速记忆
    高标准企业级安全性,华为云会议为线上沟通保驾护航
  • 原文地址:https://www.cnblogs.com/lizhuming/p/16065556.html