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.cFreeRTOS\portable\RVDS\ARM_CM3\port.c

 

 

 然后工程中添加头文件

 

 

 

从源码中复制一份FreeRTOSConfig.h(FreeRTOSv10.1.0\FreeRTOS\Demo\CORTEX_STM32F103_Keil\FreeRTOSConfig.h),这里选择STM32F103_keil工程下的该文件,放到工程下的FreeRTOS\include文件夹
编译一下,可能会报错,也可能不会,先不用管。编译完成后找到FreeRTOS.h文件,如图
修改FreeRTOS.h下的两个宏定义,从0改为1,我的在200多行,不同版本FreeRTOS不一样,找一下
然后编译一下工程,此时的工程就应该是没有错误和警告的。
下一步,在我看来是最重要的一步,因为这一步我没弄好,我重做了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

 

posted @   Wakupyou  阅读(995)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示