从零开始的STM32F103项目创建+FreeRTOS的最简系统移植

一、所需环境

本文使用STM32F103C8T6这款中端使用比较多的Cortex-M3内核MCU
编译环境是使用Keil uVision4
STM32外设库是ST 官网V3.5版本 ST官网链接
移植使用的是V10.3.1版本的FreeRTOS 官网链接

二、最小工程创建

先用Keil创建一个工程,选择STM32F103C8
在这里插入图片描述选择否,后面我们自己添加官方外设库的文件

在这里插入图片描述
工程建好了之后,就可以将ST官方外设库相关文件加入工程目录里了
先新建个CMSIS的目录来放置与内核硬件相关的文件
CMSIS目录
这边需要对stm32f10x.h修改一下 不使用conf文件
在这里插入图片描述在这里插入图片描述注释掉两部分 然后定义空的assert_param函数 这样就不需要再导入stm32f10x_conf.h文件了 当然 如果喜欢使用的就不要改动了
再新建一个存放外设库文件的目录 这里命名为STM32F10x_Libs,将官网外设库STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\STM32F10x_StdPeriph_Driver里的src和inc目录复制过来
之后再创建一个User目录存放main.c 一个Basic目录放置串口等基本工具文件
然后在Keil里导入对应的文件
在这里插入图片描述
然后设置库路径和宏定义 STM32F10X_HD
在这里插入图片描述
在这里插入图片描述再记得把Use MicroLIB勾上 不然在使用串口printf函数时会卡死

在这里插入图片描述
到这里一个STM32F103C8的工程就新建完毕了,接下来就是把FreeRTOS系统移植进来

三、移植FreeRTOS

我们新建一个FreeRTOS目录 用来存放移植的文件,具体如下
在这里插入图片描述
其都可以在FreeRTOS\Source里面找到 其中list.c queue.c和tasks.c是FreeRTOS系统所需的最小文件 其它文件可以根据需求自己添加
除了include目录是全部复制 portable则是根据不同的内核和编译器进行选择复制 我们使用的是Cortex-M3和Keil 所以只需要复制FreeRTOS\Source\portable\RVDS\ARM_CM3
然后就是内存管理文件了 FreeRTOS\Source\portable\MemMang 里面有五种内存管理模式 这边选择模式4 也就是heap_4.c
复制到工程目录之后 就可以添加到Keil里了
在这里插入图片描述
再添加对应的库路径

在这里插入图片描述
有没有发现 FreeRTOS就是这么简洁!当然这还没结束,我们还需要在User里新建一个配置文件:FreeRTOSConfig.h
这边我们直接使用官方例程的配置文件

#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H

#define configUSE_PREEMPTION   1 //为1时RTOS使用抢占式调度器,为0时RTOS使用协作式调度器(时间片)
#define configUSE_IDLE_HOOK    0 //设置为1使用空闲钩子(Idle Hook类似于回调函数),0忽略空闲钩子。
#define configUSE_TICK_HOOK    0 //设置为1使用时间片钩子(Tick Hook),0忽略时间片钩子。
#define configCPU_CLOCK_HZ    ( ( unsigned long ) 72000000 ) //CPU内核时钟频率
#define configTICK_RATE_HZ    ( ( TickType_t ) 100 ) //RTOS 系统节拍中断的频率。即一秒中断的次数,每次中断RTOS都会进行任务调度。
#define configMAX_PRIORITIES   ( 5 ) //配置应用程序有效的优先级数目 0优先级最小
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 128 ) //定义空闲任务使用的堆栈大小。
#define configTOTAL_HEAP_SIZE   ( ( size_t ) ( 17 * 1024 ) ) //RTOS内核总计可用的有效的RAM大小 这边为17K
#define configMAX_TASK_NAME_LEN  ( 16 ) //定义的任务名称长度最大值 包括\0
#define configUSE_TRACE_FACILITY 0 //设置成1表示启动可视化跟踪调试,会激活一些附加的结构体成员和函数。
#define configUSE_16_BIT_TICKS  0 //定义为1使用16位计数器 为0使用32位 对于任务最大延时或阻塞时间,16位计数器是262秒,而32位是17179869秒。
#define configIDLE_SHOULD_YIELD  1 //当和空闲任务相同优先级的用户任务就绪时 空闲任务是否让出

/* Co-routine definitions. */
#define configUSE_CO_ROUTINES       0 //设置成1表示使用协程,0表示不使用协程。如果使用协程,必须在工程中包含croutine.c文件。
#define configMAX_CO_ROUTINE_PRIORITIES  ( 2 ) //应用程序协程(Co-routines)的有效优先级数目

/* 根据项目需求 编译和不编译哪些方法 */
#define INCLUDE_vTaskPrioritySet   1
#define INCLUDE_uxTaskPriorityGet   1
#define INCLUDE_vTaskDelete      1
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend     1
#define INCLUDE_vTaskDelayUntil    1
#define INCLUDE_vTaskDelay      1

#define configKERNEL_INTERRUPT_PRIORITY   255
#define configMAX_SYSCALL_INTERRUPT_PRIORITY  191 
#define configLIBRARY_KERNEL_INTERRUPT_PRIORITY 15

#endif

具体各个参数作用可以参考博文FreeRTOS内核配置说明,我也是看这篇博文给的注释
添加完FreeRTOSConfig.h之后 我们还需要更改一下startup_stm32f10x_md.s文件,将FreeRTOS中断导进去 替换掉一些系统中断 具体如下:
在这里插入图片描述大功告成,写两个任务测试一下

#include "stm32f10x.h"
#include "usart1.h"
#include "FreeRTOS.h"
#include "task.h"
void vTask1(void *pvParameters)
{
 while(1)
 {
  printf("vTask1");
  vTaskDelay(1000/portTICK_RATE_MS);
 }
}
void vTask2(void *pvParameters)
{
 while(1)
 {
  printf("vTask2");
  vTaskDelay(2000/portTICK_RATE_MS);
 }
}
int main(void){
 USART1_Init();
 xTaskCreate(vTask1,"vTask1",50,NULL,1,NULL);
 xTaskCreate(vTask2,"vTask2",50,NULL,1,NULL);
 vTaskStartScheduler();
 while(1);
 //return 0;
}

编译下载运行
在这里插入图片描述可以看到系统正常运行,到这里一个最简的FreeRTOS就已经移植完毕,接下来就学习如何使用了

项目代码:下载地址

  • 0
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值