实时操作系统系统FreeRTOS的学习(1)——任务_freertos面试内容

例如本小节我们要实现两个 LED 按照一定的频率轮流的翻转,每个 LED 对应一个任务,那么就需要定义两个任务栈,具体代码如下所示。在多任务系统中,有多少个任务就需要定义多少个任务栈。

#define TASK1_STACK_SIZE 128
StackType_t Task1Stack[TASK1_STACK_SIZE];

#define TASK2_STACK_SIZE 128
StackType_t Task2Stack[TASK2_STACK_SIZE];

任务栈其实就是一个预先定义好的全局数组,数据类型为StackType_t,大小由TASK1_STACK_SIZE 这个宏来定义,默认为 128,单位为字,即 512 字节,这也是 FreeRTOS 推荐的最小的任务栈

在 FreeRTOS 中,凡是涉及到数据类型的地方,FreeRTOS 都会将标准的 C 数据类型用 typedef重新取一个类型名。这些经过重定义的数据类型放在 portmacro.h 这个头文件。

2.2 定义任务函数

任务是一个独立的函数,函数主体无限循环且不能返回。本章我们在 main.c中定义的两个任务具体代码如下所示:

//任务 1 函数
void task1_task(void *pvParameters)
{
    while(1)
    {
        LED1=0;
        vTaskDelay(200);
        LED1=1;
        vTaskDelay(800);
    }
}
//任务 2 函数
void task2_task(void *pvParameters)
{
    while(1)
    {
        LED2=0;
        vTaskDelay(800);
        LED2=1;
        vTaskDelay(200);
    }
}

特别说明:任务里面的延时函数必须使用 FreeRTOS 里面提供的延时函数,并不能使用我们裸机编程中的那种延时。这两种的延时的区别是 FreeRTOS 里面的延时是阻塞延时,即调用 vTaskDelay()函数的时候,当前任务会被挂起,调度器会切换到其它就绪的任务,从而实现多任务。

FreeRTOS 任务的状态:

(1)运行态

当一个任务正在运行时, 那么就说这个任务处于运行态, 处于运行态的任务就是当前正在使用处理器的任务。 如果使用的是单核处理器的话那么不管在任何时刻永远都只有一个任务处于运行态

(2)就绪态

处于就绪态的任务是那些已经准备就绪(这些任务没有被阻塞或者挂起), 可以运行的任务,但是处于就绪态的任务还没有运行,因为有一个同优先级或者更高优先级的任务正在运行!

(3)阻塞态

如果一个任务当前正在等待某个外部事件的话就说它处于阻塞态, 比如说如果某个任务调用了函数 vTaskDelay()的话就会进入阻塞态, 直到延时周期完成。任务在等待队列、信号量、事件组、通知或互斥信号量的时候也会进入阻塞态。任务进入阻塞态会有一个超时时间,当超过这个超时时间任务就会退出阻塞态,即使所等待的事件还没有来临!

(4)挂起态

像阻塞态一样,任务进入挂起态以后也不能被调度器调用进入运行态, 但是进入挂起态的任务没有超时时间。任务进入和退出挂起态通过调用函数 vTaskSuspend()xTaskResume()

**总结:**FreeRTOS利用这些状态使任务更加灵活的运行,更加节约CPU资源,实时性更强。这些状态都可以由相对应的API函数来控制任务变成哪种状态!!!

2.3 定义任务控制块

在裸机系统中,程序的主体是 CPU 按照顺序执行的。而在多任务系统中,任务的执行是由系统调度的。系统为了顺利的调度任务,为每个任务都额外定义了一个任务控制块,这个任务控制块(TCB)就相当于任务的身份证,里面存有任务的所有信息,比如任务的栈指针,任务名称,任务的形参等。**有了这个任务控制块之后,以后系统对任务的全部操作都可以通过这个任务控制块来实现。**定义一个任务控制块需要一个新的数据类型,该数据类型在 task.c 这 C 文件中声明,具体代码如下所示,使用它可以为每个任务都定义一个任务控制块实体。

typedef struct tskTaskControlBlock
{
    volatile StackType_t *pxTopOfStack; /* 栈顶 */
    ListItem_t xStateListItem; /* 任务节点 */
    StackType_t *pxStack; /* 任务栈起始地址 */
    /* 任务名称,字符串形式 */(4)
    char pcTaskName[ configMAX_TASK_NAME_LEN ];
} tskTCB;
typedef tskTCB TCB_t;

我们在 main.c 文件中为两个任务定义的任务控制块,具体 代码如下所示:

StaticTask_t Task1TaskTCB;
StaticTask_t Task2TaskTCB;

三、 FreeRTOS 的任务

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年嵌入式&物联网开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上嵌入式&物联网开发知识点,真正体系化!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新!!

果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!**](https://bbs.csdn.net/topics/618654289)

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新!!

  • 30
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值