--基于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接入相關的技術分享。敬請關注!
更多原創分享請關注微信公眾號:嵌入式企鵝圈!

- 前言
- 物聯網架構演進和微信智能設備平臺開發
- 基于微信硬件公眾平臺的智能控制開發流程
- Protocol buffer序列化及其在微信藍牙協議中的應用
- 網絡架構、云平臺和微信公眾平臺開發接入
- 如何快速理解一個全新的嵌入式操作系統
- 如何快速理解一個全新的嵌入式操作系統(續)
- 一張圖讀懂基于微信硬件平臺的物聯網架構
- 揭開智能配置上網(微信Airkiss)的神秘面紗
- 物聯網核心協議—消息推送技術演進
- 藍牙防丟器原理、實現與Android BLE接口編程
- 以藍牙開發的視覺解讀微信Airsync協議
- 全球最低功耗藍牙單芯片(DA14580)系統架構和應用開發框架分析
- 從零開始搭建微信硬件開發環境全過程——1小時掌握微信硬件開發流程