3-FreeRTOS介绍和移植使用(FreeRTOS移植)

FreeRTOS移植

Keil MDK创建项目

首先在PC上创建FreeRTOS项目文件夹目录树如下,其中:

  • Board文件夹用来存放开发板硬件操作的相关C文件,如led、串口等;
  • CMSIS文件夹存放CortexM系列微控制器软件接口标准相关C文件;
  • FreeRTOS文件夹存放FreeRTOS操作系统相关的C文件;
  • Output文件夹存放编译输出的文件;
  • Stdlib文件夹存放STM32的标准库C文件;

《3-FreeRTOS介绍和移植使用(FreeRTOS移植)》

接下来将STM32L的标准库和FreeRTOS里的相关源码C文件添加相应的项目路径下:

把STM32L151的标准库STM32L1xx_StdPeriph_Lib_V1.3.1\Libraries\STM32L1xx_StdPeriph_Driver里的incsrc两个文件夹拷贝到Stdlib文件夹下;

将STM32L151的标注库STM32L1xx_StdPeriph_Lib_V1.3.1\Libraries\CMSIS\Device\ST\STM32L1xx\Source\Templates\arm\startup_stm32l1xx_md.s文件拷贝到CMSIS文件夹下;

将STM32L151的标准库STM32L1xx_StdPeriph_Lib_V1.3.1\Libraries\CMSIS\Device\ST\STM32L1xx\Include里的stm32l1xx.hsystem_stm32l1xx.h等文件拷贝到CMSIS文件夹下;

将STM32L151的标准库STM32L1xx_StdPeriph_Lib_V1.3.1\Libraries\CMSIS\Device\ST\STM32L1xx\Source\Templates\system_stm32l1xx.c文件拷贝到CMSIS文件夹下;

将STM32L151的标准库STM32L1xx_StdPeriph_Lib_V1.3.1\Project\STM32L1xx_StdPeriph_Templates\stm32l1xx_conf.h文件拷贝到CMSIS文件夹下;

将Keil安装路径下的D:\Program Files\Keil\ARM\PACK\ARM\CMSIS\5.4.0\CMSIS\Core\Include里的cmsis_armcc.hcmsis_compiler.hcmsis_version.hcore_cm3.hmpu_armv7.h等文件拷贝到CMSIS文件夹下:

 

FreeRTOSv10.1.1\FreeRTOS\Source\include文件夹拷贝FreeRTOS文件夹下;

FreeRTOSv10.1.1\FreeRTOS\Source中的list.c、queue.ctasks.c拷贝到FreeRTOS文件夹下;

FreeRTOSv10.1.1\FreeRTOS\Source\portable\RVDS\ARM_CM3\port.c拷贝到FreeRTOS文件夹下;

FreeRTOSv10.1.1\FreeRTOS\Source\portable\MemMang\heap_4.c拷贝到FreeRTOS文件夹下;

FreeRTOSv10.1.1\FreeRTOS\Demo\CORTEX_STM32L152_IAR\FreeRTOSConfig.h拷贝到FreeRTOS文件夹

 

使用Keil MDK创建STM32L151的FreeRTOS的项目,创建CMSIS、Stdlib、Board、FreeRTOS、Main五个Group并将之前的源码添加到MDK项目的相应组里。

《3-FreeRTOS介绍和移植使用(FreeRTOS移植)》

《3-FreeRTOS介绍和移植使用(FreeRTOS移植)》

 

修改启动代码:

SVC(系统服务调用)和 PendSV(可悬起系统调用)多用于在操作系统的软件开发中。 SVC 用于产生系统函数的调用请求,例如,操作系统不让用户程序直接访问硬件,而是通过提供一些系统服务函数,用户程序使用 SVC 发出对系统服务函数的呼叫请求,以这种方法调用它们来间接访问硬件。因此,当用户程序想要控制特定的硬件时,它就会产生一个 SVC 异常,然后操作系统提供的 SVC 异常服务例程得到执行,它再调用相关的操作系统函数,后者完成用户程序请求的服务。

另一个相关的异常是 PendSV,他的一个典型使用场合是和SVC协同合作完成不同任务之间切换(上下文切换)。一方面, SVC异常是必须立即得到响应的(若因优先级不比当前正处理的高, 或是其它原因使之无法立即响应, 将上访成硬 fault),应用程序执行 SVC 时都是希望所需的请求立即得到响应。另一方面, PendSV 则不同,它是可以像普通的中断一样被悬起的(不像 SVC 那样会上访)。 OS 可以利用它“缓期执行” 一个异常——直到其它重要的任务完成后才执行动作。

操作系统进行运转的时候,都会需要一个定义时间的系统“滴答”。它会根据“滴答”的节拍来工作,把整个时间段分成很多小小的时间片,每个任务每次只能运行一个“时间片”的时间长度就得退出给别的任务运行,这样可以确保任何一个任务都不会霸占整个系统。此外操作系统所提供的各种定时功能,都与这个系统滴答有关。因此,需要一个定时器用来周期性地产生中断提供定时,而且最好还让用户程序不能随意访问它的寄存器,以维持操作系统“心跳”的节律。 ARM CortexM3的内核在设计的时候,专门设计了一个系统定时器外设Systick,内嵌在NVIC中。它是一个24位的向下递减的计数器,计数器每记数一次的时间为1/SYSCLK,当重装载寄存器的值递减到0时系统就会产生Systick中断,以此循环反复进行,这样就可以为操作系统提供系统滴答服务。因为他是CortexM3内核里的一个外设,所以所有基于CortexM3内核的MCU都具有该功能。

因为SVC、PendSV和Systick这三个中断功能对于操作系统的设计非常需要,所以FreeRTOS在port.c文件中分别重新定义了这三个中断服务处理程序,这时我们在启动代码startup_stm32l1xx_md.s中用他们替换STM32标准库里提供的相应函数,即将 SVC_Handler修改改成vPortSVCHandler, 将PendSV_Handler改成xPortPendSVHandler ,将SysTick_Handler改成xPortSysTickHandler:。

修改CMSIS下的startup_stm32l1xx_md.s文件

FreeRTOS内核配置

FreeRTOS内核是高度可定制的,使用配置文件FreeRTOSConfig.h进行定制。每个FreeRTOS应用都必须包含这个头文件,用户根据实际应用来裁剪定制FreeRTOS内核。这个配置文件是针对用户程序的,而非内核,因此配置文件一般放在应用程序目录下,不要放在RTOS内核源码目录下。在下载的FreeRTOS文件包中,每个演示例程都有一个FreeRTOSConfig.h文件。有些例程的配置文件是比较旧的版本,可能不会包含所有有效选项。如果没有在配置文件中指定某个选项,那么RTOS内核会使用默认值。之前我们已经将STM32L152_IAR Demon项目中的配置文件拷贝到了项目中,下面是这个典型的FreeRTOSConfig.h配置文件注释说明:

FreeRTOS运行需要的一些钩子函数

如果你在FreeRTOSConfig.h中定义了宏configUSE_MALLOC_FAILED_HOOK,则需要提供malloc失败的钩子函数vApplicationMallocFailedHook();如果定义了宏configUSE_IDLE_HOOK则需要提供钩子函数vApplicationIdleHook(),如果定义了宏configCHECK_FOR_STACK_OVERFLOW则需要提供钩子函数vApplicationStackOverflowHook();如果设置了configUSE_TICK_HOOK=1,则必须编写voidvApplicationTickHook( void )函数,该函数可以利用时间片中断,可以很方便的实现一个定时器功能。

这时我们在Board路径下创建提供这些钩子函数的C文件stm32_vport.c和相应头文件stm32_vport.h提供这些钩子函数,同时在该C文件中也定义prvSetupHardware()函数用来初始化相关硬件:

初始化和操作LED的源码

在Board路径下创建并添加LED初始化和操作的C文件stm32_led.c 和 头文件 stm32_led.h

初始化调试串口和实现printf的源码

在Board路径下创建并添加串口初始化和printf实现的C文件stm32_usart.c 和 头文件stm32_usart.h

FreeRTOS入口main程序:

在准备好上面的源码文件之后,我们接下来编写整个项目的入口main函数并添加到Keil MDK项目中去,在这里我们首先初始化相应的硬件(主要是LED和调试串口),之后调用xTaskCreate()创建了两个任务vLEDFlashTask和vSerialPutsTask,其中vLEDFlashTask让LED每隔250ms亮灭一次,而vSerialPutsTask则每隔10s在串口上输出一次。具体源码如下:

编译运行

项目创建并添加好源码之后,接下来我们需要对项目进行一些配置就可以编译、运行了:

《3-FreeRTOS介绍和移植使用(FreeRTOS移植)》

因为使用了printf,所以我们要在项目配置中要使能 “Use MicroLIB”:

《3-FreeRTOS介绍和移植使用(FreeRTOS移植)》

选着编译输出的文件到Output文件夹中:

《3-FreeRTOS介绍和移植使用(FreeRTOS移植)》

添加两个必须的宏定义STM32L1XX_MD,USE_STDPERIPH_DRIVER和所有的头文件所在的路径

《3-FreeRTOS介绍和移植使用(FreeRTOS移植)》

因为现在已经开始运行FreeRTOS操作系统,系统上电后被操作系统接管。这时如果使用ST-Link来烧录的时候会出现“Internal command error”错误,这时我们在Debug里设置Connect时“With Pre-reset”就可以解决ST-Link不能烧录的问题了。

《3-FreeRTOS介绍和移植使用(FreeRTOS移植)》

接下来编译整个项目并调试运行,会发现串口上每隔10s收到开发板的打印消息,以及LED每隔250ms各亮灭一次,验证了FreeRTOS的两个任务调度运行成功。

《3-FreeRTOS介绍和移植使用(FreeRTOS移植)》

《3-FreeRTOS介绍和移植使用(FreeRTOS移植)》

 

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注