天天看點

作業系統RTOS為什麼要搞兩種API?

作者:嵌入式開發胖哥

摘要:研究所學生沒有假期,是以今天繼續更新RTOS系列文章。本文以FreeRTOS為例,如果我們自己在官網下載下傳源碼然後手動移植代碼就是使用FreeRTOS的原生API接口,如果我們使用STM32CubeMX來配置工程就是使用的CMSIS-API接口,是對FreeRTOS的原生API接口進行了封裝。

一、RTOS為什麼要搞兩種API?

CMSIS-RTOS API是ARM公司為RTOS核心制定的一套通用接口協定,它提供了一套「标準的API接口」,可以移植到各種各樣的RTOS上,使得上層的軟體、中間件、庫以及其他元件在不同的RTOS之上都可以正常工作。

簡單的說就是:STM32是ARM核心的,這大家都知道。FreeRTOS是一種免費的開源的嵌入式作業系統。那它肯定就不屬于ARM公司的對不對?這也很好了解。現在你要在我ARM核心上面使用不是我的RTOS産品,那麼我ARM公司就要把你這個RTOS給打包一遍,封裝成屬于我的适合我的API接口協定類型的CMSIS-RTOS API。這樣解釋應該好一點。

作業系統RTOS為什麼要搞兩種API?

在STM32上使用FreeRTOS,可以直接使用FreeRTOS的原生接口(原生API),源碼移植就是使用的是原生API接口,這無可厚非。你也可以選擇CMSIS接口,實際上CMSIS接口和原生接口都是類似的,但是如果你學會了CMSIS的RTOS接口之後,也能自學對應的原生接口,當然還是有差別的,是以還是需要花時間去熟悉的。

學會了CMSIS的最大好處就是,隻要其它RTOS有提供CMSIS接口,我們就可以直接使用CMSIS接口,而不需要再花時間去了解原生接口。比如我們在學習UCOS時,發現UCOS的API和FreeRTOS的API不同,是因為我們學的都是它們原生的API,就是我們下載下傳源碼後在keil中移植的那種。但是如果我們學會了CMSIS-API,那麼不管以後學習哪一個OS,隻要這個OS提供了CMSIS的接口,我們就直接可以用CMSIS的API來調用學習,而不需要再花時間去了解原生接口。

STM32CubeMX在提供FreeRTOS時也提供了CMSIS接口,後面具體舉例時就可以看到封裝的.c檔案,總之ST對FreeRTOS封裝出了CMSIS接口。

二、使用CubeMX配置FreeRTOS

以STM32F407ZGT6晶片為例,使用CubeMX配置FreeRTOS。

1、建立工程

作業系統RTOS為什麼要搞兩種API?

2、外部晶振

選擇外部晶振

作業系統RTOS為什麼要搞兩種API?

4、下載下傳器

選擇四線的SWD接口下載下傳器。

作業系統RTOS為什麼要搞兩種API?

5、打開FreeRTOS

這裡可以看到STM32CubeMX隻提供了一種RTOS就是FreeRTOS,并且提供的是CMSIS接口API,并沒有提供原生的API,是以如果你想學習原生API就必須學會手動移植源碼,使用STM32CubeMX來建立工程就必須使用ARM公司的CMSIS API

作業系統RTOS為什麼要搞兩種API?
作業系統RTOS為什麼要搞兩種API?

Include paramters

這一個與FreeRTOS的原生接口有關,大家凡是看到v打頭、x打頭的函數,都是FreeRTOS的原生函數,我們現在要使用的是對原生接口封裝後的CMSIS API,通過Include paramter的配置可以決定哪些原生接口被使用,哪些不被使用,不過有關Include paramters中的内容,一般情況下使用預設設定即可。

作業系統RTOS為什麼要搞兩種API?

User Constant

在該這欄目中可以添加宏定義,添加後就會在代碼中自動生成宏定義的代碼,但是我們一般不會這樣添加,我們需要定義什麼宏定義,我們一般都是直接在代碼中編寫。

作業系統RTOS為什麼要搞兩種API?

Task and Queues

在這一個欄目中,我們可以添加任務(線程),自動生成代碼時就會生成建立任務(線程)的代碼,一般會有一個預設任務,如果需要的話我們可以額外添加一個任務,當然我們也可以自己去寫這些建立任務的代碼。

添加一個任務(線程),預設任務+添加的任務,目前我們有兩個任務,建立工程時會自動生成建立這兩個任務的代碼。

添加之前

作業系統RTOS為什麼要搞兩種API?

添加之前

添加之後

作業系統RTOS為什麼要搞兩種API?

添加之後

Timers and Semaphores

通過該欄目可以添加軟體定時器、互斥鎖和信号量,然後就可以自動生成軟體定時器、互斥鎖和信号量的代碼,但是一般情況是在寫代碼時我們自己添加相應的代碼,而不是自動生成能,是以這個欄目不配置。

作業系統RTOS為什麼要搞兩種API?

目前不添加定時器、互斥鎖和信号量,程式設計時在代碼中添加。

FreeRTOS Heap Usage(堆設定)

作業系統RTOS為什麼要搞兩種API?

6、時鐘配置

作業系統RTOS為什麼要搞兩種API?

3年嵌入式物聯網學習資源整理分享:C語言、Linux開發、資料結構;軟體開發,STM32單片機、ARM硬體開發、物聯網通信開發、綜合項目開發教程資料;筆試面試真題。點選下方插件免費領取↓↓↓鍥炬枃搴�

Fvco:VCO頻率
SYSCLK:系統時鐘頻率
Fusb:USB,SDIO,RNG等的時鐘頻率
Fs:PLL輸入時鐘頻率,可以是HSI,HSE等. 
plln:主PLL倍頻系數(PLL倍頻),取值範圍:64~432.
pllm:主PLL和音頻PLL分頻系數(PLL之前的分頻),取值範圍:2~63.
pllp:系統時鐘的主PLL分頻系數(PLL之後的分頻),取值範圍:2,4,6,8.(僅限這4個值!)
pllq:USB/SDIO/随機數産生器等的主PLL分頻系數(PLL之後的分頻),取值範圍:2~15.
           

外部晶振為8M的時候,推薦值:plln=336,pllm=8,pllp=2

作業系統RTOS為什麼要搞兩種API?

7、工程設定

作業系統RTOS為什麼要搞兩種API?
作業系統RTOS為什麼要搞兩種API?

8、生成代碼

建議勾選上分檔案管理。我們在生成代碼的時候,出現了如下提示,我們這裡需要解決這個警告,否者會出問題。

作業系統RTOS為什麼要搞兩種API?

前面介紹FreeRTOS時說過,FreeRTOS線程切換的本質就是定時器定一個時間,定的時間到了就切換運作其它線程,在預設情況下會使用Systick來作為RTOS的時間片定時器,這裡不湊巧的是HAL 庫代碼已經使用了 Systick,是以上面警告就是告訴你沖突了,我們需要解決這個沖突。

如何解決沖突?

先點選“否”,将 sys 中的 Systick 換成其它定時器,比如tim1,RTOS就使用 tim1來做自己的Systick。

作業系統RTOS為什麼要搞兩種API?

做了以上設定後在生成代碼時就不會再出現前面所提到的警告。

FreeRTOSConfig.h

在生成的工程項目中的頭檔案目錄下有一個FreeRTOSConfig.h,如果是源碼移植的話,我們應該修改這一個.h來設定我們需要的配置,但是CubeMx提供了圖形化的配置界面,也就是我們前面所介紹的内容,我們進行了前面的配置後,關鍵配置資訊就會記錄到這個.h中,最後 FreeRTOS在工作時就會使用到.h 中的相關配置。

3、工程檔案介紹

作業系統RTOS為什麼要搞兩種API?
作業系統RTOS為什麼要搞兩種API?

CMSIS API

作業系統RTOS為什麼要搞兩種API?

CMSIS API

怎麼樣是不是跟我們使用原生API建立的任務函數有點不一樣,那是肯定不一樣的。但是要明白這種方式隻不過是給FreeRTOS原生的API穿上了一件華麗的外衣而已,函數内部其實還是調用的原生API,隻不過沒讓你看見而已。

作業系統RTOS為什麼要搞兩種API?

原生API

作業系統RTOS為什麼要搞兩種API?

原生API

不管是CMSIS API還是原生API函數的建立過程基本是一樣的,隻不過函數不一樣,是以也不要太過糾結使用哪一種API,後期這兩種API都會分析它們之間的不同,包括消息隊列、信号量、互斥量等等!

CMSIS API函數主要有:

Signal Events //信号
    osSignalSet : Set signal flags of a thread.
    osSignalClear : Reset signal flags of a thread.
    osSignalWait : Suspend execution until specific signal flags are set.
Mutexes //互斥鎖
    osMutexCreate : Define and initialize a mutex.
    osMutexWait : Obtain a mutex or Wait until it becomes available.
    osMutexRelease : Release a mutex.
    osMutexDelete : Delete a mutex.
Semaphores //信号量
    osSemaphoreCreate : Define and initialize a semaphore.
    osSemaphoreWait : Obtain a semaphore token or Wait until it becomes available.
    osSemaphoreRelease : Release a semaphore token.
    osSemaphoreDelete : Delete a semaphore.
Memory Pool //記憶體池
    osPoolCreate : Define and initialize a fix-size memory pool.
    osPoolAlloc : Allocate a memory block.
    osPoolCAlloc : Allocate a memory block and zero-set this block.
    osPoolFree : Return a memory block to the memory pool.
Message Queue //消息隊列
    osMessageCreate : Define and initialize a message queue.
    osMessagePut : Put a message into a message queue.
    osMessageGet : Get a message or suspend thread execution until message arrives.
Mail Queue //郵箱隊列
    osMailCreate : Define and initialize a mail queue with fix-size memory blocks.
    osMailAlloc : Allocate a memory block.
    osMailCAlloc : Allocate a memory block and zero-set this block.
    osMailPut : Put a memory block into a mail queue.
    osMailGet : Get a mail or suspend thread execution until mail arrives.
    osMailFree : Return a memory block to the mail queue.
           

最後,祝大家中秋節快樂,玩的開心!

原文作者:果果小師弟

原文标題:作業系統RTOS為什麼要搞兩種API?

原文連結:https://mp.weixin.qq.com/s/Fv7KoqSIGQPMtKuxpRCOiw

繼續閱讀