在現(xiàn)代開(kāi)發(fā)周期中使用傳感器時(shí),重要的是在編寫(xiě)任何傳感器代碼之前,開(kāi)發(fā)人員花時(shí)間仔細(xì)考慮他們的系統(tǒng)架構(gòu)。精心架構(gòu)的應(yīng)用程序?qū)⑻峁┸浖?a target="_blank">接口,不僅提供與傳感器交互的通用方法,而且還將抽象這些傳感器的硬件細(xì)節(jié)。許多嵌入式開(kāi)發(fā)人員仍在編寫(xiě)代碼,將他們的傳感器代碼與他們的應(yīng)用程序緊密耦合,這使得重用、擴(kuò)展和測(cè)試軟件變得具有挑戰(zhàn)性。開(kāi)發(fā)人員可以遵循的一個(gè)很好的最佳實(shí)踐是花時(shí)間在他們的架構(gòu)中設(shè)計(jì)一個(gè)合適的接口,然后產(chǎn)生這些好處。在我之前的帖子中,我討論了不同類型的驅(qū)動(dòng)程序。在這篇文章中,我將討論接口設(shè)計(jì)概念以及如何將它們應(yīng)用于與傳感器的接口。
創(chuàng)建接口的好處
使用面向?qū)ο笳Z(yǔ)言的開(kāi)發(fā)人員自然會(huì)理解接口可以為應(yīng)用程序提供的好處,但大多數(shù)嵌入式系統(tǒng)仍然使用 C 編寫(xiě),因此這些開(kāi)發(fā)人員可能會(huì)忽略這些好處。在嵌入式系統(tǒng)中創(chuàng)建與 I/O 設(shè)備交互的接口有很多好處,例如:
- 反轉(zhuǎn)代碼依賴方向
- 增強(qiáng)便攜性
- 抽象的復(fù)雜性和低級(jí)細(xì)節(jié)
- 提高重用性和可擴(kuò)展性
- 簡(jiǎn)化軟件維護(hù)
當(dāng)使用接口與傳感器交互時(shí),開(kāi)發(fā)人員會(huì)發(fā)現(xiàn)許多低級(jí)細(xì)節(jié)都是從高級(jí)應(yīng)用程序中抽象出來(lái)的。這意味著應(yīng)用程序不知道傳感器是否連接到 ADC、I2C 總線、SPI 總線或其他一些硬件接口。
例如,花點(diǎn)時(shí)間看一下下圖:

傳感器接口中的抽象(來(lái)源:Jacob Beningo)
在此示例中,應(yīng)用程序通過(guò)傳感器 API 進(jìn)行調(diào)用,并使用其操作之一與傳感器進(jìn)行交互。應(yīng)用程序不知道 Sensor API 的幕后發(fā)生了什么,它可能有函數(shù)調(diào)用,例如:
該傳感器接口可能正在直接調(diào)用 ADC 外圍設(shè)備,或者它可能正在創(chuàng)建從通信外圍設(shè)備發(fā)送出去的消息包。界面的好處是應(yīng)用程序開(kāi)發(fā)人員不需要知道這些細(xì)節(jié)。(事實(shí)上??,接口層可能只是取消對(duì)已配置為指向正確模塊以處理傳感器通信的函數(shù)指針的引用!這在我們的 C 應(yīng)用程序中提供了一種簡(jiǎn)單的繼承形式。)
設(shè)計(jì)傳感器接口
有興趣創(chuàng)建良好、可重復(fù)使用的傳感器接口的開(kāi)發(fā)人員應(yīng)該遵循幾個(gè)步驟。這些步驟有助于確保界面在第一次交互時(shí)盡可能可用,即使在界面完全穩(wěn)定之前可能需要多次迭代。
第一步是確定將在您將設(shè)計(jì)的嵌入式系統(tǒng)中使用的傳感器類型,然后檢查數(shù)據(jù)表。在此步驟中,您希望熟悉所有不同傳感器類型之間共有的操作和數(shù)據(jù),以及哪些不常見(jiàn)。您會(huì)發(fā)現(xiàn),即使跨不同類型的傳感器,操作和數(shù)據(jù)之間也始終存在共性。我們希望將這種共性構(gòu)建到界面中。我們將不常見(jiàn)的操作和數(shù)據(jù)構(gòu)建到該接口的擴(kuò)展中,這允許我們根據(jù)正在開(kāi)發(fā)的應(yīng)用程序添加和刪除這些功能。
接下來(lái),一旦我們確定了操作和數(shù)據(jù),我們就可以用 C 語(yǔ)言勾勒出一個(gè)可以滿足我們傳感器需求的接口。該接口的復(fù)雜性完全取決于開(kāi)發(fā)人員。例如,我們可以設(shè)計(jì)一個(gè)簡(jiǎn)單的基于函數(shù)調(diào)用的接口,其中函數(shù)原型可能如下所示:
bool Sensor_Init(const SensorConfig_t * const Config);
bool Sensor_Read(const SensorObj_t * const, SensorData_t * const SensorData);
bool Sensor_Write(const SensorObj_t * const, SensorData_t * const SensorData);
在這種情況下,對(duì)接口的任何調(diào)用都會(huì)返回一個(gè)布爾值,該布爾值提供有關(guān)操作結(jié)果的信息。例如,我們可能會(huì)調(diào)用Sensor_Read,如果底層實(shí)現(xiàn)是輪詢?cè)O(shè)備以獲取傳感器數(shù)據(jù)就緒,那么如果沒(méi)有新數(shù)據(jù),我們可能會(huì)返回 false。如果數(shù)據(jù)可用,則可能會(huì)將其復(fù)制到提供給接口的SensorData位置并返回 true。(我們當(dāng)然可以變得更復(fù)雜并創(chuàng)建錯(cuò)誤代碼和其他返回值,但我們應(yīng)該從簡(jiǎn)單開(kāi)始)。
該接口可用于與任意數(shù)量的傳感器進(jìn)行交互,我們只需將SensorObj信息傳遞給接口,然后讓接口完成我們需要完成的操作即可。我們也可以將其用作模板并為傳感器名稱重命名Sensor,盡管這開(kāi)始最小化抽象的有用性和可重用性。
我們可以設(shè)計(jì)接口的最后一種有趣的方式是成為函數(shù)指針的結(jié)構(gòu)。然后,開(kāi)發(fā)人員將實(shí)例化該結(jié)構(gòu)并使用與他們想要連接的傳感器相關(guān)的特定函數(shù)調(diào)用對(duì)其進(jìn)行初始化。此實(shí)現(xiàn)可能如下所示:
typedef struct
{
bool ( Init)(const SensorConfig_t * const Config);
bool ( Read)(const SensorObj_t * const, SensorData_t * const SensorData);
bool (*Write)(const SensorObj_t * const, SensorData_t * const SensorData);
} 傳感器_t;
然后,我們可以通過(guò)簡(jiǎn)單地創(chuàng)建和初始化這個(gè)結(jié)構(gòu)來(lái)為多個(gè)傳感器使用相同的接口,例如:
常量 Sensor_t 模擬 =
{
Adc_Init,
Adc_Read,
Adc_Write
};
常量 Sensor_t Gyro =
{
Gyro_Init,
Gyro_Read,
Gyro_Write
};
調(diào)用傳感器的接口然后看起來(lái)像:
模擬.Init(AdcConfig);
Gryo.Init(GyroConfig);
正如你所看到的,這種類型的接口是非常可擴(kuò)展和可重用的。這可能會(huì)讓一些開(kāi)發(fā)人員感到緊張,因?yàn)樗_實(shí)使用了函數(shù)指針。必須注意確保這些函數(shù)指針正常運(yùn)行。
結(jié)論
將傳感器連接到嵌入式系統(tǒng)時(shí),自然的本能是檢查該傳感器,然后開(kāi)始為其編寫(xiě)驅(qū)動(dòng)程序。不幸的是,這導(dǎo)致軟件緊密耦合并且不具有可擴(kuò)展或可重用的優(yōu)點(diǎn)。正如我們?cè)谶@篇文章中所看到的,我們應(yīng)該首先關(guān)注我們的軟件架構(gòu)以及我們的傳感器如何適應(yīng)該架構(gòu)。然后我們可以開(kāi)發(fā)一個(gè)接口來(lái)抽象出我們傳感器的細(xì)節(jié),這樣應(yīng)用程序就不會(huì)意識(shí)到復(fù)雜性或低級(jí)細(xì)節(jié)。這樣一來(lái),如果在設(shè)計(jì)周期后期發(fā)現(xiàn)傳感器不適合應(yīng)用程序,則可以輕松更換傳感器,而無(wú)需修改核心應(yīng)用程序代碼。
審核編輯 黃昊宇
-
傳感器
+關(guān)注
關(guān)注
2563文章
52589瀏覽量
763749 -
接口設(shè)計(jì)
+關(guān)注
關(guān)注
2文章
197瀏覽量
30198
發(fā)布評(píng)論請(qǐng)先 登錄
傳感器有哪些類型?有哪些接口?
可以通過(guò) slavefifo 接口建立 FX3 和傳感器通信嗎?
EE-358:紅色/透明傳感器與ADSP-BF609 Blackfin處理器接口

從RF到HDMI:傳統(tǒng)接口的現(xiàn)代優(yōu)化

VGA接口在現(xiàn)代設(shè)備中的應(yīng)用
使用MSP430掃描接口和光學(xué)傳感器進(jìn)行旋轉(zhuǎn)和線性運(yùn)動(dòng)檢測(cè)

使用原始捕捉模式將CMOS傳感器與TMS320DM642接口

使用MSP430擴(kuò)展掃描接口(ESI)進(jìn)行LC傳感器旋轉(zhuǎn)檢測(cè)

TPIC8101爆震傳感器接口技術(shù)簡(jiǎn)介

LM82帶雙線串行接口的數(shù)字溫度傳感器數(shù)據(jù)表

配備 SMAART Wire? 接口的 TMP104 低功耗數(shù)字溫度傳感器數(shù)據(jù)表

TMP106 雙線接口數(shù)字溫度傳感器數(shù)據(jù)表

振動(dòng)電阻式傳感器測(cè)量模塊的傳感器接口

評(píng)論