最近想在Keil开发环境下将FreeRTOS移植到STM32F4系列单片机上,无奈官方DEMO中STM32F4系列只有IAR的示例,遂决定自己动手移植,并将这个学习过程记录下来。
相关文件添加
FreeRTOS官网下载最新的源代码。
不妨在工程所在文件夹下新建FreeRTOS文件夹,将\FreeRTOSV8.2.0\FreeRTOS\Source路径下的include文件夹复制到新建的FreeRTOS文件夹下,将\FreeRTOSV8.2.0\FreeRTOS\Demo\CORTEX_STM32F103_Keil路径下的FreeRTOSConfig.h复制到include文件夹下,将\FreeRTOSV8.2.0\FreeRTOS\Source\portable\RVDS\ARM_CM4F路径下的portmacro.h也复制到include文件夹下。
参考《FreeRTOS实时内核使用指南》中的Table 21,将\FreeRTOSV8.2.0\FreeRTOS\Source路径下的list.c、queue.c、tasks.c,\FreeRTOSV8.2.0\FreeRTOS\Source\portable\RVDS\ARM_CM4F路径下的port.c,\FreeRTOSV8.2.0\FreeRTOS\Source\portable\MemMang路径下的heap_2.c复制到新建的FreeRTOS文件夹下。将上述5个源文件添加至工程中,如下图所示:
相关文件修改
- 在FreeRTOSConfig.h中插入如下代码:
#include <stdint.h>
extern uint32_t SystemCoreClock;
以及将对应的代码修改如下:
#define configCPU_CLOCK_HZ ( SystemCoreClock )
- 在startup_stm32f40_41xxx.s中插入如下代码:
IMPORT xPortPendSVHandler
IMPORT xPortSysTickHandler
IMPORT vPortSVCHandler
以及将相应的代码修改如下:
DCD vPortSVCHandler ; SVCall Handler
DCD DebugMon_Handler ; Debug Monitor Handler
DCD 0 ; Reserved
DCD xPortPendSVHandler ; PendSV Handler
DCD xPortSysTickHandler ; SysTick Handler
- 最后根据所选用的晶振,修改stm32f4xx.h和system_stm32f4xx.c文件中相关的宏定义。
相关代码
通过调用vTaskDelayUntil()函数使任务间隔100ms执行,从而实现IO口电平的周期翻转。
void vGPIOTask(void *pvParameters)
{
portTickType xLastWakeTime;
xLastWakeTime = xTaskGetTickCount();
while(1)
{
if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_0))
{
GPIO_ResetBits(GPIOA, GPIO_Pin_0);
}
else
{
GPIO_SetBits(GPIOA, GPIO_Pin_0);
}
vTaskDelayUntil(&xLastWakeTime, 100 / portTICK_RATE_MS);
}
}
在示波器上观察PA0的输出波形,电平间隔100ms翻转一次符合预期,波形如下图所示: