加入星計劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
  • 推薦器件
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

嵌入式軟件為啥要進(jìn)行模塊化設(shè)計?

07/15 12:20
1270
閱讀需 8 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

我是老溫,一名熱愛學(xué)習(xí)的嵌入式工程師,關(guān)注我,一起變得更加優(yōu)秀!

在如今的嵌入式軟硬件技術(shù)開發(fā)領(lǐng)域,幾乎每一位工程師都會大談模塊化設(shè)計,硬件工程師在設(shè)計原理圖的時候,電源要模塊化,核心板要模塊化,功能電路要模塊化。軟件工程師在coding的時候,CPU初始化要模塊化,IIC代碼要模塊化,RTC代碼要模塊化,等等。

于是,當(dāng)大家對模塊化設(shè)計的概念和思想有了普遍共識后,我們在寫單片機(jī)代碼的時候,(大多數(shù)工程師極有可能)是以下面這種代碼形式去組織產(chǎn)品的功能模塊代碼。

void main(void){    gpio_init();    //初始化GPIO    iic_init();    //初始化IIC總線    rtc_init();    //初始化RTC        while(1)    {        function_code_1();    //功能代碼1        function_code_2();    //功能代碼2????????function_code_3();    //功能代碼3    }}

這看上去似乎是非常合情合理合邏輯的,先把需要用到的硬件接口都初始化完成,然后在 while(1) 循環(huán)里面不斷地輪詢,處理我們的業(yè)務(wù)邏輯。

關(guān)于源代碼文件的存放,可能是 iic.c 和 iic.h ,gpio.c 和 gpio.h 都放在MCU的外設(shè)驅(qū)動文件夾,功能模塊源代碼放在另一個文件夾。

(幾乎所有的單片機(jī)入門教程都是這么教我們的,外設(shè)驅(qū)動放一塊,業(yè)務(wù)邏輯放一塊,這看上去很模塊化呀,沒啥毛病~)

然而,當(dāng)我們對這個世界的客觀事物理解越來越深刻的時候,才發(fā)現(xiàn)這個世界的大多數(shù)事物,都是以“模塊”的形式存在著。

我是一個模塊(職場嗎嘍),給公司當(dāng)牛馬;公司是一個模塊,給行業(yè)提供解決方案或產(chǎn)品;行業(yè)是一個模塊,給產(chǎn)業(yè)鏈提供完善的行業(yè)支持;產(chǎn)業(yè)鏈?zhǔn)且粋€模塊,給社會主義經(jīng)濟(jì)建設(shè)提供可靠的資源支撐;社會主義是。。。扯遠(yuǎn)了:)

于是,我們上面的單片機(jī)偽代碼,比如它是一個給廣州塔按時點亮流水燈的控制器產(chǎn)品,用模塊化的思想就可以優(yōu)化為以下的形式;

void main(void){????light_module_init();????//燈光模塊,里面包含GPIO接口初始化????storage_module_init();??//存儲模塊,里面包含IIC初始化,存儲設(shè)備初始化????clock_module_init();????//時鐘模塊,里面包含RTC額初始化。        while(1)    {????????light_module.handler();??//處理燈光模塊的邏輯,比如定時點燈????????storage_module.handler();??//處理存儲器邏輯,比如定時保存配置數(shù)據(jù)????????clock_module.handler();????//處理時鐘或鬧鐘,比如發(fā)出定時或計時信號    }}

從以上代碼可以看出,我們把MCU外設(shè)驅(qū)動的初始化,放在模塊的初始化函數(shù)里面進(jìn)行處理了,主循環(huán)while(1)里面也是調(diào)用了模塊提供的事務(wù)處理函數(shù)。各個模塊分工明確,只掃自家門前雪,不管他人瓦上霜。

模塊之間可以通過約定的接口進(jìn)行數(shù)據(jù)的交互和通信,并且嚴(yán)格禁止跨模塊使用全局變量,模塊的接口頭文件禁止放入 “extern xxx變量” 的代碼,一旦放入這種代碼,大概率是會被下一位接坑者“友好問候”的?。

模塊化之后,事情一下子變得簡單起來了,當(dāng)我們發(fā)現(xiàn)塔上的燈不亮了,就去檢查一下 light_module 和電源總閘唄,當(dāng)我們發(fā)現(xiàn)定時時間不準(zhǔn)了,就去檢查一下時鐘模塊唄。懷疑硬件驅(qū)動有問題的,就去看看 xxx_module_init 的代碼,懷疑業(yè)務(wù)邏輯的,就去看看 xxx_module_handler 代碼。

模塊化設(shè)計是嵌入式系統(tǒng)設(shè)計中的一種重要方法論,但通常這種方法論描述得過于抽象,難以理解,以下是模塊化設(shè)計的核心哲學(xué)思想,我們可以嘗試通俗地理解這些思想背后的目標(biāo)。

1、高內(nèi)聚、低耦合、接口明確

模塊內(nèi)部的各個變量各個函數(shù),都給咱統(tǒng)一管理起來,不對外的函數(shù)要static,不想讓模塊使用者知道的內(nèi)容,就不要放在接口頭文件,對外接口要規(guī)范,提供明確的接口使用指導(dǎo)。

2、可重用性、可擴(kuò)展性、可維護(hù)性

模塊源碼被使用時,可以輕松復(fù)制粘貼,模塊使用者只需遵循接口規(guī)范,通過正確的輸入即可獲得正確的輸出。模塊作者給模塊擴(kuò)展功能時,不需要重寫所有代碼。模塊設(shè)計者在維護(hù)模塊某個功能時,只需專注某個局部,而不是模塊全局。

3、單一職責(zé)原則

一個模塊只負(fù)責(zé)一項任務(wù)(或者一項功能),其他不屬于自己分內(nèi)的事情,就別管了(也管不了),各家只掃門前雪就行了!

4、分層架構(gòu)、配置管理

模塊化的內(nèi)在設(shè)計可以采用分層架構(gòu),每一層負(fù)責(zé)處理不同的抽象級別。也就是說,模塊內(nèi)部之間也要有層次感,模塊內(nèi)部也不是一鍋亂燉的東西,最起碼的層次階級還是要有的,并且還要提供適當(dāng)?shù)呐渲梦募ɑ驍?shù)據(jù)結(jié)構(gòu))來控制模塊的功能與行為。

5、測試與驗證

哪里出問題了,直接找出問題的模塊就行,電源出問題了,一開始該不會去懷疑網(wǎng)絡(luò)通信不了而導(dǎo)致電源出問題吧?!模塊化設(shè)計的軟件,使得對單個模塊進(jìn)行測試驗證或者找問題變得更加容易,有助于提高軟件整體質(zhì)量。

通過遵循這些設(shè)計哲學(xué),嵌入式軟件的開發(fā)可以更加高效,最后,需要補(bǔ)充的一點就是,如果產(chǎn)品的功能邏輯肉眼可見的簡單,就不用扯啥模塊化了,用最直接簡單粗暴的方式來操作硬件,完成功能開發(fā),怎么方便怎么來,別整啥模塊化給自己制造麻煩了。

模塊化思想,是適用于對中大型的產(chǎn)品業(yè)務(wù)軟件進(jìn)行規(guī)劃設(shè)計的,并不具備普適性用途,也不是放之四海而皆準(zhǔn)的真理,工程師們還是需要具體問題具體分析,按需使用。

 

推薦器件

更多器件
器件型號 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊 ECAD模型 風(fēng)險等級 參考價格 更多信息
EPCQ64ASI16N 1 Intel Corporation Memory Circuit, 8MX8, CMOS, PDSO16, SOIC-16

ECAD模型

下載ECAD模型
暫無數(shù)據(jù) 查看
AQY282S 1 Panasonic Electronic Components Solid State Relay,
$1.69 查看
ABM3C-25.000MHZ-D4Y-T 1 Abracon Corporation CRYSTAL 25.0000MHZ 18PF SMD

ECAD模型

下載ECAD模型
$2.57 查看

相關(guān)推薦

電子產(chǎn)業(yè)圖譜