STM32F103移植FreeRTOS操作系统
使用的是STM32F103ZET6芯片,随便一个开发板都可。
使用的是标准库函数来进行开发,去网上下载了原子哥的代码,直接打开跑马灯实验开整。
首先下载FreeRTOS源码压缩包,直接去官网下载即可,FreeRTOS - Market leading RTOS (Real Time Operating System) for embedded systems with Internet of Things extensions我下载的是目前最新版,解压以后得到如图所示。
下一步复制一版跑马灯实验,在文件夹目录下新建一个FreeRTOS文件夹。
下一步复制下载的源码中的 Source
文件夹下的所有文件到刚才的跑马灯工程FreeRTOS文件夹下。
下一步工程下新建FreeRTOS目录,添加源码中的7个.文件和FreeRTOS\portable\MenMang\heap_4.c
和FreeRTOS\portable\RVDS\ARM_CM3\port.c
然后工程中添加头文件

从源码中复制一份FreeRTOSConfig.h(
FreeRTOSv10.1.0\FreeRTOS\Demo\CORTEX_STM32F103_Keil\FreeRTOSConfig.h
),这里选择STM32F103_keil工程下的该文件,放到工程下的FreeRTOS\include
文件夹编译一下,可能会报错,也可能不会,先不用管。编译完成后找到FreeRTOS.h文件,如图


然后编译一下工程,此时的工程就应该是没有错误和警告的。
下一步,在我看来是最重要的一步,因为这一步我没弄好,我重做了3遍上面的步骤,无语。。。。
修改startup_stm32f10x_hd.s
; Vector Table Mapped to Address 0 at Reset AREA RESET, DATA, READONLY EXPORT __Vectors EXPORT __Vectors_End EXPORT __Vectors_Size IMPORT vPortSVCHandler IMPORT xPortPendSVHandler IMPORT xPortSysTickHandler __Vectors DCD __initial_sp ; Top of Stack DCD Reset_Handler ; Reset Handler DCD NMI_Handler ; NMI Handler DCD HardFault_Handler ; Hard Fault Handler DCD MemManage_Handler ; MPU Fault Handler DCD BusFault_Handler ; Bus Fault Handler DCD UsageFault_Handler ; Usage Fault Handler DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved ; DCD SVC_Handler ; SVCall Handler DCD vPortSVCHandler DCD DebugMon_Handler ; Debug Monitor Handler DCD 0 ; Reserved ; DCD PendSV_Handler ; PendSV Handler DCD xPortPendSVHandler ; DCD SysTick_Handler ; SysTick Handler DCD xPortSysTickHandler
直接复制粘贴就OK,我就是因为没有复制粘贴,我多做了好几遍,全是泪啊,然后编译,下载
下一步,直接使用高端程序员方式,Ctrl+C,Ctrl+V以下主函数代码,就ok啦。
#include "sys.h" #include "delay.h" #include "usart.h" #include "led.h" #include "FreeRTOS.h" #include "task.h" //任务优先级 #define START_TASK_PRIO 1 //任务堆栈大小 #define START_STK_SIZE 128 //任务句柄 TaskHandle_t StartTask_Handler; //任务函数 void start_task(void *pvParameters); //任务优先级 #define LED0_TASK_PRIO 2 //任务堆栈大小 #define LED0_STK_SIZE 50 //任务句柄 TaskHandle_t LED0Task_Handler; //任务函数 void led0_task(void *pvParameters); //任务优先级 #define LED1_TASK_PRIO 3 //任务堆栈大小 #define LED1_STK_SIZE 50 //任务句柄 TaskHandle_t LED1Task_Handler; //任务函数 void led1_task(void *pvParameters); int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4 LED_Init(); //初始化LED端口 //创建开始任务 xTaskCreate((TaskFunction_t )start_task, //任务函数 (const char* )"start_task", //任务名称 (uint16_t )START_STK_SIZE, //任务堆栈大小 (void* )NULL, //传递给任务函数的参数 (UBaseType_t )START_TASK_PRIO, //任务优先级 (TaskHandle_t* )&StartTask_Handler); //任务句柄 vTaskStartScheduler(); //开启任务调度 } //开始任务任务函数 void start_task(void *pvParameters) { taskENTER_CRITICAL(); //进入临界区 //创建LED0任务 xTaskCreate((TaskFunction_t )led0_task, (const char* )"led0_task", (uint16_t )LED0_STK_SIZE, (void* )NULL, (UBaseType_t )LED0_TASK_PRIO, (TaskHandle_t* )&LED0Task_Handler); //创建LED1任务 xTaskCreate((TaskFunction_t )led1_task, (const char* )"led1_task", (uint16_t )LED1_STK_SIZE, (void* )NULL, (UBaseType_t )LED1_TASK_PRIO, (TaskHandle_t* )&LED1Task_Handler); vTaskDelete(StartTask_Handler); //删除开始任务 taskEXIT_CRITICAL(); //退出临界区 } //LED0任务函数 void led0_task(void *pvParameters) { while(1) { LED0=~LED0; vTaskDelay(500); } } //LED1任务函数 void led1_task(void *pvParameters) { while(1) { LED1=0; vTaskDelay(200); LED1=1; vTaskDelay(800); } }
转自简书上的一位大佬。
链接:https://www.jianshu.com/p/01f3580feef8
链接:https://www.jianshu.com/p/01f3580feef8
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现