STM32F10x SPL V3.6.2 集成 FreeRTOS v202112

来源:https://www.cnblogs.com/milton/archive/2022/09/29/16740075.html
-Advertisement-
Play Games

在整理 GCC Arm 工具鏈的Bluepill代碼示例, 常用外設都差不多了, 接下來是 FreeRTOS, 網上查到的基本上都是基於舊版本的集成, STM32 SPL版本3.5.0, FreeRTOS版本9.x或者10.x, 不如自己用新版本集成一下. 順便做個筆記. STM32F10x_Std... ...


STM32F10x SPL 集成 FreeRTOS

在整理 GCC Arm 工具鏈的Bluepill代碼示例, 常用外設都差不多了, 接下來是 FreeRTOS, 網上查到的基本上都是基於舊版本的集成, STM32 SPL版本3.5.0, FreeRTOS版本9.x或者10.x, 不如自己用新版本集成一下. 順便做個筆記.

轉載請標明出處: https://www.cnblogs.com/milton/p/16740075.html

軟體版本

STM32F10x_StdPeriph_Driver V3.6.2

ST的SPL算是教科書一般的嵌入式庫, 當前市面上大部分32位MCU的庫設計和命名, 都能看到SPL的影子, 有些甚至就是原盤照抄. 因為ST將中心放到了STM32Cube和HAL上, SPL基本上不再更新, 在時隔九年後的2021年才發佈V3.6.2. 這部分基本穩定, 和V3.5.x相比變化很小. 所以大部分廠商也樂於用SPL作為原型開發他們的庫函數, 不存在主幹分叉的問題了.

ST官網上SPL的下載地址 https://www.st.com/en/embedded-software/stm32-standard-peripheral-libraries.html點擊F1. 不知道ST是有意還是無意, 這個地址大部分時間是404狀態. 如果無法下載, 可以使用這個備份下載地址(註:下載不需要積分)

FreeRTOS v202112.00

這個版本也發佈了好一陣了, 一直沒見新的版本, LTS是202012.05, 比這個還早一年, 先用這個吧.
在代碼中可以看到 FreeRTOS v202112.00 對應的FreeRTOS Kernel版本是 V10.4.6

GCC Arm 11.2-2022.02

使用的 gcc-arm-11.2-2022.02-x86_64-arm-none-eabi, 次新的版本.

集成的要點

前提

已經有可以使用 GCC Arm 工具鏈編譯的基於 SPL V3.6.2 的項目模板

需要複製的文件

https://www.freertos.org/下載 FreeRTOS 202112.00 , 文件比較大, 但是實際上需要的文件很少. 解開後到 FreeRTOS/Source 目錄下, 複製以下的文件到項目目錄下

  • FreeRTOS/Source/include 整個目錄, 這些是頭文件
  • FreeRTOS/Source 下的所有C文件
  • FreeRTOS/Source/portable/GCC/ARM_CM3 目錄, 這是針對 STM32F103 的適配文件
  • FreeRTOS/Source/portable/MemMang 目錄, 裡面包含一些現成的記憶體管理實現

放到項目下, 目錄結構是這樣的

FreeRTOS
├── include
│   ├── atomic.h
│   ├── croutine.h
│   ├── deprecated_definitions.h
│   ├── event_groups.h
│   ├── FreeRTOS.h
│   ├── list.h
│   ├── message_buffer.h
│   ├── mpu_prototypes.h
│   ├── mpu_wrappers.h
│   ├── portable.h
│   ├── projdefs.h
│   ├── queue.h
│   ├── semphr.h
│   ├── stack_macros.h
│   ├── StackMacros.h
│   ├── stdint.readme
│   ├── stream_buffer.h
│   ├── task.h
│   └── timers.h
├── portable
│   ├── GCC
│   │   └── ARM_CM3
│   │       ├── port.c
│   │       └── portmacro.h
│   └── MemMang
│       ├── heap_1.c
│       ├── heap_2.c
│       ├── heap_3.c
│       ├── heap_4.c
│       └── heap_5.c
├── croutine.c
├── event_groups.c
├── list.c
├── queue.c
├── stream_buffer.c
├── tasks.c
└── timers.c

需要準備的文件: FreeRTOSConfig.h

可以直接使用 FreeRTOS/Demo/CORTEX_STM32F103_Keil/ 這個例子的 FreeRTOSConfig.h, 如果要避免編譯中的warning, 需要加一行

#define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 0

裡面幾個可調節的項

  • configMINIMAL_STACK_SIZE 最小棧尺寸, 預設為128, 需要占用的記憶體為 128 * 4 = 512 bytes
  • configTOTAL_HEAP_SIZE 聲明的堆尺寸, 預設的( ( size_t ) ( 17 * 1024 ) )會恰好將STM32F103C8的20K記憶體用完

需要修改的代碼: 中斷處理

選項一: 替換 startup 中的中斷處理函數

如果項目固定啟用 FreeRTOS, 則直接在 startup 代碼中修改, 對於代碼中的函數名直接替換

  • SVC_Handler -> vPortSVCHandler
  • PendSV_Handler -> xPortPendSVHandler
  • SysTick_Handler -> xPortSysTickHandler

選項二: 使用巨集定義編譯時替換

這個方式便於切換 FreeRTOS 和 Non-FreeRTOS 模式, 在 FreeRTOSConfig.h 中, 最後一個#endif之前添加以下代碼就可以了

/* Use MACRO to replace the handlers without changing startup file */
#define vPortSVCHandler     SVC_Handler
#define xPortPendSVHandler  PendSV_Handler
#define xPortSysTickHandler SysTick_Handler

測試代碼

以上步驟就已經完成了 FreeRTOS 的集成, 可以使用以下代碼檢測結果. 對於 Bluepill 板載 LED PC13 的亮燈測試.

需要註意的是, 如果使用了 FreeRTOS, 就不要再調用 SysTick_Config() 方法, 會和 FreeRTOS 衝突.

#include <stm32f10x.h>
#include <stm32f10x_gpio.h>
#include <stm32f10x_rcc.h>
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"

void vTaskFunction(void *pvParameters)
{
    (void)(pvParameters);   // Suppress "unused parameter" warning

    while (1)
    {
        GPIO_ResetBits(GPIOC, GPIO_Pin_13);
        vTaskDelay(500);
        GPIO_SetBits(GPIOC, GPIO_Pin_13);
        vTaskDelay(500);
    }
}

void LED_Config(void)
{
    // GPIO structure for port initialization
    GPIO_InitTypeDef GPIO_InitStructure;
    // enable clock on APB2
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
    /* configure port PC13 for driving an LED
     * Use GPIO_Pin_All if you want to drive the whole port
     */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  // output push-pull mode
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // highest speed
    GPIO_Init(GPIOC, &GPIO_InitStructure);            // initialize port
}

int main(void)
{
    BaseType_t xReturned;

    /*
     * Don't use Delay_Init(), which conflict with FreeRTOS tick handling
     */

    LED_Config();

    xReturned = xTaskCreate(
        vTaskFunction,              // Task function point
        "TaskLED",                  // Task name
        configMINIMAL_STACK_SIZE,   // Use the minimum stack size, each take 4 bytes(32bit)
        NULL,                       // Parameters
        2,                          // Priority
        NULL);                      // Task handler

    if (xReturned != pdPASS)
    {
        while (1);
    }

    /* Start the scheduler. */
    vTaskStartScheduler();

    /* Will only get here if there was not enough heap space to create the idle task. */
    return 0;
}

參考


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Spring中AOP的底層原理就是動態代理模式,所以我們在這裡對代理模式進行學習。 一、代理模式 1.什麼是代理 代理,顧名思義,就是一個人代替另一個人去做他需要做的事情。代理是一種設計模式,具體實現就是一個類代替某個類去實現功能。 我們舉一個例子: 我要租房子,我可以找房東直接租房子。同樣我可以找 ...
  • 特殊說明:第一章只包含了 初始化上下文,初始化監聽器列表,發佈springboot啟動事件 相關內容 其中一部分代碼 /** * Run the Spring application, creating and refreshing a new * {@link ApplicationContext ...
  • 前言 在使用SpringBoot的時候經常需要對客戶端傳入的參數進行合法性的校驗,校驗的方法基本上都是使用SpringBoot提供的註解,有時候遇上註解不能滿足需求的時候還需要在業務邏輯上進行判斷。這樣根本就沒有實現解耦。 使用方法 項目maven引入 <dependency> <groupId>c ...
  • 0.基本的數據類型: Number(數字) String(字元串) List(列表) Tuple(元組) Set(集合) Dictionary(字典) 1.基本的輸入輸出: input #輸入 print #輸出 age = 10; name = "小明"; print(age,type(age)) ...
  • ConcurrentHashMap 思考:HashTable是線程安全的,為什麼不推薦使用? HashTable是一個線程安全的類,它使用synchronized來鎖住整張Hash表來實現線程安全,即每次鎖住整張表讓線程獨占,相當於所有線程進行讀寫時都去競爭一把鎖,導致效率非常低下。 1 Concu ...
  • zip 是一個非常常見的壓縮包格式,本文主要用於說明如何使用代碼 文件或文件夾壓縮為 zip壓縮包及其解壓操作, 我們採用的是 微軟官方的實現,所以也不需要安裝第三方的組件包。 使用的時候記得 using System.IO.Compression; /// <summary> /// 將指定目錄壓 ...
  • 1. 融合效果 融合效果是指對兩個接近的元素進行高斯模糊後再提高對比度,使它們看上去“粘”在一起。在之前的一篇文章中,我使用 Win2D 實現了融合效果,效果如下: 不過 Win2D 不適用於 WPF,在 WPF 中可以使用 BlurEffect 配合自定義 Effect 實現類似的效果。Handy ...
  • 1、初衷 開發中經常需要做一些介面的簽名生成和校驗工作,最開始的時候都是每個介面去按照約定單獨實現,久而久之就變的非常難維護,因此就琢磨怎麼能夠寫了一個比較通用的簽名生成工具。 2、思路 採用鏈式調用的方式,使得簽名的步驟可以動態拼湊組合。 3、直接看效果 //設置數據源 var signSourc ...
一周排行
    -Advertisement-
    Play Games
  • Timer是什麼 Timer 是一種用於創建定期粒度行為的機制。 與標準的 .NET System.Threading.Timer 類相似,Orleans 的 Timer 允許在一段時間後執行特定的操作,或者在特定的時間間隔內重覆執行操作。 它在分散式系統中具有重要作用,特別是在處理需要周期性執行的 ...
  • 前言 相信很多做WPF開發的小伙伴都遇到過表格類的需求,雖然現有的Grid控制項也能實現,但是使用起來的體驗感並不好,比如要實現一個Excel中的表格效果,估計你能想到的第一個方法就是套Border控制項,用這種方法你需要控制每個Border的邊框,並且在一堆Bordr中找到Grid.Row,Grid. ...
  • .NET C#程式啟動閃退,目錄導致的問題 這是第2次踩這個坑了,很小的編程細節,容易忽略,所以寫個博客,分享給大家。 1.第一次坑:是windows 系統把程式運行成服務,找不到配置文件,原因是以服務運行它的工作目錄是在C:\Windows\System32 2.本次坑:WPF桌面程式通過註冊表設 ...
  • 在分散式系統中,數據的持久化是至關重要的一環。 Orleans 7 引入了強大的持久化功能,使得在分散式環境下管理數據變得更加輕鬆和可靠。 本文將介紹什麼是 Orleans 7 的持久化,如何設置它以及相應的代碼示例。 什麼是 Orleans 7 的持久化? Orleans 7 的持久化是指將 Or ...
  • 前言 .NET Feature Management 是一個用於管理應用程式功能的庫,它可以幫助開發人員在應用程式中輕鬆地添加、移除和管理功能。使用 Feature Management,開發人員可以根據不同用戶、環境或其他條件來動態地控制應用程式中的功能。這使得開發人員可以更靈活地管理應用程式的功 ...
  • 在 WPF 應用程式中,拖放操作是實現用戶交互的重要組成部分。通過拖放操作,用戶可以輕鬆地將數據從一個位置移動到另一個位置,或者將控制項從一個容器移動到另一個容器。然而,WPF 中預設的拖放操作可能並不是那麼好用。為瞭解決這個問題,我們可以自定義一個 Panel 來實現更簡單的拖拽操作。 自定義 Pa ...
  • 在實際使用中,由於涉及到不同編程語言之間互相調用,導致C++ 中的OpenCV與C#中的OpenCvSharp 圖像數據在不同編程語言之間難以有效傳遞。在本文中我們將結合OpenCvSharp源碼實現原理,探究兩種數據之間的通信方式。 ...
  • 一、前言 這是一篇搭建許可權管理系統的系列文章。 隨著網路的發展,信息安全對應任何企業來說都越發的重要,而本系列文章將和大家一起一步一步搭建一個全新的許可權管理系統。 說明:由於搭建一個全新的項目過於繁瑣,所有作者將挑選核心代碼和核心思路進行分享。 二、技術選擇 三、開始設計 1、自主搭建vue前端和. ...
  • Csharper中的表達式樹 這節課來瞭解一下表示式樹是什麼? 在C#中,表達式樹是一種數據結構,它可以表示一些代碼塊,如Lambda表達式或查詢表達式。表達式樹使你能夠查看和操作數據,就像你可以查看和操作代碼一樣。它們通常用於創建動態查詢和解析表達式。 一、認識表達式樹 為什麼要這樣說?它和委托有 ...
  • 在使用Django等框架來操作MySQL時,實際上底層還是通過Python來操作的,首先需要安裝一個驅動程式,在Python3中,驅動程式有多種選擇,比如有pymysql以及mysqlclient等。使用pip命令安裝mysqlclient失敗應如何解決? 安裝的python版本說明 機器同時安裝了 ...