在FreeRTOS中,每个任务都是无限循环的,一般来说任务是不会结束运行的,也不允许有返回值,任务的结构一般都是
While(1)
{
/****一直在循环执行*****/
}
如果不需要这个任务了,那就把它删除。
移植的教程我就不写了,超级简单的,按照已有的大把教程来做就行了。(如果没有资源,可以在后台找我,我给一份移植的教程/源码)
其实FreeRTOS的运用及其简单,移植成功按照自己的意愿来配置即可,而且FreeRTOS有很多手册,虽然作者英语很差,但是我有谷歌翻译!!!哈哈哈
既然一直都说任务任务,那肯定要有任务啊,创建任务:
// task. h task.c
BaseType_t xTaskCreate( TaskFunction_t pvTaskCode,
const char * const pcName,
uint16_t usStackDepth,
void *pvParameters,
UBaseType_t uxPriority,
TaskHandle_t *pvCreatedTask
);
函数的原型都有,按照字面的理解
TaskFunction_t pvTaskCode //传递进来的是任务函数
const char * const pcName //传递进来的是任务Name
uint16_t usStackDepth //传入的是堆栈的大小
在这里要说明一下,在裸机中开发,我们不管局部变量还是全局变量,反正定义了就能用,中断发生时,函数返回地址发哪里,我们也不管。但是在操作系统中,我们必须弄清楚我们的参数是怎么储存的,他们的大小是多大,就需要我们去定义这个堆栈的大小。它就是用来存放我们的这些东西的。太小,导致堆栈溢出,发生异常。(栈是单片机 RAM 里面一段连续的内存空间)
因为在多任务系统中,每个任务都是独立的,互不干扰的,所以要为每个任务都分配独立的栈空间。
void *pvParameters //传递给任务函数的参数
UBaseType_t uxPriority //任务优先级
TaskHandle_t *pvCreatedTask //任务句柄
任务句柄也是很重要的东西,我们怎么删除任务也是要用到任务句柄,其实说白了,我操作系统怎么知道你是什么任务,靠的就是任务句柄的判断,才知道哪个任务在执行,哪个任务被挂起。下一个要执行的任务是哪个等等,靠的都是任务句柄。
那么要使用这些东西,我们肯定要实现啦,下面就是实现的定义,要定义优先级,堆栈大小,任务句柄,任务函数等。
创建任务后,可以开启任务调度了,然后系统就开始运行。
xTaskCreate((TaskFunction_t )LED_Task, //任务函数
(const char* )"led_task", //任务名称
(uint16_t )LED_STK_SIZE, //任务堆栈大小
(void* )NULL, //传递给任务函数的参数
(UBaseType_t )START_TASK_PRIO, //任务优先级
(TaskHandle_t* )&LED_Task_Handler);//任务句柄
vTaskStartScheduler(); //开启任务调度
这个创建任务的函数 xTaskCreate 是有返回值的,其返回值的类型是BaseType_t。
我们在描述中看看:
我们其实可以在任务调度的时候判断一下返回值是否为pdPASS从而知道任务创是否建成功。并且打印一个信息作为调试。因为后面使用信号量这些的时候都要知道信号量是否创建成功,使得代码健壮一些。免得有隐藏的bug。
然后就是具体实现我们的任务LED_Task是在做什么的
当然可以实现多个任务。还是很简单的。
这就是一个简单的操作系统的概述。
下一篇,应该是讲述开启任务调度与任务切换的具体过程。
这个可以参考野火的书籍《从 0 到 1 教你写 uCOS-III》,写的很好,简单易懂。