一、新建KEIL5工程
1、新建一个空目录,命名为stm32f103。 在stm32f103/新建目录: APP、LIB、USER、STARTUP
2、在stm32f103/下建立一个空的keil5工程命名为FreeRTOS。选择芯片STM32F103C8。
3、搭建工程框架,打开官方固件库包:
1)将STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\STM32F10x_StdPeriph_Driver目录下的src、inc拷贝到stm32f103/LIB目录下
2)将STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x下的 stm32f10x.h、system_stm32f10x.c、system_stm32f10x.h拷贝到stm32f103/STARTUP目录下。
3)将STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\arm下的startup_stm32f10x_hd.s文件拷贝到stm32f103/STARTUP目录下。
4)将STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\CoreSupport目录下的core_cm3.c、core_cm3.h拷贝到stm32f103/STARTUP目录下。
5)(将STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Template目录下的stm32f10x_conf.h、stm32f10x_it.c、stm32f10x_it.h拷贝到 stm32f103/USER目录下。system_stm32f10x.c不要再拷贝了,因为上面已经拷贝过了。
4、写自己的应用代码。
在APP目录下新建自己的main.c文件。
5、
点击
弹出如下界面,新建如下代码分组,并将对应的文件添加到对于分组目录下
6、配置编译头文件路径
点击
弹出如下界面,添加头文件路径
二、移植FreeRTOS 9.0.0
1、在stm32f103目录下建立 FreeRTOS目录
2、将源码 FreeRTOSv9.0.0\FreeRTOS\Source下的所有文件拷贝到stm32f103/FreeRTOS目录下
3、portable 文件夹下的只需要留下keil、MemMang 和RVDS这三个文件夹,其它的都删除。
4、将源码 FreeRTOSv9.0.0\FreeRTOS\Demo\CORTEX_STM32F103_Keil目录下的FreeRTOSConfig.h文件拷贝到stm32f103\FreeRTOS\include目录下。此文件是内核裁剪、配置文件。
5、将FreeRTOS代码加入到代码分组并设置头文件目录
相关文件地址如下
stm32f103\FreeRTOS\portable\MemMang\heap_4.c
stm32f103\FreeRTOS\portable\RVDS\ARM_CM3\port.c
t
头文件目录增加
6、在delay.c中增加代码,否则在调用
extern void xPortSysTickHandler(void);
void SysTick_Handler(void)
{
if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)
{
xPortSysTickHandler();
}
}
7、在FreeRTOSConfig.h末尾增加如下三行,使用FreeRTOS提供的函数。
#define INCLUDE_xTaskGetSchedulerState 1
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
8、在stm32f10x_it.c中删除三个函数。
void SVC_Handler(void)
void PendSV_Handler(void)
void SysTick_Handler(void)
我之前测试时发现在这文件中实现SysTick_Handler()函数,在调用vTaskDelay()函数后程序卡住,xTaskGetTickCount()获取的系统节拍不会增加。在delay.c中实现就可以了,不知道为什。
9、在main函数中实现多任务创建和开始任务调度
#include "bsp.h"
#include "FreeRTOS.h"
#include "task.h"
void task1_entryPoint(void)
{
while(1){
vTaskDelay(1000/portTICK_RATE_MS);
}
}
void task2_entryPoint(void)
{
while(1) {
vTaskDelay(100/portTICK_RATE_MS);
}
}
int main()
{
/* 创建任务句柄 */
TaskHandle_t ledTurnOnTask_Handle = NULL;
bsp_init();
/* 创建任务 */
xTaskCreate((TaskFunction_t )task1_entryPoint, /* 任务入口函数 */
(const char* )"task1_entryPoint",/* 任务名字 */
(uint16_t )512, /* 任务栈大小 */
(void* )NULL,/* 任务入口函数参数 */
(UBaseType_t )1, /* 任务的优先级 */
(TaskHandle_t* )&ledTurnOnTask_Handle);/* 任务控制块指针 */
xTaskCreate((TaskFunction_t )task2_entryPoint, /* 任务入口函数 */
(const char* )"task2_entryPoint",/* 任务名字 */
(uint16_t )512, /* 任务栈大小 */
(void* )NULL,/* 任务入口函数参数 */
(UBaseType_t )1, /* 任务的优先级 */
(TaskHandle_t* )&ledTurnOnTask_Handle);/* 任务控制块指针 */
/* 启动任务调度 */
vTaskStartScheduler();
}