1. 程式人生 > >如何快速理解一個全新的嵌入式作業系統

如何快速理解一個全新的嵌入式作業系統

---基於TI CC254X OSAL的分析

當工具鏈配置完成後,Source Insight向你展示一份原始碼工程,不借助百度和開發文件,能否在一兩個小時內理解原始碼的組成框架和介面,進行快速開發?

在筆者過往撰寫的博文中,一直在倡導兩個嵌入式學習和開發理念:提高嵌入式系統架構和軟體層次形成大局觀;掌握從需求的角度去理解新系統和技術這個方法論。在軟體大局觀作為學習新系統的背景知識的基礎上,從軟體需求的角度入手就能快速理解和掌握一個全新的系統。本文以TI藍芽BLE CC254x的原始碼庫和工程為例進行分析研究。

一、作業系統相關概念

1. 作業系統

最常見的通用作業系統是Windows和Linux。作業系統給應用層提供程序排程、程序間通訊、記憶體管理、驅動管理、檔案管理、中斷管理、時間管理等相關介面。在嵌入式領域,除了通用的嵌入式Linux作業系統,更多的是定製型的作業系統。定製型作業系統一般都是閉源且高度裁剪移植的系統,根據應用的需求提供必要的功能和管理模組。資源豐富型系統的應用層和核心層會使用不同的CPU執行模式,只有核心層能夠訪問硬體資源,而資源緊缺型系統的應用層和核心都是運行同一模式,都能夠訪問硬體資源。

嵌入式系統中有單任務作業系統和多工作業系統。單任務作業系統一般用於簡單的電子控制和處理產品中,如玩具、工業控制、家電等等。而多工作業系統則用於較為複雜且功能豐富的電子產品中,如手機、視訊監控等等。

在一般的簡單的電子產品中,作業系統只是一種層次概念,其管理的功能顯得比較弱,有時甚至為了效果和記憶體而進一步削減它的存在,但是軟體層次能夠讓軟體工程顯得更加有序和易於維護和管理。只要中斷管理、GPIO和驅動、時間管理單獨成模組,我們都可以認為它形成作業系統。

2. 核心

核心是多工作業系統的核心,最基本的功能就是任務排程和任務間通訊。既然是多工併發執行,而CPU只有一個(假設是單核CPU),就必須做好任務的排程和任務間的同步和通訊。Linux是一個作業系統(OS),其核心(kernel)除了任務排程、任務間通訊,還有記憶體管理、網路介面等;UCOS是常見的多工核心,多用於資源有限型嵌入式系統,它提供了優先順序搶佔的任務排程和訊號量、郵箱、訊息佇列等任務間通訊,儘管UCOS也提供了記憶體管理,但完全可以裁剪掉這個功能。

3. 併發

一個系統可能有多個獨立的任務,但是否是多工作業系統,是以這些任務是否併發為標準。所謂併發,是指各個獨立的任務是否能夠得到公平的執行機會。如果一個任務必須要等待另一個任務完成才能執行,那兩者是序列執行;如果一個任務能夠在另一個任務執行過程中搶佔CPU,才算是併發執行。併發執行跟任務上下文密切相關,單任務作業系統只有一個使用者上下文,而多工作業系統的每個任務都有一個上下文,任務切換就是對上下文的切換。

4. TI CC254x需求分析

TI CC254x是在8051核上整合藍芽BLE4.0低功耗的單晶片,可以預想它是一個資源緊缺型的嵌入式系統;同時CC254x是為了完成藍芽連線和簡單的控制功能(即GAP profile和GATT profile),因此TI提供的庫也重點圍繞藍芽連線和控制傳輸設計,而沒有通用作業系統所支援的檔案、驅動管理等功能;另外藍芽協議是分層協議棧,各層都有獨立的的業務和處理流程,它會是多工應用嗎?

TI向用戶提供了一個叫做OSAL(作業系統抽象層)的程式設計框架,除了藍芽相關的底層協議不透明,OS相關的任務排程和通訊、藍芽高層協議都是使用者透明的。誠如以上對單任務作業系統的分析,OASL也是一個較弱的作業系統,只包含了排程和通訊的核心,和一個硬體抽象層。但不妨礙我們把它當成一個作業系統去理解。

5. 如何快速開發

理解工程的架構、任務排程、任務通訊、使用者訊息的輸入和輸出之後,就能進入快速開發階段了。基於以上分析,要在OASL上進行快速開發,我們需要重點關注OSAL的任務編排程、任務間通訊、使用者訊息輸入和處理。對於藍芽協議棧相關的內容(GAP、GATT等應用profile),不是本文的重點,以後再另外撰文闡述。

二、OSAL的任務排程

1. 背景知識

嵌入式系統中每個任務都是while(1)的大迴圈。在單任務中可能還會有不同的場景,例如每個功能選單都可以認為是一個場景,每個場景都有自己的訊息大迴圈,但本質上還是一個while(1)的迴圈。而在多工作業系統中,每個任務都有自己的訊息迴圈。任務間的協同執行依賴任務的主動釋放控制權(主動休眠)和被動的掛起(如等待另一個任務的訊號量)。每個任務都必須要在就緒狀態才可能得到執行的機會。

2. OAL應用需求

OSAL支援藍芽協議棧,包括鏈路層、適配層、GAP連線管理、ATT屬性管理、GAP profile應用、GATT profile應用,此外還要支援使用者的按鍵訊息輸入處理等。各層均有獨立的分工和職責。到底是以多工來支援這種模型,還是單任務的多場景呢。拭目以待!

3. OSAL程式碼分析(以SimplePeripheral為例)

1)從main開始,main->osal_init_system-> osalInitTasks,如下圖:


tasksCnt是系統的任務個數,如下圖:


陣列中每個成員都是一個任務處理過程。先給tasksEvents申請空間,tasksEvents是做什麼的,先不管它。

osalInitTasks接著就是進行各個任務的初始化,這時還沒有進入訊息迴圈。我們注意到taskID在每個任務初始化後,taskID都會加1,而在每個任務初始化的開始都會記錄傳入的taskID並儲存,作為任務的標記。

2)main-> osal_start_system,如下圖:

 

我們看到大迴圈了。繼續看:

 

可見,taskID除了任務標識,還有優先順序的含義。tasksEvents陣列的每個元素即對應每個任務的就緒狀態,0為沒有事件需要處理,非0代表有事件需要處理。

跟蹤一個任務處理流程,我們發現裡面並沒有while(1)迴圈,都是等到某個任務執行完才返回,返回之後回到osal_start_system大迴圈。因此該系統本質上是一個單任務操作,只有一個上下文。但是OASL的程式設計模型看起來確實蠻想多工系統的,或者其借鑑了很多多工程式設計的思維,如在OASL看到了很多UCOS的影子。

為什麼要將返回值設定到tasksEvents中,就是因為其本質是一個單任務迴圈,如果某個子任務時間執行過長,會影響更高優先順序的任務的響應變慢,影響整體效能。因此如果一個任務執行比較長,宜進行分割,在返回值那裡設定繼續處理事件,然後返回大迴圈,看看有沒有更高優先順序的任務需要執行。

三、OASL的任務間通訊

1. 背景知識

Linux的任務間通訊包括訊息佇列、共享變數,有訊號量來同步;UCOS也有訊息佇列、郵箱和條件變數、訊號量等手段來進行通訊和同步。OSAL是單任務作業系統,需要由使用者層的各個任務處理過程自己約束保證同步。

訊息一般包括按鍵訊息、時間訊息、繪圖訊息等等,訊號量用於任務間的同步,並不屬於訊息傳遞。

2. OSAL的程式碼分析

tasksEvents的元素除了作為就緒狀態,還有另外一個作用就是作為引數傳入該應用處理過程。我們跟蹤一個處理過程:


可以看到,event可能是使用者自定義的事件,如這個任務要做的週期性的事情和啟動連線的事件。另外,event還可能是系統訊息事件(SYS_EVENT_MSG),它是什麼?訊息和事件在OSAL中是怎麼理解的。

其實把事件作為訊息的型別更容易理解,事件用一個16位的整型來表示,從程式碼來看,是每個位元表示一種事件,其最多隻能表示16種事件。對於按鍵訊息,由於其可能有多個不同的鍵值,因此不宜通過多個事件來表示,而是用一個按鍵事件來表示,然後按鍵的鍵值通過訊息佇列來傳遞。

通過跟蹤訊息傳送osal_msg_send( uint8 destination_task, uint8 *msg_ptr )和訊息接收osal_msg_receive( uint8 task_id )介面,可以發現,所有的任務共用一個連結串列型的訊息佇列,每個結點記錄訊息的事件型別/值和接收任務的taskID。

那麼事件的傳送介面呢?如下圖


即往tasksEvents的taskID下標成員寫入對應的事件值。這樣在之後的大迴圈中目標task就會得到執行的機會。訊息傳送osal_msg_send不僅將訊息插入到全域性訊息佇列連結串列,而且最後也會呼叫osal_set_event介面填入SYS_EVENT_MSG事件。

此外,還有一個定時傳送事件的介面osal_start_timerEx,其在規定的時間到達後才會傳送該事件,以讓目標taskID得到執行事件的機會。

四、OSAL訊息處理

OSAL提供了一個HAL硬體抽象層,咱們主要分析按鍵輸入和串列埠輸出就好了。

利用TI CC2540進行藍芽方案開發還是幾個前,當時一個小時就理解了OSAL,但現在把當時的理解思路還原整理出來花了差不多四個小時,主要是因為在撰寫過程中不斷地考慮如何讓讀者更好地理解本文的學習思路,即總結軟體架構方面的知識,和如何從需求的角度去理解新的系統。嗚嗚,還是把OSAL的訊息處理流程留到下一篇好了。

接下來將會陸續推出物聯網-微信藍芽和wifi接入相關的技術分享。敬請關注!

更多原創分享請關注微信公眾號:嵌入式企鵝圈!


相關推薦

如何快速理解一個全新嵌入式作業系統

---基於TI CC254X OSAL的分析當工具鏈配置完成後,Source Insight向你展示一份原始碼工程,不借助百度和開發文件,能否在一兩個小時內理解原始碼的組成框架和介面,進行快速開發?在筆

IFTNews:就好像理解比特幣還不夠困難一樣,以太坊引入了一個全新的復雜性。即使你有紮實的技術背

音樂 簡化 地產 市場 必須 什麽 展望 基礎 部分 IFTNews:就好像理解比特幣還不夠困難一樣,以太坊引入了一個全新的復雜性。即使你有紮實的技術背景,在一切都有意義之前,還需要一些時間和獨立的研究——除非你是個天才。 話雖如此,對以太坊如何運作的基本理解實際上可以使一

如何選擇一個合適的嵌入式作業系統

選擇一個合適的嵌入式作業系統,可以考慮以下幾個因素:第一是應用。如果你想開發的嵌入式裝置是一個和

getBoundingClientRect的快速理解

cli 一個 bound 兼容性問題 想要 html 返回 理解 好的 getBoundingClinetRect: 獲取某一個元素相對視窗的位置集合(它是一個方法,返回一個對象集合)   位置集合主要包括 { top, left, right,bottom } 等屬性

快速理解Java中的五種單例模式

嵌套類 ati class 由於 aop 適合 singleton 重復 code 解法一:只適合單線程環境(不好) package test; /** * @author xiaoping * */ public class Singleton { pri

如何教你快速通過一個cmd命令啟動Oracle的兩個相關服務

安裝目錄 startup ice 11.2 start 服務 文件 我們 font 你安裝好了Oracle數據庫之後。 它都會默認開機自啟服務。 而我們為了節省電腦資源就把它給調為手動。 我們調為手動之後以後要用到Oracle數據庫就必須再去服務裏面一個一個去啟動。 這樣是

快速構建一個 Springboot

pan -1 conf tomcat one feature 添加 自動配置 span 快速構建一個 Springboot 官網:http://projects.spring.io/spring-boot/ Spring Boot可以輕松創建可以“運行”的獨立的,生產級的

六招助你快速建設一個優秀網站

怎樣建網站 網站建設 站長都知道一個優秀的網站對網站的影響有多重要,不僅可以為用戶帶來驚喜,還可以給網站帶來意想不到的收獲。而要建一個優秀的網站該怎樣建網站,一般有哪些步驟呢?下面就一起來分析一下。 第一、對網站的目的定位要清晰。對於網站目的的定位,每個人都不一樣的看法,但是從整體上來說,網站建

學一點 mysql 雙機異地熱備份----快速理解mysql主從,主主備份原理及實踐

server counter ror 位置 正在 大型 主循環 備份 配置詳解 雙機熱備的概念簡單說一下,就是要保持兩個數據庫的狀態自動同步。對任何一個數據庫的操作都自動應用到另外一個數據庫,始終保持兩個數據庫數據一致。 這樣做的好處多。 1. 可以做災備,其中一個壞了可

快速部署一個LNMP

lnmp1.安裝nginx # wget http://nginx.org/packages/rhel/7/x86_64/RPMS/nginx-1.8.1-1.el7.ngx.x86_64.rpm # rpm -ivh nginx-1.8.1-1.el7.ngx.x86_64.rpm 2.安裝

快速理解VirtualBox的四種網絡連接方式

又是 dhcp nat guest 參考資料 virt 簡單的 網絡基礎知識 基礎知識 VirtualBox中有4中網絡連接方式: NAT Bridged Adapter Internal Host-only Adapter VMWare中有三種,其實他跟

快速排序,一個愛情故事-java版

-- .com span 得到 跳出循環 div public while 五步 public static void myquicksort(int[] ages,int girl,int boy){ //這是一個站在數組兩端,追求完美愛情的故事 //年齡

如何快速知道一個顏色的rgb值

編輯 如何 win7 rgb 參考 cnblogs mage 技術分享 顏色表 1.如果你想使用某種顏色缺不知道rgb值是多少,可以將一張圖片用系統自帶的畫圖(我的系統是win7)0工具打開,點擊編輯顏色就會出現調色板,然後就可以選擇查看具體顏色的rgb值了 2.如果

從頭開始編寫一個實時嵌入式操作系統的內核(一)

rtos signed 語言 配置 ffd ldr 進行 first special 今年大四,在準備自己的畢業設計。因為畢設題目是一個比較復雜的多傳感器監控的嵌入式系統,然後最近自己有使用一些rtos,比方說freertos和ucos,感覺比起單純對單片機的裸機開發還是有

快速上手一個第三方控件,工具等

info 實現 pro 源碼 GridView mis form 圖表 國內開發 我也曾苦苦追尋一個通用的流程,怎麽去快速上手一個新的第三方的東西,真的很難啊,文檔看不懂,也不知道重點在哪。 雖然一直在用C1控件,但基本對於如何上手雲裏霧裏,基本是摸黑瞎找的,現在突然在其官

webpack快速入門——webpack3.X 快速上手一個Demo

目錄 pre head -c 文字 get cal 瀏覽器 size 1.進入根目錄,建兩個文件夾,分別為src和dist 1).src文件夾:用來存放我們編寫的javascript代碼,可以簡單的理解為用JavaScript編寫的模塊。 2).dist文件夾:用來存放供瀏

webpack-第02節:讓你快速上手一個Demo

bpa live data- ati translate 輸入 理解 dex ans 上節課已經安裝好了Webpack到電腦上,這節課就開始一個簡單的Demo,讓你快速上手和熟悉Webpack的基本用法,學習並作完這節課內容你就可以和朋友小吹一下說:我也會Webpack。

兩天快速開發一個自己的微信小程序

navig 預覽圖片 免費 tab頁 初始 組件 view 暫時 換上 一.寫在前面 1.為什麽要學小程序開發? 對於前端開發而言,微信小程序因為其簡單快速、開發成本低、用戶流量巨大等特點,也就成了前端開發工程師必會的一個技能。 2.先放上我做的小程序 可以在微

如何快速接手一個

tgz .com ecb bdd a20 usr bdc dtc sof 4v8iwx緯恐俑陡圖資http://blog.sina.com.cn/s/blog_17da9a8600102xudq.htmlh675b3棺歐材餒謎倚http://blog.sina.com.cn

一個全新的開始

body img ima clas python 發現 今天 什麽 百度 2018年過完春節,新年要有新的目標,慚愧的發現自從工作到現在已經三年了,自己忘記了什麽是堅持,忘記了不顧一切去完成一件事情的心跳感,導致現在一直停滯不前,庸庸碌碌的打了三年的醬油,什麽東西都