FreeRTOS 笔记之④:任务的定义与任务的切换

目录

1. 任务是什么

2. 创建任务

2.1 定义任务栈

2.2 定义任务函数

2.3 定义任务控制块

2.4  实现任务创建函数

2.4.1 xTaskCreateStatic()函数

2.4.2 prvInitialiseNewTask()函数

2.4.3 pxPortInitialiseStack()函数

3. 实现就绪列表

3.1 定义就绪列表

3.2 就绪列表初始化

3.3 将任务插入到就绪列表

4. 实现调度器

4.1 启动调度器

4.1.1 vTaskStartScheduler()函数

4.1.2 xPortStartScheduler()函数

4.1.3 prvStartFirstTask()函数

4.1.4 vPortSVCHandler()函数

4.2 任务切换

4.2.1 taskYIELD()

4.2.2 xPortPendSVHandler()函数

4.2.3 TaskSwitchContext()函数

5. 例程试验

6. SVC 和PendSV


1. 任务是什么

在裸机系统中,系统的主体就是main函数里面顺序执行的无限循环,这个无限循环里面CPU按照顺序完成各种事情。在多任务系统中,我们根据功能的不同,把整个系统分割成一个个独立的且无法返回的函数,这个函数我们称为任务。

任务(task),是抽象的东西,并没有一个严格的定义,一般是指由软件完成的一个活动。对于类似freeRTOS的系统来说,任务即线程/进程。

任务的大概形式具体见代码

void task_entry( void * parg)
{
    /* 任务主体,无限循环且不能返回 */
    for (;;) {
        /* 任务主体代码 */
    }
}

2. 创建任务

2.1 定义任务栈

在一个裸机系统中,如果有全局变量,有子函数调用,有中断发生。那么系统在运行的时候,全局变量放在哪里,子函数调用时,局部变量放在哪里,中断发生时,函数返回地址放哪里。如果只是单纯的裸机编程,它们放哪里我们不用管,但是如果要写一个RTOS,这些种种环境参数,我们必须弄清楚他们是如何存储的。在裸机系统中,他们统统放在一个叫栈的地方,栈是单片机RAM里面一段连续的内存空间,栈的大小一般在启动文件或者链接脚本里面指定,最后由C库函数_main进行初始化。

但是,在多任务系统中,每个任务都是独立的,互不干扰的,所以要为每个任务都分配独立的栈空间,这个栈空间通常是一个预先定义好的全局数组,也可以是动态分配的一段内存空间,但它们都存在于RAM中。

实现两个变量按照一定的频率轮流的翻转,每个变量对应一个任务,那么就需要定义两个任务栈,具体见代码清单。在多任务系统中,有多少个任务就需要定义多少个任务栈。

#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推荐的最小的任务栈。

2.2 定义任务函数

任务是一个独立的函数,函数主体无限循环且不能返回。

/* 软件延时 */
void delay (uint32_t count)
{
	for(; count!=0; co
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值