精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

嵌入式軟件的設計模式

開發 前端
隊列模式串行訪問資源,通過將請求放在隊列中,并且按照先進先出 (FIFO) 的順序從隊列取出,隊列模式概念上非常簡單,但是導致資源的請求響應延遲,影響時效性。

1、嵌入式軟件與設計模式

思從深而行從簡

軟件開發,難的不是編寫軟件,而是編寫功能正常的軟件。軟件工程化才能保證軟件質量和項目進度,而設計模式使代碼開發真正工程化,設計模式是軟件工程的基石。

所謂設計模式就是對常見問題的通解,合理地運用設計模式可以很好地解決很多問題,每種模式針對一個通用問題,以及該問題的核心解決方案,這也是設計模式能被廣泛應用的原因。真正的高手能云淡風輕地用最簡單的方法解決最復雜的問題,這也是高級程序員與新手的本質區別之一。

一般常見的是四人幫模式即GOF的23種設計模式,是偏向于可復用的面向對象的軟件,并不能很完美的契合嵌入式軟件,因為嵌入式C語言是結構化的語言,與硬件關聯。雖然也可強制封裝結構體實現類似效果(復雜的嵌入式應用軟件也可使用,但對于通用PC的高級語言存在差距)。

基于嵌入式系統的工作流,選擇合適的設計模式或代碼框架,將復雜軟件解耦或者分層,提高代碼復用度和可擴展性具有一定意義,當然,代價是對資源和實時性的損耗。

嵌入式系統軟件設計模式 :

1、硬件訪問類

2、并發同步類 

3、狀態與工作流類 

4、安全性與可靠性類

設計模式是在已具備一定開發基礎的前提下,對軟件架構的優化,因此部分章節需要熟悉數字電路、RTOS實時操作系統等,才能更好的理解。更多理論信息可關注微信公眾號【嵌入式系統】的其他文章。

2、硬件訪問類設計模式

2.1 硬件訪問的概念

嵌入式系統最明顯的特性是可直接訪問硬件,硬件操作通常會包括初始化、配置、控制等步驟,嵌入式軟件管理硬件,給硬件提供命令或數據,或者從其獲取信息,這塊即是常說的硬件驅動代碼。這類軟件設計主要是考慮硬件器件的更換與兼容,對業務層的封裝和隔離。

2.2 硬件代理模式

硬件代理模式(Hardware Proxy Pattem)使用結構體封裝所有硬件設備訪問,無論其硬件接口是怎樣的,代理為客戶提供與硬件形態無關的接口。

如果應用層直接訪問硬件設備,硬件的變化所導致的問題會加??;一個細節的改變,應用層均需要重新調整,通過提供介于應用層和硬件之間的代理,就極大地限制了硬件改變的影響,從而減少這樣的修改。類似常說的代理律師,就是即使不懂法律,但可以請律師,由代理律師去活動。

硬件代理接口可以形如 init、open、close、read、write、control,其內部實現無需開放。函數名稱或者結構體內函數指針名只是參考,也可以自定義諸如config等,這里只是說明,對不同的硬件設備統一訪問接口,封閉細節。

但是也有一定缺點,硬件細節已經在硬件代理內部完全封裝,對運行實時性有不良的影響。其實,所有的設計模式都是利于軟件維護,而不利于實時性。代理模式只是簡單封裝接口,不能實現線程安全,除非在封裝時額外增加加臨界區或者隊列保護。

例如開啟加速度傳感器,最初需求只有一顆如BMA425,其開啟接口為 gsensor_bma425_open;但后期硬件替換為SCA720,如果是直接操作則需重寫驅動,將原開啟接口全部替換為gsensor_sc7a20_open。這種方式固然效率高,但也導致代碼維護困難,從驅動層到業務層都需要替換接口。而且不能實現軟件自動識別其型號,自動匹配驅動,對項目維護也是較大工作量。

如果改為硬件代理,則可以先封裝函數指針結構體,偽代碼形如

typedef struct
{
*init;
*open;
*close;
}gsensor_ops_t;

gsensor_ops_t bma425;
gsensor_ops_t sc7a20;
gsensor_ops_t* p_gsensor_ops;

所有業務層訪問p_gsensor_ops,至于其究竟是哪一顆傳感器則無需關注,擴展或者更換硬件無需修改業務層。最佳的方案是驅動層可以根據硬件固有差異,如芯片ID或者I2C從機地址,識別出具體硬件型號,自動將p_gsensor_ops指向具體的型號的驅動接口,對軟件版本和生產維護更加友好,不管硬件如何變化,軟件一版即可。

2.3 硬件適配器模式

硬件適配器模式 (Hardware Adapter Patterm) 在兩個接口之間進行轉換,使已經存在硬件接口能適應新的期望。

適配器模式的最直觀應用是手機充電器,市電220V的交流電,但手機只支持5V的直流電,要確保手機正常充電,就是在充電鏈路中增加適配器,將220v的交流轉換為5v的直流。

一般來說具有同一個功能的硬件器件,其接口往往相似,比如前面提到的加速度傳感器,不管是哪個廠商,都是提供I2C或者SPI接口。硬件適配器模式則是在業務層和硬件層之間加入相互轉換,創建適配器提供客戶期望的接口,而不是重寫硬件設備的接口,最少化返工代碼。

在軟件開發中經常有同個物理量,不同硬件的表示數值不同,前面提到的加速度傳感器,因為量程和精度的差異,加速度大小1g的表示值,不同的傳感器xyz三軸數值不同,有的是512表示1g,有的是256表示1g;這樣對業務層的邏輯算法就難以統一標準。所以可以在業務算法和硬件驅動之間,增加適配轉換,統一1g的表示值,這樣才能保證硬件的變化不影響算法。

再比如簡單的例子,將第三方庫移植到不同的平臺,因為參數等信息不完全相同,原來是傳入1-100表示百分比,但新接口是以0.01~1.00表示,則需要在調用接口前轉換兩者關系。所以,硬件適配器模式一般用在硬件器件更換,或者軟件跨平臺移植,它并沒具體的接口套路,是因地制宜,按接口形式轉換。

2.4 中介者模式

中介者模式(Mediator Pattern)是用來降低多個元素之間的通信復雜性,提供一個中介類,協調處理不同類之間的通信,各子類之間不直接通信,松耦合,使代碼易于維護。

比如而二手房交易,有10個買家與10個賣家,如果都直接去溝通對接,每人需要和10人對接,而且信息沒經過過濾,溝通效率低;如果有個中介,所有人都只與中介對接,中介再按買家和賣家意愿,轉達有效意見,買家與賣家無需直接交流,就能促成滿意的交易。每添加新元素就需更新中介者,最終可能導致中介者越發難以維護;如果中介者出現問題,則中介功能包括相關元素程序崩潰,這和房產交易中介卷錢跑路一樣。

圖片

軟件中定義兩種角色分別為合作者和中介者,合作者 (Collaborator) 指所有可能被中介者調用的具體對象,中介者 (Mediaior) 協調多個具體合作者。中介者需要明確每個合作者交互的消息,從哪來,到哪去。當感興趣的事件發生時,合作者可以給中介者發送消息,中介者提供協調邏輯,或者與消息關聯的合作者通信。

中介者與每個具體合作者一般通過多個指針連接,如果具體的合作者的接口一致,指針數組是最好的。兩種角色的結構體定義偽代碼形如下,針對的場景是根據汽車引擎點火acc狀態,加速度傳感器gsensor監測的震動信息,GPS衛星定位獲取運行速度,三組數據組合判斷當前車輛是處于什么狀態。

//中介者管理3個關聯合作者
typedef struct mediator_t
{
colleague_t *acc;
colleague_t *gsensor;
colleague_t *gps;
mediator_relay relay;
}mediator_t;

//每個合作者提供2個接口,向中介者發消息,和接收處理中介者的消息
typedef struct colleague_t
{
mediator_t *m_mediator;
colleague_send send;
colleague_receive receive;
}colleague_t;

合作者發送消息時不明確是誰執行,只管發送;中介者需要識別類型,按既定規則轉發給對應的合作者執行。這也是中介者模式的缺點,中介者代碼龐大,隨著合作者數量的增加會變得復雜難以維護。完整的演示代碼如下。

//微信公眾號:嵌入式系統
#include <stdio.h>

typedef enum
{
EVENT_1,
EVENT_2,
EVENT_3,
EVENT_MAX
}event_t;//模擬測試消息

struct mediator_t;
typedef int (*mediator_relay)(event_t id,void *data,int len);

struct colleague_t;
typedef int (*colleague_send)(event_t id,void *data,int len);
typedef int (*colleague_receive)(event_t id,void *data,int len);

typedef struct mediator_t
{
colleague_t *acc;
colleague_t *gsensor;
colleague_t *gps;
mediator_relay relay;
}mediator_t;

typedef struct colleague_t
{
mediator_t *m_mediator;
colleague_send send;
colleague_receive receive;
}colleague_t;

/*******************************************************/
//合作者接口
static colleague_t colleague_acc={0};
static colleague_t colleague_gsensor={0};
static colleague_t colleague_gps={0};
static int colleague_acc_send(event_t id,void *data,int len)
{
colleague_t *handle=&colleague_acc;
handle->m_mediator->relay(id,data,len);
}

static int colleague_acc_receive(event_t id,void *data,int len)
{
printf("ACC recv id=%d,%s\r\n",id,data);
}

static int colleague_gsensor_send(event_t id,void *data,int len)
{
colleague_t *handle=&colleague_gsensor;
handle->m_mediator->relay(id,data,len);
}

static int colleague_gsensor_receive(event_t id,void *data,int len)
{
printf("gSensor recv id=%d,%s\r\n",id,data);
}

static int colleague_gps_send(event_t id,void *data,int len)
{
colleague_t *handle=&colleague_gps;
handle->m_mediator->relay(id,data,len);
}

static int colleague_gps_receive(event_t id,void *data,int len)
{
printf("GPS recv id=%d,%s\r\n",id,data);
}

/*******************************************************/
//中介者接口
static mediator_t mediator_manager={0};

//中介者協調全局,將對應的事件轉發給有需要的合作者,范例只是說明用法,隨意定義的關系
//這個函數中介者模式維護的重點,也是它的缺點
static int mediator_msg_relay(event_t id,void *data,int len)
{
mediator_t *handle=&mediator_manager;

switch(id)
{
case EVENT_1:
handle->gsensor->receive(id,data,len);
break;
case EVENT_2:
handle->gps->receive(id,data,len);
break;
case EVENT_3:
handle->acc->receive(id,data,len);
break;
default:
break;
}
}

/*******************************************************/
//測試接口
//如果覺得這樣有一定耦合度,可以由中介者提供注冊API給合作者調用,傳入自身地址給中介者
static void init_member(void)
{
colleague_acc.m_mediator=&mediator_manager;
colleague_acc.send=colleague_acc_send;
colleague_acc.receive=colleague_acc_receive;

colleague_gsensor.m_mediator=&mediator_manager;
colleague_gsensor.send=colleague_gsensor_send;
colleague_gsensor.receive=colleague_gsensor_receive;

colleague_gps.m_mediator=&mediator_manager;
colleague_gps.send=colleague_gps_send;
colleague_gps.receive=colleague_gps_receive;

mediator_manager.acc=&colleague_acc;
mediator_manager.gsensor=&colleague_gsensor;
mediator_manager.gps=&colleague_gps;
mediator_manager.relay=mediator_msg_relay;
}

//微信公眾號:嵌入式系統
int main(void)
{
printf("embedded-system\r\n");
init_member();
colleague_acc.send(EVENT_1,(void*)"from acc",0);
colleague_gsensor.send(EVENT_2,(void*)"from gsensor",0);
colleague_gps.send(EVENT_3,(void*)"from gps",0);
return 0;
}

看懂范例才能更好的理解中介者模式的價值。

//微信公眾號:嵌入式系統
//運行結果:
embedded-system
gSensor recv id=0,from acc
GPS recv id=1,from gsensor
ACC recv id=2,from gps

三個關聯合作者互相交互,只處理與自己關聯的事件,對外或者app有問題就找中介,不與具體的合作者通信。

2.5 觀察者模式

觀察者模式提供一種方法來使對象“監聽”其他對象,而不需要修改任何數據服務器。在嵌入式領域,適合傳感器采樣或者某些周期更新的數據,轉發給關注它的元素,比較類似發布--訂閱模式。

好比在紅綠燈路口,交通信號燈由綠變紅,整條車道的車都會收到該信息并進行制動處理。信號燈本身不關注外界,只是按自己的節奏控制燈的變化;而眾多車主觀察到紅燈,都進行停車動作。

一個目標對象的狀態發生改變,所有的依賴對象(觀察者對象)都將得到通知。在嵌入式軟件的實現上,觀察者模式通過在數據生產服務器添加訂閱和取消訂閱,服務器端不需要任何客戶的先驗信息。數據服務器按一定的更新策略,通知對其感興趣的客戶。

軟件上,通知列表最簡單的方式是定義一個足夠大的數組來包含所有潛在的客戶,在有很多客戶的高度動態的系統中這會浪費內存,另一種方案是用鏈表構建一個系統。數據產生服務提供眾多函數指針,有需求的客戶提供自身句柄,一般是回調函數指針;當響應數據變化按既定策略執行回調,實現數據源的變化信息廣播到所有觀察者的效果。

例如設備支持GPS衛星定位,在驅動上報GPS信息的接口,底層提供一個函數指針數組,上層用自身的回調函數填充數組。底層獲取到GPS信息后,查詢數組,若回調函數非空則執行。每個回調函數由各模塊分別實現,代碼整潔,耦合性低。

//微信公眾號:嵌入式系統
#include <string.h>
#include <stdio.h>

#define

typedef unsigned char uint8_t;
typedef void (*gnss_info_callback)(void* data);

typedef struct
{
gnss_info_callback m_cb;
} pal_gnss_subscription_info;

//訂閱池
static pal_gnss_subscription_info g_gnss_subscription_pool[PAL_GNSS_SUBSCRIPTIONS_MAX] = {0};

//訂閱
uint8_t pal_gnss_subscribe(gnss_info_callback callback)
{
uint8_t i;
uint8_t ret=0;

if(callback != NULL)
{
for(i = 0; i < PAL_GNSS_SUBSCRIPTIONS_MAX; i++)
{
if(g_gnss_subscription_pool[i].m_cb == NULL)
{
//RTOS注意競爭
g_gnss_subscription_pool[i].m_cb = callback;
ret = 1;
break;
}
}
}
else
{
ret = 0;
}
return ret;
}

//取消訂閱
void pal_gnss_unsubscribe(gnss_info_callback callback)
{
uint8_t i;

for(i = 0; i < PAL_GNSS_SUBSCRIPTIONS_MAX; i++)
{
if(g_gnss_subscription_pool[i].m_cb == callback)
{
//RTOS注意競爭
g_gnss_subscription_pool[i].m_cb = NULL;
break;
}
}
}

//廣播給觀察者,執行回調
void pal_gnss_info_update(void)
{
uint8_t i;
uint8_t data=1;//test

for(i = 0; i < PAL_GNSS_SUBSCRIPTIONS_MAX; i++)
{
if(g_gnss_subscription_pool[i].m_cb != NULL)
{
//RTOS中使用消息隊列更好,這里只是演示效果
g_gnss_subscription_pool[i].m_cb((void*)&data);
}
}
}

//微信公眾號:嵌入式系統
int main(void)
{
printf("embedded-system\r\n");
return 0;
}

觀察者模式,訂閱-發布機制尤其傳感器采集數據,分發給不同模塊,各模塊收到廣播后按自身需求處理數據的場景。

2.6 消抖過濾模式

這個簡單的模式用于消除來自于金屬表面間歇性連接引起的多個假事件。

按鈕、撥動開關和機電式繼電器等機械式輸入設備,它們都有一個共同的問題,即接觸金屬產生連接,金屬變形或“彈性”在開關轉換時產生間歇連接。從而導致控制系統中有多個電子信號。消抖過濾模式通過在首次檢測到異常信號后,等待一段時間將多個信號減少到一個信號。簡單且常見的場景就是按鍵消抖,這也是嵌入式入門的基礎。

嵌入式系統軟件檢測到首次跳變事件,設置延遲定時器 〈如果需要關閉設備中斷) ,隨后檢查設備狀態。一定時間后(去抖動時間),如果狀態不同,則事件一定是真實的,則發送相應的信息給應用層。因為按鍵防抖屬于嵌入式軟件入門基礎,這里不做詳細描述,重點關注定時器,可以采用CPU延時等待,也可以采用硬件定時實現,后者更合理。

關于按鍵檢測,底層區分按鍵碼和按鍵事件類型(短按、長按、連續按),可以參考 《按鍵檢測》,結合觀察者模式,使用二維數據管理按鍵回調函數,可以實現按鍵檢測驅動與業務的隔離。

2.7 中斷模式

物理世界從根本上來說是并發與異步的,事情該發生時它就會發生,如果嵌入式系統不加以注意,這些事件可能丟失。為了及時監測感興趣的事件,硬件中斷模式,即中斷中斷服務程序是最有效的方法。

中斷模式是一種構造系統的方式,用于對傳入事件作出適當的反應。在嵌入式系統中,事件分為不同等級的緊急度,即使在系統非常繁忙地處理其它事件時也必須處理。在本章其他內容中討論的輪詢模式中,在系統方便的時候查詢感興趣的事件;雖然這是有好處的,不中斷當前正在執行的過程,但它的缺點是高緊急度和高頻率的事件可能得不到及時處理。中斷模式通過立即停止當前的過程,處理傳入事件來解決這個問題,并且隨后返回原來的流程。

通常情況下,當中斷服務程序ISR執行時,關閉中斷,這意味著中斷服務程序必須快速執行以確保不會丟失其他中斷。因為中斷服務程序必須很短,當它們調用其他的系統服務時必須非常小心。如果ISR 處理占用太長時間,在共享資源上出現競爭條件或發生死鎖,問題很難跟蹤。

中斷模式是嵌入式軟件特有的,硬件中斷的特點是響應及時,處理要簡短,尤其是在RTOS中。

2.8 輪詢模式

另一種從硬件獲取傳感器數據或信號的常用模式是定期檢查,稱為輪詢過程。當數據或信號不是非常緊急到不能等待到下一個輪詢時段來收取,或當數據或信號可用時,硬件沒有能力生成中斷(或缺乏中斷檢測口),這時輪詢非常有用。

輪詢分定期或者不定期進行,定期輪詢使用定時器按固定間隔查詢,不定期即機會輪詢是當系統方便的時候才輪詢,沒有固定間隔。

定期輪詢主要用于周期性的變化,或者變化很緩慢的狀態,按合適的間隔定時查詢設備狀態,如果數據或信號輪詢時間加上反應處理時間,比數據更新間隔長,那就必須引起注意,否則數據將會丟失。因為定期輪流,其本身檢查綁定一個定時器中斷,因此定期輪詢模式其實是中斷模式的特殊情況。

不定期輪詢是當系統方便的時候才輪詢,如在主系統功能或在重復執行的周期點之間,在低端單片機上比較常見,對其他系統從事的活動的及時性影響也小。非定期的模式如果時間非常短,也可以嵌套在其它驅動中,諸如死循環循環等待某個狀態,比如查詢UART發送完成,IIC的ACK響應,但是這種循環體一定要注意,必須留有一定會退出循環的條件。

2.9 小結

硬件代理模式關注指定硬件細節的封裝,解決硬件元件更新迭代和多個同類器件的兼容。

而硬件適配器模式為適應不同但是相似的硬件,也解決跨平臺移植。

硬件器件組合工作,或者軟件需求的復雜交互則適合中介者模式。

觀察者模式為硬件數據支持動態添加和刪除客戶,適合多個模塊共享傳感器數據的場景。

消抖過濾模式、中斷模式、輪詢模式用于解決與硬件交互的低層次問題。

軟件模式的選擇,與硬件框架、資源和軟件需求、應用場景相關,合適的才是最好的。

3、并發同步類設計模式

3.1 并發和RTOS概念

基于RTOS的軟件,宏觀上多個任務并行,實際是多任務的分時調度,對應著硬件資源可能就是前任務還未完成訪問,后任務要搶占使用,這切換過程中就存在競爭。若沒有RTOS相關基礎,可以先參考基于《RTOS的軟件開發理論》?    和 《FreeRTOS及其應用,萬字長文,基礎入門》 ,否則本章信息可能無法理解。當任務調度啟動后,所有的任務獨立運行,如何設計避免一個資源被多個任務搶占使用,按串行訪問共享資源?

3.2 臨界區模式

臨界區模式是與任務協調相關的最簡單粗暴的模式。禁止任務在區域內轉換,通過禁用任務轉換甚至禁止中斷來處理競爭關系,保證當前任務不間斷的執行,直到完成相關操作退出臨界區。

臨界區模式結構簡單,受保護的元素是資源而不是任務,在臨界區開始之前禁止任務切換,并在服務結束后重新可用。RTOS提供臨界區進出時的任務切換使能處理,或者直接在硬件級別配置中斷等方式開關中斷處理。

臨界區模式關閉任務調度或者中斷響應,實際會影響其他任務的時序。因此要求臨界區持續時間很短,一般是在同一個任務內使用互斥鎖或者臨界區接口,快速完成相應操作,否則可能導致系統異常。例如有2個任務模塊共享讀寫某一塊內存數據,或者操作某個寄存器,就比較適合臨界區。

3.3 守衛調用模式

守衛調用模式,通過提供的鎖定機制串行訪問,以阻止鎖定后其他線程的調用服務,簡單描述就是A任務占用某個資源后,將其鎖定;優先級高于A的B任務想要使用它,得先咨詢能否使用,如果資源處于鎖定狀態則延時等待(相應的任務阻塞,即使優先級更高),等到前一個任務使用結束,解鎖釋放資源,B任務才能執行。

這里面存在一定問題,如果還有任務C,其優先級介于A和B之間,表面上C會先執行,導致優先級低的C竟然比任務B先執行,即優先級反轉,實際不會這樣。

一般RTOS信號量支持優先級繼承,即任務B使用某個信號量等待A任務時,臨時會將A任務的優先級提高,和B相等,實際執行順序是B-A-C。

通過信號量的獲取和釋放,來獨占的訪問某個硬件或者軟件資源,其對時間沒有太嚴格要求,這種在業務層開發更常見。一般在兩個任務或者任務與中斷間,進行鎖定,確保共享資源按順序使用,也可用于同步交互。

兩個任務同步處理的場景,AT指令的發送任務和接收解析任務適合信號量,發送任務必須等前一AT回復,發出AT后阻塞等待信號量;接收解析任務確認接收完成,釋放信號量;這時發送任務才能退出阻塞,發送下一個AT。

3.3 隊列模式

隊列模式是任務間異步通信最常見的實現,在非耦合的任務間及時通信,通過隊列先進先出的數據結構,發送者將消息存入隊列,接收者從隊列中取出消息。它也提供一種簡單方法串行訪問共享資源,將訪問消息排隊,并且在稍后的時間中處理,這就避免了共享資源常見的相互排斥的問題。

消息隊列使用異步通信,并且不會遇到互斥問題,這是因為沒有引用共享資源。消息隊列以單一的形式避免并發系統中通過傳遞引用共享信息產生的資源損壞的問題。在傳值共享中,制作一個信息的副本,并且發送給接收線程進行處理。接收線程完全擁有收到的數據,并且因此能夠自由修改,而不需要考慮由于多個寫者,或者在一個寫者和多個讀者中共享它們造成信息損壞。其缺點之一是發送者傳遞消息后不能立即處理,需要進程等待,直到接收者任務運行,并且能夠處理正等待的消息。

隊列模式通過對數據和命令排隊串行訪問數據,允許接收者每次處理一個。由于它是異步完成,所以消息發送和處理之間的時間是非耦合的。這可能不滿足系統的性能需求。守衛調用模式也串行訪問,但是同步執行,以便數據和命令傳輸發生在時間上更加接近。但關于信號量的釋放使用出現問題,會導致較嚴重的錯誤。

隊列的最簡單的實現策略是消息元素數組。這具有簡單性的優點,但是缺乏鏈表的靈活性隊列是很容易實現的,但是有很多可能的變體。有時一些消息比其他的更加緊急或者重要,并且應該在等待的低優先級消息之前處理。擴展添加多個緩沖區 (每個優先級一個) 實現優先級修改,或者基于消息優先級 ,但是這樣會很麻煩。

一般還是固定長度的數組隊列,但是可以向隊列頭或者尾插入新數據,這種滿足絕大部分需求,這種情況下需要注意的是接收處理要及時,避免隊列溢出。

例如只有1個UART,通過開關切換分時復用接2個外設,就比較適合隊列模式,讀寫請求緩存到隊列,按序取出執行,避免出現收發數據不完整的問題。

3.4 匯合模式

任務同步發生在簡單的函數調用、共享單一資源或者傳遞數據,可用隊列模式或守衛調用模式,但如果同步需要的條件更加復雜,涉及多個任務間的同步,匯合模式更適合解決任務間復雜形式同步的問題。

在這個模式中,兩個或更多的任務通過操作類似全局變量的位,按變量相應位的狀態執行不同動作。在RTOS內核中,如freeRTOS,這個全局變量叫事件組,其讀寫操作也有相應的API。

例如3個子任務各自監測不同外設,主任務收到3個子任務反饋的外設連接正常的事件,主任務才在UI界面提示所有外設連接正常。

3.5 小結

并發才是嵌入式軟件開發的常態,事情并行發生必須預防競爭與沖突,這也是實時操作系統 (RTOS) 的基本要求。

臨界區模式、守衛調用模式和隊列模式解決在多任務環境下串行訪問資源的問題。臨界區模式在資源訪問期間關閉任務轉換,因此防止可能的資源數據損壞,但是阻塞了更高優先級任務,使它們永遠不能訪問資源。

守衛調用模式通過信號量完成相同的資源保護目標,該模式可能能夠導致優先級倒置,所以該模式需要使用支持優先級繼承的方式。

隊列模式串行訪問資源,通過將請求放在隊列中,并且按照先進先出 (FIFO) 的順序從隊列取出,隊列模式概念上非常簡單,但是導致資源的請求響應延遲,影響時效性。

看起來這些模式很高級,其實主流的實時操作系統,其內核都支持這些模式相關的接口。內核開發的大佬們,早就洞悉了并發的風險與模式,使用內核的互斥鎖、信號量、隊列和事件組,可以很容易的實現這些模式。

如果基于裸機開發,主程序和中斷程序也近似存在共享沖突,可以自定義全局變量、循環數組實現守衛調用模式或隊列模式;其他模式,裸機基本上也用不上。

全文四類設計模式篇幅過長,拆分發布,其他模式稍后。文中提到的RTOS開發相關可閱讀其它文章,并發同步類相關的理論比較重要。

責任編輯:武曉燕 來源: 嵌入式系統
相關推薦

2023-01-04 09:37:16

2023-07-16 22:48:59

2015-05-07 10:10:28

嵌入式設計軟件

2023-11-29 07:51:40

嵌入式軟件設計

2023-04-27 07:06:18

2011-04-18 11:34:34

嵌入式軟件測試

2023-05-04 00:27:40

2023-10-26 09:02:30

框架設計模式

2018-03-12 16:18:31

嵌入式開源

2018-04-08 16:26:48

2010-01-19 09:08:46

嵌入式Windows Emb

2023-01-27 23:46:36

嵌入式軟件技巧

2009-04-11 15:12:24

2012-03-05 15:45:32

嵌入式開源軟件

2022-04-13 09:34:52

軟件開發嵌入式軟件

2011-05-24 17:34:38

嵌入式系統

2009-05-27 19:28:20

Linux磁場設計

2022-01-10 23:43:50

嵌入式軟件開發工具

2009-07-21 08:59:11

嵌入式系統軟件

2011-01-14 13:13:23

嵌入式Linux開發
點贊
收藏

51CTO技術棧公眾號

久久久久久高清| 美女性感视频久久久| 男人操女人免费软件| 男女污污视频在线观看| 日韩中文字幕区一区有砖一区| 亚洲欧美视频在线| 国产成年人视频网站| 黄色一级大片在线免费看产| 风间由美一区二区三区在线观看| 欧美亚洲伦理www| 免费91在线观看| 日本高清精品| 在线亚洲一区观看| 91传媒免费视频| 黄色电影免费在线看| 国产精品123| 国产xxx69麻豆国语对白| 日本免费网站视频| 婷婷国产精品| 欧美一区二区三区日韩视频| 日韩精品一区二区三区久久| 黄色在线播放网站| 久久久精品国产免费观看同学| 国产综合久久久久久| 精品欧美一区二区三区免费观看| 97久久视频| 精品伊人久久97| gogo亚洲国模私拍人体| 日韩不卡视频在线观看| 亚洲高清免费观看| 国产av第一区| 成人在线免费电影| 99国内精品久久| 动漫3d精品一区二区三区| 在线免费av片| 日本中文一区二区三区| 97色在线视频观看| 久久久久久久福利| 中文无码久久精品| 精品国产欧美一区二区五十路 | www在线观看黄色| 亚洲精品视频免费看| 亚洲欧美综合一区| 国产在线色视频| 26uuu久久天堂性欧美| 成人xxxxx色| 国产三级午夜理伦三级| 久久99精品久久久| 国产伦精品免费视频| 波多野结衣电车| 久久一区欧美| 人人澡人人澡人人看欧美| 影音先锋亚洲天堂| 国产欧美高清| 2019亚洲男人天堂| 午夜精品三级久久久有码| 亚洲精品乱码久久久久久蜜桃麻豆| 欧美成人免费播放| 亚洲成人生活片| 一区二区中文| 欧美日韩不卡合集视频| 欧美精品一区二区蜜桃| 欧美体内she精视频在线观看| 欧美人交a欧美精品| 久久久.www| 欧美午夜不卡影院在线观看完整版免费| 久久在线视频在线| 丁香花五月激情| 亚洲精品黄色| 欧美中文字幕第一页| 国产性生活视频| 琪琪一区二区三区| 91在线观看免费高清| av官网在线观看| 成人免费视频网站在线观看| 国产午夜精品在线| 欧美拍拍视频| 中文字幕不卡在线观看| 在线观看视频黄色| 美女网站视频在线| 欧美性xxxxxxx| 黑人粗进入欧美aaaaa| 婷婷久久免费视频| 精品国产乱子伦一区| 我和岳m愉情xxxⅹ视频| 日本不卡高清| 欧美激情亚洲激情| 日本视频免费观看| 黄色精品一二区| 国产精品久久亚洲| 国产视频第一区| 亚洲人精品午夜| 国产精品专区在线| 丁香婷婷久久| 精品国产青草久久久久福利| 91网站免费入口| 亚洲成av人片乱码色午夜| 欧美激情综合色综合啪啪五月| 国产综合精品视频| 国产一区二区在线电影| 国产一区二区精品免费| fc2在线中文字幕| 亚洲午夜影视影院在线观看| 日本黄色三级大片| 国产精品欧美一区二区三区不卡| 欧美精品一区二区三区在线| 久久亚洲无码视频| 极品尤物久久久av免费看| 国产不卡av在线免费观看| 国产黄色片av| 欧美高清在线一区二区| 日韩精品一区在线视频| 97欧美成人| 亚洲国产欧美一区二区丝袜黑人 | 国产精品久久久久影院色老大| 国产在线视频在线| 日韩av一级| 精品国产乱码久久| 日韩在线视频免费看| 美女视频一区免费观看| av蓝导航精品导航| 欧美成人精品一区二区男人看| 欧美日韩一二三四五区| 中文字幕在线观看视频www| 大色综合视频网站在线播放| 午夜精品久久久久久99热| 99热这里只有精品66| 欧美激情在线一区二区| www一区二区www免费| 日本在线一区二区三区| 日韩在线观看免费高清| 国产女主播喷水视频在线观看| 成人免费黄色大片| 最新av网址在线观看| 国产亚洲精彩久久| 亚洲人成伊人成综合网久久久| 久久精品国产亚洲av高清色欲 | 国产精品偷伦视频免费观看了 | 亚洲最大中文字幕| 久草手机在线观看| 成人高清伦理免费影院在线观看| 国产av不卡一区二区| 国精品产品一区| 亚洲一区二区久久久| 日韩精品在线不卡| 成人免费视频caoporn| 欧美图片激情小说| 成人av婷婷| 久久久久久久一区二区| 亚洲高清视频在线播放| 一区二区在线观看视频| 天堂在线精品视频| 欧美高清一区| 99视频在线播放| 日本aa在线| 精品av综合导航| 日韩欧美一区二区一幕| 99久久久精品| 男人揉女人奶房视频60分 | 五月天国产在线| 日韩成人免费视频| 五月婷婷中文字幕| 国产午夜精品福利| 成年人在线观看视频免费| 青青草原综合久久大伊人精品| 国产精品成人aaaaa网站| 国产天堂素人系列在线视频| 欧美三级中文字| 男人的午夜天堂| 国产精品资源网| 免费超爽大片黄| 亚洲综合福利| 国产精品色婷婷视频| 欧美性猛交xxx乱大交3蜜桃| 91精品在线免费| 日韩高清精品免费观看| 久久久久久久久久久99999| 国内自拍视频网| 亚洲成人最新网站| 国产精品视频免费观看| 欧美理论影院| 精品国产一区二区三区久久狼5月 精品国产一区二区三区久久久狼 精品国产一区二区三区久久久 | av中文在线资源| 国产丝袜一区视频在线观看| 国产一级片一区二区| 亚洲欧美视频一区| 精品一区二区视频在线观看| 日韩和欧美的一区| 波多野结衣与黑人| 亚洲三级网页| 91丨九色丨国产在线| 激情黄产视频在线免费观看| 国产一区二区三区视频免费| 国产黄色片免费| 91成人国产精品| www.色小姐com| xnxx国产精品| 亚洲国产欧美91| 国产日韩欧美一区在线| 成人手机视频在线| 免费观看成人www动漫视频| 国产精品久在线观看| 国产经典三级在线| 日韩视频在线一区| 免费福利在线观看| 亚洲精品在线三区| 91久久久久国产一区二区| 午夜电影一区二区三区| 99精品中文字幕| 26uuu色噜噜精品一区| 在线观看免费视频污| 日韩高清在线一区| 久久视频这里有精品| **女人18毛片一区二区| 日本黄网免费一区二区精品| 成人在线视频中文字幕| 国产精品7m视频| 色戒汤唯在线观看| 欧美激情高清视频| 麻豆视频在线观看免费| 亚洲成年人在线播放| 99精品国产99久久久久久97| 欧美影院一区二区| 中日韩精品视频在线观看| 亚洲视频狠狠干| 日本黄区免费视频观看| 久久久久久日产精品| 无码国产精品一区二区免费式直播 | 久久五月情影视| 国产视频网址在线| 亚洲摸下面视频| 日本激情一区二区| 欧美男男青年gay1069videost| 亚洲综合久久网| 亚洲成人黄色影院| 久久高清无码视频| 一区二区三区中文字幕在线观看| 成人午夜免费影院| 国产三级精品视频| 在线免费观看麻豆| 91在线视频18| 娇妻高潮浓精白浆xxⅹ| 国产精品系列在线观看| 肉色超薄丝袜脚交| 国产一区二区看久久| 色www免费视频| 免费久久精品视频| 欧美一级特黄a| 日韩中文欧美在线| 国产免费视频传媒| 人人精品人人爱| 一区二区三区国产免费| 日韩精品福利网| 美女网站色免费| 麻豆精品在线观看| 午夜两性免费视频| 日本成人在线一区| 国产九九在线观看| 久久精品久久综合| 制服丝袜中文字幕第一页| 久久99国产精品免费网站| 手机免费av片| 极品少妇一区二区| 992tv人人草| 成人精品国产免费网站| 国产美女视频免费观看下载软件| 99re热视频精品| 丰满少妇一区二区| 国产欧美综合色| 91麻豆精品久久毛片一级| 亚洲色图欧洲色图婷婷| 免费中文字幕视频| 黄色一区二区三区| 波多野结衣理论片| 欧美高清视频一二三区| av小说天堂网| 日韩精品免费电影| 北岛玲一区二区三区| 久久久av一区| 黄色污网站在线观看| 国产精品h片在线播放| 免费日韩成人| 国产精品毛片一区视频| 亚洲人亚洲人色久| 亚洲一区三区| 国产一区激情| 免费在线观看的av网站| 久草热8精品视频在线观看| 最好看的中文字幕| 久久一夜天堂av一区二区三区| 中文字幕在线观看免费高清| 亚洲美女偷拍久久| 精品成人av一区二区在线播放| 欧美日韩美少妇| 国精产品一品二品国精品69xx | 国产精品网站大全| 91精品尤物| 欧美综合激情| 欧美精品不卡| 成人免费视频久久| 国产成人啪免费观看软件| 在线 丝袜 欧美 日韩 制服| 中文字幕制服丝袜一区二区三区| 久青草免费视频| 欧美日韩精品欧美日韩精品 | 日韩精品欧美国产精品忘忧草 | 亚洲图片小说视频| 亚洲第一区第一页| 麻豆网站在线| 国产精品第二页| 51亚洲精品| 亚洲高清在线播放| 99国产一区| 天天av天天操| 欧美激情中文字幕一区二区| 久久艹免费视频| 日韩免费性生活视频播放| www.亚洲免费| 国产91在线播放| 欧美大片网址| 国产女教师bbwbbwbbw| 蜜臀va亚洲va欧美va天堂| 国产伦精品一区三区精东| 亚洲品质自拍视频网站| 国产情侣小视频| 亚洲毛片在线免费观看| 欧美日韩在线视频免费观看| 国产一区二区香蕉| 国产一区日韩| 日韩精品视频一区二区在线观看| 国产黑丝在线一区二区三区| 色婷婷国产精品免| 色婷婷综合久久久中文一区二区| 国内爆初菊对白视频| 欧美老少配视频| 国产精品视频一区二区三区综合 | 国产精品99蜜臀久久不卡二区| 欧美精品国产白浆久久久久| 精品人妻大屁股白浆无码| 国产精品一区二区久久不卡| 欧美一级特黄高清视频| 欧美日韩一级片在线观看| 成人高清免费观看mv| 国产精品久久久久91| 北条麻妃国产九九九精品小说| 亚洲熟妇av一区二区三区| heyzo一本久久综合| 久久精品国产亚洲av无码娇色| 精品国产污网站| 大菠萝精品导航| 久久国产精品 国产精品| 日韩亚洲在线| 91久久免费视频| 91久久国产综合久久| 成人免费高清在线播放| 国产精品一二三视频| 99视频精品全国免费| 午夜免费福利网站| 亚洲男人都懂的| www.五月婷婷| 91精品国产乱码久久久久久久久 | 亚洲日本精品国产第一区| 蜜臀av一级做a爰片久久| 亚洲区一区二区三| 欧美一区二区三区人| 黄色污污视频在线观看| 国产精品日韩高清| 先锋亚洲精品| 亚洲熟女少妇一区二区| 欧美一区午夜视频在线观看| 视频在线观看入口黄最新永久免费国产| 成人资源av| 国产精品久久国产愉拍| 好吊视频在线观看| 欧美日韩国产区一| 日本小视频在线免费观看| 精品国产乱码久久久久| 日韩综合小视频| 久久国产精品国语对白| 欧美精品一区在线观看| se69色成人网wwwsex| 97超碰人人爱| 成人午夜在线免费| 波多野结衣在线观看一区| 久久影视免费观看| 丝袜美腿一区二区三区动态图| 中文字幕第80页| 亚洲精品国产品国语在线app| 成人毛片在线免费观看| 国产精品吹潮在线观看| 一区二区日韩欧美| 国产精品揄拍100视频| 3atv一区二区三区| 麻豆免费版在线观看| 性欧美videosex高清少妇| 国产999精品久久久久久| 日韩中文字幕高清| 欧美激情2020午夜免费观看| 欧美极品在线观看| 91亚洲一线产区二线产区|