初识 FreeRTOS + lwip

本文是对一些对Linux等系统有认识,但却没有接触过FreeRTOS系统的人提供一些帮助,能够了解FreeRTOS大致的一些工作原理和如何在FreeRTOS系统上开发还有网络协议栈实现等。作者对于FreeRTOS开发时间还不长,发现文中有哪些谬误,烦劳指出不胜感谢。本文大致分为以下几部分:

  • Preface 主要描述RTOS与通用系统之间的区别和FreeRTOS系统的特性
  • Task Management 主要描述Task如何创建、哪些状态切换等
  • Task Communication & Synchronization 主要描述Task间通信及同步方式
  • FreeRTOS Network 主要描述FreeRTOS的网络实现方式
  • FreeRTOS Debug & Performance Analysis 主要描述 FreeRTOS的一些debug手段以及性能分析方式

1 Preface

What is RTOS?

那么什么是实时操作系统,实时操作系统又与我们平时使用的Linux、Windows操作系统有哪些不同呢?

先简单介绍下大多数操作系统都允许多个程序同时执行,称为多任务处理。但实际上每个处理器在同一时刻只能处理单个执行线程,而操作系统的调度程序来选择在何时运行哪个程序,并通过在每个程序之前快速切换从而提供同时执行的假象

RTOS(Real-time operating system)实时操作系统和非实时操作系统根本区别就在于调度机制的不同。实时操作系统要旨在于确定性的执行模式。因为认为只有在可预测操作系统行为(确定)时,才能够满足实时的需求。大部分的RTOS操作系统是通过用户设定每个执行线程的优先级来实现确定性。在调度时,一定会优先执行高优先级的程序。而非实时操作系统是保证每个执行线程都不会饿死,尽量保证高优先级的程序较多运行。

那么,使用了实时操作系统,系统响应速度一定快,实时性一定得到保障了么?

不一定。在实时性要求较高的系统里,仍需注意以下两点:

  • 因为实时操作系统本身引入了执行开销,所以对于小型应用来说,有RTOS的性能也许不如无操作系统的情况。实时操作系统的优势最能体现在中大型系统中,当任务间存在复杂的耦合和依赖关系,并且应用程序经常要长时间等待外部资源时。
  • 在决定使用RTOS情况下,如果需提供实时性保证,仍需要使用实时系统理论对任务可调度性和相应时间进行分析,才可得到科学、系统的相应性保证。

常见的RTOSFreeRTOSuCosII / uCosIIINucleus RTOS

常见应用场景是针对实时性要求较高使用,像汽车引擎控制、轨道交通、工业机器人、飞行器控制系统等

What is FreeRTOS?

FreeRTOS是一种RTOS系统,已经在35种微处理器下应用。目前在MIT License下发布,是一款开源、完全免费、商业级的操作系统。FreeRTOS参考的官方网站:https://www.freertos.org/

初识 FreeRTOS + lwip_第1张图片

上图为全球电子产业媒体集团AspenCore发布的2017年嵌入式市场调研报告。FreeRTOS20%的比重,位居第,其中28%的调查者表示接下来更愿意尝试FreeRTOS系统。

FreeRTOS 有哪些特性?

FreeRTOS为多任务、互斥体、信号量和软件定时器提供了方法。没有如LinuxWindows一样的文件系统、规范化设备驱动、用户和网络支持。其重点放在小巧和执行速度上。FreeRTOS在使用上更像是在调用C库,不像一般意义的操作系统。主要有以下特性:

1、 占用内存小、开销低、执行速度快。

2、为低功率应用的无Tick选项,即没有时间片分配,如无高优先级任务抢占,将一直运行下去。

3、有效的软件定时器实现。FreeRTOS有定时器的Task,用于实现定时器功能,和硬件无直接关系。

4、快速Notifications机制。后文会详细介绍,一种Task间通信方式。

5、优先级继承的互斥锁。后文会详细介绍,Task同步方式的优点。

6、易于使用的API。

那么,与Linux系统相比较,有哪些细节上的不同呢?

 

Linux

FreeRTOS

执行线程定义

线程/进程

Task

内存管理

用户态和内核态 

分配内存复杂

无区分用户态和内核态

分配内存简单

文件系统

多用户文件系统

同步/线程安全

自旋锁/RCU..

互斥锁/条件变量

互斥锁/挂起调度器

进程通信方式

FIFO/信号量/消息队列

Queue/Notifications

 

2 Task Management

那么,从上一章中介绍到FreeRTOS并没有文件系统,Linux应用开发都知道,将应用的code编译成一个bin档,运行时,启动该bin档即可,那么在FreeRTOS中如何进行开发呢?

FreeRTOS 入口是main函数,如下图所示,依次进行硬件初始化,Task初始化,TaskStartScheduler。

初识 FreeRTOS + lwip_第2张图片

FreeRTOS通过添加Task来实现功能,Task即Linux上进程的概念。一般情况下,在FreeRTOS初始化阶段,对需要运行的Task进行初始化,包括Task运行的函数、分配的栈大小、优先级和传入参数等,接着在运行vTaskStartScheduler函数,会对已注册的Task进行调度运行。如果Task都能创建成功,则不会运行至最后的死循环中去。

可以看出,如果想新添加一个功能或者修改一点东西,在FreeRTOS中必须将整个操作系统及其他所有的Task重新编译。(只是需要重新编译,因编译优化,有些没有修改到的地方,就不会重新编译)。

那么,Task中的有什么必须遵守的规范么?

Task做为FreeRTOS的调度单元,是独立的运行实例,具有和其他Task不重复的堆栈空间。Task通常是无限循环执行,不允许以任何方式退出实现函数(return语句或者运行结束)。如果Task真的不需要了,需要显式的调用delete函数结束Task运行。

下图为Task1的具体实现,可以看到是在打印传入参数,然后利用循环等待一段时间,再循环运行。

初识 FreeRTOS + lwip_第3张图片

Task2的实现与Task1实现相同,下图展示了运行结果

初识 FreeRTOS + lwip_第4张图片

图中可以看出Task1和Task2交替打印,且打印次数基本相同。

FreeRTOS中在调度了Task后,会给该Task分配固定时间片,在时间片结束后触发Tick中断,进入Tick中断后,会根据优先级选择下一个时间片运行哪个Task。在FreeRTOS的配置文件中,可以设定时间片的长短以及选择无Tick模式(Tick中断频率一般是100Hz~1000Hz)。

由于Task1与Task2具有相同的优先级,所以调度程序会依次选择两个Task(FreeRTOS对于优先级相同的Task的选择原则是选择过往运行总时间较短的那个Task)。运行时序图如下图所示:

初识 FreeRTOS + lwip_第5张图片

如将Task2的优先级调整为2,即比Task1的优先级高,那么运行效果是如何呢?

初识 FreeRTOS + lwip_第6张图片

效果图如上图所示,Task2一直在运行,这里就体现了如第一章所描述实时操作系统的特点。当高优先级任务与低优先级任务同为就绪态时,调度程序运行一定会选择高优先级Task运行。运行时序图如下:

初识 FreeRTOS + lwip_第7张图片

上文中提及的Task状态有就绪态和运行态,从上图中分析,一开始Task1和Task2同时为就绪态,一开始调度程序运行,从就绪态的Task中看到Task2的优先级最高,故运行Task2,Task2从就绪态转为运行态并开始运行,当时间片结束,Task2从运行态转为就绪态,调度程序同样从就绪态的Task中挑选优先级最高的Task2,以此循环运行。

那么,低优先级的程序就永远运行不了么,这里引入阻塞态的概念。

会将Task2和Task1中的利用空循环实现等待的方式,改为调用vTaskDelay函数。调用该函数会将Task转为阻塞态,直到达到等待时间,会将Task转回就绪态。实现效果如下:

初识 FreeRTOS + lwip_第8张图片

从上图中可以看出,Task1和Task2交替运行。时序图如下图所示。

初识 FreeRTOS + lwip_第9张图片

对时序图进行分析,一开始Task1和Task2 同为就绪态,调度程序选择优先级较高的Task2进入运行态并运行,Task2中打印之后调用vTaskDelay函数,进入阻塞态。进入调度程序,只能选择唯一在就绪态的Task1运行,同样的也进入了阻塞态。当调度程序发现没有就绪态的Task时,会选择Idel Task,该task会处于低功耗的状态,由Schduler创建。直到Delay时间结束,将Task2和Task1从阻塞态转入就绪态,调度程序继续调度运行。

3 Task Communication & Synchronization

上一章中有提到,Task在初始化时规定了栈的大小,所以分配时每个Task有着互不重叠的空间。如下图所示

初识 FreeRTOS + lwip_第10张图片

那么Task之间如何通信呢,FreeRTOS有提供Queue机制用于Task间通信,Queue具有自己的空间,如下图所示

Queue的用法也非常简单,与Linux FIFO的用法比较类似,初始化Queue的num和size后,便先入先出的访问,原理如下图所示:

初识 FreeRTOS + lwip_第11张图片

因用法较简单,这里不赘述,详细用法查询官方文档。

介绍完Task间通信,再

你可能感兴趣的:(freeRTOS)