当前位置:首页 > 公众号精选 > 技术让梦想更伟大
[导读]关注、星标公众号 ,直达精彩内容 FreeRTOS下载包的文件结构 在FreeRTOS官方网站可以下载到最新版的FreeRTOS包,我这里使用的是V8.2.3版本。 下载包内的总文件数量多的令人生畏,但文件结构却很简洁。《FreeRTOS入门指南》一文的第3节详细描述了下载包文件结


关注、星标公众号 ,直达精彩内容

FreeRTOS下载包的文件结构

在FreeRTOS官方网站可以下载到最新版的FreeRTOS包,我这里使用的是V8.2.3版本。

下载包内的总文件数量多的令人生畏,但文件结构却很简洁。《FreeRTOS入门指南》一文的第3节详细描述了下载包文件结构,我们这里只是简单提一下。

下载包根目录下包含两个子目录:FreeRTOS和FreeRTOS-Plus。其中,FreeRTOS-Plus文件夹中包含一些FreeRTOS+组件和演示例程(组件大都收费),我们不对这个文件夹下的内容多做了解,重点说一下FreeRTOS文件夹。

FreeRTOS文件夹下包含两个子目录:Demo和Source。其中,Demo包含演示例程的工程文件,Source包含实时操作系统源代码文件。

FreeRTOS实时操作系统内核仅包含三个必要文件,此外还有三个可选文件。RTOS核心代码位于三个源文件中,分别是tasks.c、queue.c和list.c。这三个文件位于FreeRTOS/Source目录下,在同一目录下还有3个可选的文件,叫做timers.c、event_groups.c和croutine.c,分别用于软件定时器、事件组和协程。

对于支持的处理器架构,RTOS需要一些与处理器架构相关的代码。可以称之为RTOS硬件接口层,它们位于FreeRTOS/Source/Portable/[相应编译器]/[相应处理器架构] 文件夹下。我们这次要移植到Cortex-M3微控制,使用Keil MDK编译器,所以需要的RTOS硬件接口代码位于:FreeRTOS\Source\portable\RVDS\ARM_CM3文件夹下。

堆栈分配也是属于硬件接口层(移植层),在FreeRTOS/Source/portable/MemMang文件夹下具有各种类型的堆栈分配方案。这里我们使用heap_1.c提供的堆栈分配方案。关于FreeRTOS的内存管理,后续《FreeRTOS内存管理》一文中会详细介绍FreeRTOS内存管理的特性和用法,《FreeRTOS内存管理分析》一文会从源码级别分析FreeRTOS内存管理的具体实现,这里不用多纠结,你也可以快速的浏览一下这两篇文章,里面或许有许多不懂的,但不要着急,先放过它们。

FreeRTOS文件夹下的Demo文件夹中还包括各种演示例程,涉及多种架构的处理器以及多种编译器。FreeRTOS/Demo/Common/Minimal文件夹下的演示例程代码中,绝大部分对所有移植硬件接口都是适用的。FreeRTOS/Demo/Common/Full文件夹下的代码属于历史遗留代码,仅用于PC移植层。

移植前的一些准备

一块具有Cortex-M3微处理器的硬件板子,并且保证板子可以正常运转。下载FreeRTOS程序包(《FreeRTOS历史版本更新记录》一文中有下载地址,这是我在CSDN下载频道做的镜像文件。如果你能忍受下载网速慢,也可以去官方网站下载。) 下载CMSIS-M3,其实主要是需要里面的core_cm3.h文件(可以去ARM官方下载,如果你安装了keil 5或比较新的Keil 4 MDK编译器,在目录:Keil\ARM\CMSIS文件夹下也可以找到)

移植过程

添加RTOS核心代码

将tasks.c、queue.c和list.c这三个内核代码加入工程,将port.c和heap_1.c这两个与处理器相关代码加入工程。port.c位于FreeRTOS\Source\portable\RVDS\ARM_CM3文件夹下,heap_1.c位于FreeRTOS/Source/portable/MemMang文件夹下。

添加头文件路径

  1. ...\FreeRTOS\Source\portable\RVDS\ARM_CM3
  2. ...\FreeRTOS\Source\include

编写FreeRTOSConfig.h文件

对于刚接触FreeRTOS的用户来说,最简单方法是找一个类似的Demo工程,复制该工程下的FreeRTOSConfig.h文件,在这个基础上进行修改。详细的配置说明将在后续《FreeRTOS内核配置说明》一文中给出,这里依然不必纠结。

编写一些钩子函数

如果你在FreeRTOSConfig.h中设置了「configUSE_TICK_HOOK=1」,则必须编写voidvApplicationTickHook( void )函数。该函数利用时间片中断,可以很方便的实现一个定时器功能。详见后续文章《FreeRTOS内核配置说明》有关宏configUSE_TICK_HOOK一节。

如果你在FreeRTOSConfig.h中设置了「configCHECK_FOR_STACK_OVERFLOW=1或=2」,则必须编写voidvApplicationStackOverflowHook( xTaskHandle pxTask, signed char *pcTaskName )函数,该函数用于检测堆栈溢出,详见后续文章《FreeRTOS内核配置说明》有关宏configCHECK_FOR_STACK_OVERFLOW一节。

检查硬件

为了验证你的硬件板子是否可靠的工作,首先编写一个小程序片,比如闪烁一个LED灯或者发送一个字符等等,我们这里使用UART发送一个字符。代码如下所示(假设你已经配置好了启动代码,并正确配置了UART):

 #include"task.h"
#include"queue.h"
#include"list.h"
#include"portable.h"
#include"debug.h"

int main(void)
{
init_rtos_debug(); //初始化调试串口
MAP_UARTCharPut('A'); //发送一个字符
while(1);
}

如果硬件可以正常发送字符,说明硬件以及启动代码OK,可以进行下一步。

挂接中断

在Cortex-M3硬件下,FreeRTOS使用SysTick作为系统节拍时钟,使用SVC和PendSVC进行上下文切换。异常中断服务代码位于port.c文件中,FreeRTOS的作者已经为各种架构的CPU写好了这些代码,可以直接拿来用,需要用户做的,仅仅是将这些异常中断入口地址挂接到启动代码中。

在startup.s中,使用IMPORT关键字声明要挂接的异常中断服务函数名,然后将:

 DCD     SVC_Handler            换成:DCD     vPortSVCHandler
DCD PendSV_Handler 换成:DCD xPortPendSVHandler
DCD SysTick_Handler 换成:DCD xPortSysTickHandler

建立第一个任务Task

在步骤3.5中,我们为了测试硬件是是否能够工作,编写了一个发送字符的小函数,这里我们将把这个小函数作为我们第一个任务要执行的主要代码:每隔1秒钟,发送一个字符。代码如下所示:

voidvTask(void *pvParameters)
{
while(1)
{
MAP_UARTCharPut(0x31);
vTaskDelay(1000/portTICK_RATE_MS);
}
}

FreeRTOS的任务以及编写格式将在后续文章《FreeRTOS任务概述》一文中详述,这里只是一个很简单的任务,先有有大体印象。这里面有一个API函数vTaskDelay(),这个函数用于延时,具体用法将在后续文章《FreeRTOS任务控制》一文中详细介绍,延时函数代码级分析将在《FreeRTOS高级篇10---系统节拍时钟分析》。这里不必在意太多的未知情况,因为后面会一点点将这些未知空间探索一遍的。

设置节拍时钟

这里我们使用SysTick定时器作为系统的节拍时钟,设定每隔10ms产生一次节拍中断。由于FreeRTOS对移植做了非常多的工作,以至于我们只需要在FreeRTOSConfig.h中配置好以下两个宏定义即可:

  1. configCPU_CLOCK_HZ     (/ 你的硬件平台CPU系统时钟,Fcclk/)
  2. configTICK_RATE_HZ       ((portTickType)100)          第一个宏定义CPU系统时钟,也就是CPU执行时的频率。第二个宏定义FreeRTOS的时间片频率,这里定义为100,表明RTOS一秒钟可以切换100次任务,也就是每个时间片为10ms。

在prot.c中,函数vPortSetupTimerInterrupt()设置节拍时钟。该函数根据上面的两个宏定义的参数,计算SysTick定时器的重装载数值寄存器,然后设置SysTick定时器的控制及状态寄存器,设置如下:使用内核时钟源、使能中断、使能SysTick定时器。另外,函数vPortSetupTimerInterrupt()由函数vTaskStartScheduler()调用,这个函数用于启动调度器。

设置中断优先级相关宏

这里特别重要,因为涉及到中断优先级和中断嵌套。这里先给出基于Cortex-M3硬件(lpc177x_8x系列微控制器)的一个配置例子,在FreeRTOSConfig.h中:

#ifdef __NVIC_PRIO_BITS
#defineconfigPRIO_BITS __NVIC_PRIO_BITS
#else
#defineconfigPRIO_BITS 5 /*lpc177x_8x微处理器使用优先级寄存器的5位*/
#endif

/*设置内核使用的中断优先级*/
#define configKERNEL_INTERRUPT_PRIORITY ( 31 << (8 - configPRIO_BITS) )

/*定义RTOS可以屏蔽的最大中断优先级,大于这个优先级的中断,不受RTOS控制*/
#defineconfigMAX_SYSCALL_INTERRUPT_PRIORITY ( 5<< (8 - configPRIO_BITS) )

后续文章《FreeRTOS内核配置说明》会详细介绍这些宏的含义,对于Cortex-M内核,后续文章《Cortex-M内核使用FreeRTOS特别注意事项》一文,会讲述这些宏与硬件的联系,那个时候你一定会清楚这些宏所定义的数字会对你的硬件产生什么影响的。现在,我们只需要知道他们很重要就足够了,没人能一口吃成胖子。

设置其它宏

还需要在FreeRTOSConfig.h设置一些必要的宏,这些宏如下所示:

#define configUSE_PREEMPTION 1            //配置为1使用抢占式内核,配置为0使用时间片
#define configUSE_IDLE_HOOK 0 //设置为1使用空闲钩子;设置为0不使用空闲钩子
#define configMAX_PRIORITIES ( 5 ) //应用程序任务中可用优先级数目
#define configUSE_TICK_HOOK 0 //就设置为1使用时间片钩子,设置为0不使用
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 80 ) //最小空闲堆栈
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 5 * 1024 ) ) //内核总共可用RAM

创建任务

调用FreeRTOS提供的API函数来创建任务,代码如下所示:

xTaskCreate(vTask,"Task1",50,NULL,1,NULL);

关于详细的创建任务API函数,会在后续文章《FreeRTOS任务创建和删除》一文中介绍。

开启调度器

调用FreeRTOS提供的API函数来启动调度器,代码如下所示:

vTaskStartScheduler();

关于详细的开启调度器API函数,会在后续文章《FreeRTOS内核控制》一文中介绍。此时的main函数代码如下所示:

int main(void)
{
init_rtos_debug(); //初始化调试串口

xTaskCreate(vTask,"Task1",50,NULL,1,NULL);
vTaskStartScheduler();
while(1);
}

小结

到这里,一个最基本的FreeRTOS应用程序就已经运行起来,将硬件板子接到PC的RS232串口,可以观察到每隔一秒钟,板子都会向PC发送一个指定的字符。

回头看一下移植过程,FreeRTOS移植到Cortex-M3硬件是多么的简单,这一方面归功于FreeRTOS的设计师已经为移植做了大量工作,同时,新一代的Cortex-M3硬件也为操作系统增加了一些列便利特性,比如SysTick定时器和全新的中断及异常。

但是移植成功也只是万里长征的第一步,因为这只是最简单的应用。我们还不清楚FreeRTOS背后的机理、调度算法的面貌、甚至连信号量也都没有涉及。就本文的移植过程来看,我们也刻意忽略了很多细节,比如FreeRTOSConfig.h文件中的宏都有什么意义?改动后对RTOS有何影响?比如FreeRTOS任务API的细节、调度API的细节,再比如FreeRTOS的内存如何分配?如何进行堆栈溢出检查等等。

所以,先不要沾沾自喜,曲折的道路还远没到来呢。

接下来的很多篇文章会围绕这个最简单的移植例程做详细的讲解,要把本篇文章中刻意隐藏的细节一一拿出来。这要一直持续到我们介绍队列、信号量、互斥量等通讯机制为止。


   

推荐阅读

(点击标题可跳转阅读)

【编程之美】用C语言实现状态机(实用)

【编程之美】超时重传,滑动窗口,可靠性传输原理C语言实现

【编程之美】论嵌入式架构的重要性

免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭