前言:想起以前用標準庫做RTOS的時候一大堆操作就很煩,還好MX支持了直接配置生成RTOS工程很方便,最近發現一些很久以前買的模塊沒用上放着佔地方然後順便拿出來做了個小遙控器玩玩,下面給遙控器配個RTOS跑跑。
軟件:
STM32CubeMX V5.3.0
固件庫版本:
STM32Cube FW_F1 V1.8.0
硬件:
STM32F103C8T6
0.96寸IIC接口OLED
雙通道遙感電位器
正文:
1、接着用上次配的工程,打開RTOS,配置內核時鐘
配置時基產生定時器
HAL庫函數如CAN通訊用的是HAL_IncTick(),而HAL_IncTick()是CubeMX的TimeBase配置的,這個時候如果需要實時響應,則TimeBase最好爲最高優先級0,即根據CubeMX推薦的設置TimeBase爲TIM1提供。而原先裸機的HAL系統時鐘用的Systick,現在Systick用到FreeRTOS上的調度,所以要求Systick爲最低優先級15,這樣可以保證systick不會對進程造成影響,僅存在延時。而消除延時的手段並不是提高systick的優先級,而是讓中斷服務程序更快。
2、配置Config parameters,這裏大部分是默認參數,然後因爲後面要開三個任務,默認堆棧大小不夠,修改了一個總堆棧大小
關於裏面參數的相關含義這裏有一篇介紹得很好的文章https://blog.csdn.net/zhzht19861011/article/details/50134883
現在把部分重要的參數整理成表格如下:
類 | 參數名稱 | 參數取值 | 參數含義說明 |
USE_FREEMPTION | Enabled/Disnable | Enabled–搶佔式調度器:優先級高的任務優先執行。 Disnable–協作式調度器:不考慮優先級,所有任務輪流執行。 |
|
CPU_CLOCK_HZ | SystemCoreClock | CPU 時鐘頻率。STM32F1 默認只能使用主系統時鐘頻率。 | |
TICK_RATE_HZ | 1–1000 | tick 中斷的頻率,單位爲Hz。 直接影響到計時的分辨率,精度越高,佔用CPU時間越多。 |
|
MAX_PRIORITIES | 4–255 | 能夠分配給任務的最大優先級。佔內存儘量低 | |
MINIMAL_STACK_SIZE | 128k | 分配給空閒任務的最小棧空間,單位爲字,對於 STM32 而言一個字爲 32bit。 應該考慮線程的數量、總堆大小和系統棧大小。當動態分配時,最大值= configTOTAL_HEAP_SIZE/4;當靜態分配時,最大值= MCU ram size/4。 |
|
MAX_TASK_NAME_LEN | 12–255 | 任務名的最大(ASCII)字符數,包括字符串結束符NULL(’\0’)。 | |
USE_16_BIT_TICKS | Enabled/Disnable | 定義系統節拍計數器的變量類型,即定義portTickType是表示16位變量還是32位變量。 | |
IDLE_SHOULD_YIELD | Enabled/Disnable | 當任務具有空閒優先級且內核系統使用了搶佔式調度器,則 Disnable–阻止空閒任務爲其它具有空閒優先級的任務讓出CPU,只有當空閒任務離開運行狀態才能被搶佔。 Enabled–如果有另外一個空閒優先級的任務在準備狀態,則空閒任務立刻讓出CPU,讓該任務運行。 |
|
USE_MUTEXES | Enabled/Disnable | 是否使用互斥量 | |
USE_RECURSIVE_MUTEXES | Enabled/Disnable |
當USE_MUTEXES=1纔有意義。 是否使用遞歸互斥量 |
|
USE_COUNTING_SEMAPHORES | Enabled/Disnable | 是否使用計數信號量 | |
QUEUE_REGISTRY_SIZE | 0–255 | 隊列記錄有2個用途,都與操作系統內核的調試器有關: 1、它允許文本名稱與隊列關聯,便於在調試GUI中識別隊列。 2、它包含調試器所需的信息來定位每個已註冊的隊列和信號量。 如果想使用內核調試器查看隊列和信號量信息,必須先將這些隊列和信號量進行註冊。參見vQueueAddToRegistry()和vQueueUnregisterQueue()。 |
|
USE_APPLICATION_TASK_TAG | Enabled/Disnable | Enabled–vTaskSetApplicationTaskTag 函數有效。僅用於高級用戶。可以爲每個任務分配一個“tag”值。 此值僅用於應用程序,RTOS 內核本身並不以任何方式使用它。 | |
ENABLE_BACKWARD_COMPATIBILITY | Enabled/Disnable |
用於選擇執行的任務的方法:通用方法和特定於硬件的方法 一般設置成Disnable,效率略低於特定方法,但是沒有什麼限制條件 |
|
USE_PORT_OPTIMISED_TASK_SELECTION | Enabled/Disnable | 頭文件 FreeRTOS.h 包含一系列 #define 宏定義,這些宏將 FreeRTOS 8.0.0 版本之前使用的數據類型的名稱映射到版本 8.0.0 中使用的名稱。 這些宏可以確保RTOS內核升級到V8.0.0版本時,之前的應用代碼不用做任何修改。 |
|
USE_TICKLESS_IDLE | Enabled/Disnable | 低功耗模式是否開啓。 | |
USE_TASK_NOTIFICATIONS | Enabled/Disnable | 每個RTOS任務具有一個32位的通知值,RTOS任務通知相當於直接向任務發送一個事件,接收到通知的任務可以解除任務的阻塞狀態(因等待任務通知而進入阻塞狀態)。相對於以前必須分別創建隊列、二進制信號量、計數信號量或事件組的情況,使用任務通知顯然更靈活。更好的是,相比於使用信號量解除任務阻塞,使用任務通知可以快45% | |
RECORD_STACK_HIGH_ADDRESS | Enabled/Disnable | 這個似乎與代碼指向堆棧最高地址有關 |
3、配置Include parameters,用於裁剪內核,定製一個合適大小的內核,設置關閉某些沒必要的API可以減輕內核大小。
4、在TaskAndQueues任務列表中添加自己的任務任務及隊列的配置。
TaskName是任務名稱,一個字符串而已。下面是優先級配置,再往下是任務堆棧大小。EntryFunction是任務函數名。CodeGenerationOption是選擇自動生成代碼是否聲明成weak。Allocation是配置內存是否動態分配,此處CUbeMX默認動態分配不給更改。
5、生成代碼,在freertos.c文件裏面可以看到剛剛我們定義函數名字的函數生成了,但是還是空函數,可以自己添加邏輯和算法處理函數。
我們做好邏輯和算法處理函數之後直接在這個文件裏面調用即可,main.c文件不需要做其他操作
在main函數裏面做完底層初始化之後就開始初始化RTOS,然後開啓任務調度,這就實現了一個多線程的過程。
這裏分別設置了三個線程,OLED顯示刷新、LED閃爍、ADC數據處理。