1:裸机程序执行
在裸机程序中,对于简单的方式,经常采用查询方式,即一件事完成后,再去完成另一件事,按照顺序执行,这种执行导致当有紧急情况时,可能会得不到处理。对于更复杂的程序,为了能够去及时执行紧急任务,于是便产生了中断(ISR)。
查询+中断方式能够解决大部分裸机上的应用,但随着工程的复杂,裸机的程序可能会变得越来越复杂,中断的复杂和嵌套可能会带来难以解决得问题
2:为什么要移值FreeRTOS?
RTOS相对于裸机得最大优点便是其可以通过调度实现多任务管理,即由调度器来决定当前任务的执行,即便对于大部分单片机而言,同一时刻只能执行一个任务,但通过调度算法可以实现不同时刻,多个任务复杂有序的执行,从而达到多任务效果(看起来所有任务同时运行)。
3:实例说明
我们来看一下,一个例子:
周末,你有两个事情要处理:
1:陪同学打篮球,
2:在打球的过程中,女朋友随时有可能给你发信息,你需要及时回复信息
裸机处理方式:
int main(void)
{
...
while(1)
{
打篮球();
回信息();
}
}
假如:打一局篮球需要15分钟,回复一次信息需要5分钟,
那就变成了,最慢你女朋友可能需要15分钟后,才能等到你回复信息,你同学每次需要等5分钟,才能打下一局篮球。
这样是不是两边都很不爽,特别是你女朋友,可能你有大麻烦。
RTOS处理方式:
void main(void)
{
/* 创建打游戏任务 */
xTaskCreate(打篮球)
/* 创建回复信息任务 */
xTaskCreate(回复信息)
}
void 篮球(void)
{
while(1)
{
打篮球();
}
}
void 信息(void)
{
while(1)
{
回复信息();
}
}
FreeRTOS和裸机不同,它会让打篮球运行一个时间片,回复信息运行一个时间片,一个时间片的时间是可以我们自己设置的,就是滴答定时器的一个节拍,例如我们可以设置1ms来运行,这有点类似于一个伪多线程。
微观来看我们实际是两个任务交替运行,但是宏观上我们却感觉两个任务在同时运行
---这是用OS最大的好处,通过任务调度和时间片,实现伪多线程
再回到上面的例子:(因为轮流单个时间片足够短)
女朋友和同学的客观感受都是实时的,好像你是同时即在陪他们打篮球,又及时的回复了女朋友信息。
这。。。,简直的分身术。。。。
好,言归正转,开始FreeRTOS移值。
4:前期准备工作
1:硬件环境:这里用到的是华芯微特的一个48Mhz MCU SWM181
2:硬件代码:
3:FreeRTOS源代码:(可以直接官网下载)
Download FreeRTOS - FreeRTOS™
5:开始移值
FreeRTOS源代码结构
我们先在原始的工程目录下,新建一个FreeRTOS的文件夹,用来存放OS相关的文件
在FreeRTOS下面,再新建3个文件夹
- src文件夹用来存放源码
- config文件夹用来存配置文件:(作OS的配置和裁剪)
- port文件夹用来存放移植平台的相关文件
接下来我们将FreeRTOS源码的移植到我们新建的文件夹中
首先我们打开源码中的Soure文件夹中的protable文件夹,找到MemMang文件夹,这个文件夹中都是内存管理文件,我们只用到heap_4.c文件,将其复制到port文件夹中
一般情况下,用heap_4.c就行
a: 接着我们在刚才的portable文件夹中,找到RVDS文件夹,选择里面的ARM_M3中的port.c和portmacro.h两个文件,也复制到我们的工程文件port文件夹中
b:回到source文件夹中,将这个文件夹中的.c文件全部复制到工程新建的src文件夹中
c:在source文件夹中的include文件夹里全部都是FreeRTOS的头文件,将其添加到工程新建的inc文件夹中
d:添加一个配置文件,在FreeRTOS文件夹中的demo文件夹中找到CORTEX_STM32F103_Keil文件夹,复制里面的FreerRTOSConfig.h文件到新建的FreeRTOS文件夹中
e:接着我们添加文件路径,打开keil软件点击魔术棒,进入C/C++,在Include Paths中添加文件路径,将FreeRTO、src、inc、port的路径全部添加进来
f:新建组将文件全部添加到工程中,点击魔术棒旁边的三个格子的图标,选择新建组,我们分别新建FreeRTOS_src、FreeRTOS_config、FreeRTOS_port三个组,将工程文件夹src中的所有.c文件添加到FreeRTOS_src中,将工程文件夹port中的文件(heap_4.c、port.c添加到FreeRTOS_port中,还有配置文件FreeRTOSConfig.h添加到FreeRTOS_config组中
(如图:移值后的文件内容)
6:新建Task
好,到此基本就完成了,编译通过,就可以了。
这个移值相对是比较简单的,大家可以自己实际操作一下。