单片机学习小组
直播中

杨平

7年用户 1704经验值
私信 关注

怎样在STM32F103C8上去移植FreeRTOS操作系统呢

怎样去新建一个STM32F103C8的工程呢?
怎样在STM32F103C8上去移植FreeRTOS操作系统呢?有哪些移植步骤?

回帖(1)

李帅

2022-2-23 10:47:11
一、所需环境


本文使用STM32F103C8T6这款中端使用比较多的Cortex-M3内核MCU
编译环境是使用Keil uVision4

二、最小工程创建


先用Keil创建一个工程,选择STM32F103C8

选择否,后面我们自己添加官方外设库的文件


工程建好了之后,就可以将ST官方外设库相关文件加入工程目录里了
先新建个CMSIS的目录来放置与内核硬件相关的文件

这边需要对stm32f10x.h修改一下 不使用conf文件
注释掉两部分 然后定义空的assert_param函数 这样就不需要再导入stm32f10x_conf.h文件了 当然 如果喜欢使用的就不要改动了
再新建一个存放外设库文件的目录 这里命名为STM32F10x_Libs,将官网外设库STM32F10x_StdPeriph_Lib_V3.5.0LibrariesSTM32F10x_StdPeriph_Driver里的src和inc目录复制过来
之后再创建一个User目录存放main.c 一个Basic目录放置串口等基本工具文件
然后在Keil里导入对应的文件

然后设置库路径和宏定义 STM32F10X_HD


再记得把Use MicroLIB勾上 不然在使用串口printf函数时会卡死


到这里一个STM32F103C8的工程就新建完毕了,接下来就是把FreeRTOS系统移植进来

三、移植FreeRTOS


我们新建一个FreeRTOS目录 用来存放移植的文件,具体如下

其都可以在FreeRTOSSource里面找到 其中list.c queue.c和tasks.c是FreeRTOS系统所需的最小文件 其它文件可以根据需求自己添加
除了include目录是全部复制 portable则是根据不同的内核和编译器进行选择复制 我们使用的是Cortex-M3和Keil 所以只需要复制FreeRTOSSourceportableRVDSARM_CM3
然后就是内存管理文件了 FreeRTOSSourceportableMemMang 里面有五种内存管理模式 这边选择模式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 ) //定义的任务名称长度最大值 包括
#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
添加完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就已经移植完毕,接下来就学习如何使用了。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分