1、freeRTOS
1.1 什么是FreeRTOS
Free就是免费的,RTOS全称是real time operating system,即实时操作系统。FreeRTOS是一个迷你的实时操作系统内核,作为一个轻量级的操作系统,功能包括:任务管理、时间管理、信号量、消息队列、内存管理、记录功能、软件定时器、协程等,可满足较小系统的需要。
严格上来说,FreeRTOS并不是一个实时操作系统,因为它是分时复用的,系统将时间分割成很多时间片,然后轮流执行各个任务。每个任务都是独立运行的,互不影响,由于切块的频率很快,感觉就像是同时运行的一样。
1.2 为什么选择FreeRTOS
第一是其是免费的,源码公开,具有可移植。可裁剪。调度灵活等特点,可以方便地移植到各种单片机上运行;其二是很多半导体厂商产品的SDk(Software Development Kit)软件开发工具包,就是使用FreeRTOS作为其操作系统,尤其是WIFI、蓝牙这些带有协议栈的芯片或模块;其三是因为FreeRTOS的文件数量很少,移植简单。
1.3 FreeRTOS资料与源码下载
2、堆/栈
2.1 堆
堆就是一块空闲的内存,我们可以管理这块内存,从这块内存中取出一部分使用,使用完再释放回去。
//heap_buf就是我们开辟的堆
char heap_buf[1024];
int pos = 0;
void *my_malloc(int size)
{
int old_pos = pos;
pos += size;
return &heap_buf[old_pos];
}
void my_free(void *buf)
{
/* err */
}
int main(void)
{
char ch = 65; // char ch = 'A';
int i;
char *buf = my_malloc(100);
unsigned char uch = 200;
for (i = 0; i < 26; i++)
buf[i] = 'A' + i;
return 0;
}
2.2 栈
在编写代码中,我们可能感觉不到栈的存在,但是它确实一直在默默存在。
void c_fun(void)
{
}
void b_fun(void)
{
}
int a_fun(int val)
{
int a = 8;
a += val;
b_fun();
c_fun();
return a;
}
int main(void)
{
a_fun(46);
return 0;
}
在上面的程序中,main函数调用了a_fun,在a_fun中调用了b_fun和c_fun。main函数在调用a_fun之前,会将返回的地址保存在LR(Link Register)中,然后调用a_fun,在main中返回的地址就是return 0语句所在的位置。
a_fun函数在调用b_fun和c_fun时也是类似的,在调用之前要先将返回的地址保存在LR(Link Register)中,然后去调用,而在a_fun中调用b_fun的返回地址是c_fun所在的语句。那么此时main和a_fun函数的返回值的地址都保存在LR中,LR会不会被覆盖了?
在a_fun函数内部,它会将LR的值存入栈中,然后再来保存本身的返回值地址,这样就不怕LR会被覆盖了,因此函数返回值的地址是被存入栈中的。栈也是一块空闲的内存。在main函数执行时,它会给main函数开辟一部分的栈空间,里面存放LR等寄存器和局部变量的值。
2.3 堆和栈的区别
管理方式不同:栈由操作系统自动分配释放,无需我们手动控制;堆的申请和释放工作由程序员控制,容易产生内存泄漏。
分配方式不同:堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。
空间大小不同:栈的大小要远远小于堆的大小。
生长方向不同:堆的生长方向向上,内存地址由低到高;栈的生长方向向下,内存地址由高到低。
数据结构不同:堆可以看成一棵树,如堆排序;栈是一种先进后出的结构。
作用域的不同:堆的作用域是在全局,栈的作用域是在函数局部。
3、从官方源码精简出第一个freeRTOS
3.1 从官网下载
FreeRTOS - Free RTOS Source Code Downloads, the official FreeRTOS zip file release download
解压之后打开的目录
FreeRTOS-Plus里面是FreeRTOS生态的文件,非必需,tools里面是亚马逊相关的文件,也不需要。文件夹只需要保留FreeRTOS。
进入FreeRTOS-Demo文件夹,选择我们的目标文件夹,例如CORTEX_STM32F103_Keil,其余的就可以删掉了,在Demo中的文件夹的命名规则是指令集+芯片+编译器或者芯片+编译器。
在FreeRTOS-Source文件夹中,里面的目录结构如下所示,在portable文件夹中,我们保留RVDS和