一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

嵌入式軟件分層框架的優(yōu)劣

lilihe92 ? 來源:Silent Knight ? 作者:Silent Knight ? 2023-02-21 09:45 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

正文

前言

為了能夠使得產(chǎn)品得到更好的開發(fā)速度與以后更好的迭代和移植,框架分層是很有必要的。但如對于中小型項(xiàng)目嚴(yán)格遵循這些原則,勢必會消耗過多精力去思考怎么設(shè)計(jì)系統(tǒng),這是一個(gè)抉擇的過程。

一、框架分層是什么?

嵌入式架構(gòu)中:一般分為硬件架構(gòu)與軟件架構(gòu)。這里是嵌入式軟件設(shè)計(jì),也是大多數(shù)人接觸的設(shè)計(jì)。

所謂的分層,也可以理解為模塊化的設(shè)計(jì),但是框架分層的設(shè)計(jì)一般會遵循以下幾點(diǎn)原則

每個(gè)模塊提供的接口要統(tǒng)一,只能增加,不能改。在設(shè)計(jì)的時(shí)候得考慮好兼容性,使用起來麻煩不麻煩等等。

同一級模塊與模塊之間相互獨(dú)立,互不影響,不能相互調(diào)用,只能調(diào)用它下一層的接口。

不同模塊構(gòu)成不同的層,層與層之間不能跨級調(diào)用。

模塊中又可以繼續(xù)分層,可以增減分層,這個(gè)需要根據(jù)自己的項(xiàng)目需求來進(jìn)行設(shè)置。

一般可以分為:硬件驅(qū)動層–>功能模塊層–>應(yīng)用接口層–>業(yè)務(wù)邏輯層–>應(yīng)用層

讓我們看看這個(gè)經(jīng)典的圖,簡單了解一下框架分層。

ff0d5af4-b130-11ed-bfe3-dac502259ad0.png

從圖中不難觀察出,設(shè)計(jì)都是遵循設(shè)計(jì)的原則的,層與層之間不能相互調(diào)用。

二、框架分層的優(yōu)劣勢

1.優(yōu)勢

單一職責(zé):每一層只負(fù)責(zé)一個(gè)職責(zé),職責(zé)邊界清晰,不會造成跨級調(diào)用,在大型項(xiàng)目中,每個(gè)人負(fù)責(zé)的部分不一樣,加快整個(gè)項(xiàng)目的開發(fā)進(jìn)度。

高內(nèi)聚:分層是把相同的職責(zé)放在同一個(gè)層中,所有業(yè)務(wù)邏輯內(nèi)聚在領(lǐng)域?qū)印T跍y試的時(shí)候,只需要測試該領(lǐng)域的層即可,一般不需要考慮其他層的問題。

耦合:依賴關(guān)系非常簡單,上層只能依賴于下層,沒有循環(huán)依賴。

易維護(hù):面對變更容易修改。在平臺更改后,如果只是改了驅(qū)動,其他層都不需要動,只需要把驅(qū)動層給更改,其他層的功能不需要更改。

易復(fù)用:如果功能模塊變動了,只需升級相應(yīng)的功能模塊,其他的模塊不受影響,應(yīng)用層也不受影響。

如果想要更好地利用這些優(yōu)勢,那得嚴(yán)格遵循設(shè)計(jì)的原則。

2.劣勢

開發(fā)成本高:因?yàn)槎鄬臃謩e承擔(dān)各自的職責(zé),增加功能需要在多個(gè)層增加代碼,這樣難免會增加開發(fā)成本。但是合理的抽象,根據(jù)自己的項(xiàng)目設(shè)置合理的層級是能降低開發(fā)成本的。

性能略低:業(yè)務(wù)流需要經(jīng)過多層代碼的處理,性能會有所消耗。

可擴(kuò)展性低:因?yàn)樯舷聦又g存在耦合度,有些功能變化可能涉及到多層的修改。

有優(yōu)勢也有劣勢,需要根據(jù)自己的項(xiàng)目需要,進(jìn)行部分的取舍,如果是中小型項(xiàng)目,可以不需要分層(如果不考慮到以后會迭代的話),或者部分分層就夠了,既能利用框架分層的部分優(yōu)勢,也能降低開發(fā)成本。

三、一個(gè)簡單的例子

由于主要討論的是軟件框架的分層設(shè)計(jì),這里使用STM32cubemx來進(jìn)行硬件的初始化,盡可能少考慮到硬件驅(qū)動的部分。

以一個(gè)智能小燈的作為例子:

功能

按鍵控制小燈的亮度,等級為:0,1,2,3

串口可以觀察當(dāng)前小燈亮度等級

OLED也可以觀察當(dāng)前小燈亮度等級

下面就是這個(gè)例子的一個(gè)簡單的圖示。

這和例子比較簡單,業(yè)務(wù)邏輯層完全可以去除,直接從應(yīng)用層調(diào)用功能模塊層,加快開發(fā)進(jìn)度。

006244e6-b131-11ed-bfe3-dac502259ad0.png

最后附上一點(diǎn)點(diǎn)代碼,就是關(guān)于LED如何進(jìn)行在不同層進(jìn)行封裝

硬件層

首先看HAL庫生成提供的代碼,這個(gè)就是LED硬件層,也就是GPIO層,cubemx已經(jīng)生成了,在stm32f4xx_hal_gpio.c(我用的是F4),以及有相應(yīng)的GPIO的驅(qū)動了,這里不需要我們進(jìn)行處理。

009bda08-b131-11ed-bfe3-dac502259ad0.png

硬件層驅(qū)動層

看LED部分的驅(qū)動,也就是下面的這兩個(gè)函數(shù)

voidMX_TIM1_Init(void);
voidHAL_TIM_MspPostInit(TIM_HandleTypeDef*timHandle);
12
/*TIM1initfunction*/
voidMX_TIM1_Init(void)
{

/*USERCODEBEGINTIM1_Init0*/

/*USERCODEENDTIM1_Init0*/

TIM_ClockConfigTypeDefsClockSourceConfig={0};
TIM_MasterConfigTypeDefsMasterConfig={0};
TIM_OC_InitTypeDefsConfigOC={0};
TIM_BreakDeadTimeConfigTypeDefsBreakDeadTimeConfig={0};

/*USERCODEBEGINTIM1_Init1*/

/*USERCODEENDTIM1_Init1*/
htim1.Instance=TIM1;
htim1.Init.Prescaler=168-1;
htim1.Init.CounterMode=TIM_COUNTERMODE_UP;
htim1.Init.Period=10000;
htim1.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter=0;
htim1.Init.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_ENABLE;
if(HAL_TIM_Base_Init(&htim1)!=HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource=TIM_CLOCKSOURCE_INTERNAL;
if(HAL_TIM_ConfigClockSource(&htim1,&sClockSourceConfig)!=HAL_OK)
{
Error_Handler();
}
if(HAL_TIM_PWM_Init(&htim1)!=HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger=TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode=TIM_MASTERSLAVEMODE_DISABLE;
if(HAL_TIMEx_MasterConfigSynchronization(&htim1,&sMasterConfig)!=HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode=TIM_OCMODE_PWM1;
sConfigOC.Pulse=0;
sConfigOC.OCPolarity=TIM_OCPOLARITY_HIGH;
sConfigOC.OCNPolarity=TIM_OCNPOLARITY_HIGH;
sConfigOC.OCFastMode=TIM_OCFAST_DISABLE;
sConfigOC.OCIdleState=TIM_OCIDLESTATE_RESET;
sConfigOC.OCNIdleState=TIM_OCNIDLESTATE_RESET;
if(HAL_TIM_PWM_ConfigChannel(&htim1,&sConfigOC,TIM_CHANNEL_2)!=HAL_OK)
{
Error_Handler();
}
sBreakDeadTimeConfig.OffStateRunMode=TIM_OSSR_DISABLE;
sBreakDeadTimeConfig.OffStateIDLEMode=TIM_OSSI_DISABLE;
sBreakDeadTimeConfig.LockLevel=TIM_LOCKLEVEL_OFF;
sBreakDeadTimeConfig.DeadTime=0;
sBreakDeadTimeConfig.BreakState=TIM_BREAK_DISABLE;
sBreakDeadTimeConfig.BreakPolarity=TIM_BREAKPOLARITY_HIGH;
sBreakDeadTimeConfig.AutomaticOutput=TIM_AUTOMATICOUTPUT_DISABLE;
if(HAL_TIMEx_ConfigBreakDeadTime(&htim1,&sBreakDeadTimeConfig)!=HAL_OK)
{
Error_Handler();
}
/*USERCODEBEGINTIM1_Init2*/

/*USERCODEENDTIM1_Init2*/
HAL_TIM_MspPostInit(&htim1);

}

voidHAL_TIM_MspPostInit(TIM_HandleTypeDef*timHandle)
{

GPIO_InitTypeDefGPIO_InitStruct={0};
if(timHandle->Instance==TIM1)
{
/*USERCODEBEGINTIM1_MspPostInit0*/

/*USERCODEENDTIM1_MspPostInit0*/

__HAL_RCC_GPIOE_CLK_ENABLE();
/**TIM1GPIOConfiguration
PE11------>TIM1_CH2
*/
GPIO_InitStruct.Pin=GPIO_PIN_11;
GPIO_InitStruct.Mode=GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull=GPIO_NOPULL;
GPIO_InitStruct.Speed=GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate=GPIO_AF1_TIM1;
HAL_GPIO_Init(GPIOE,&GPIO_InitStruct);

/*USERCODEBEGINTIM1_MspPostInit1*/

/*USERCODEENDTIM1_MspPostInit1*/
}

}
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798

對其進(jìn)行封裝,就是我們想要的Led小燈的驅(qū)動了,到時(shí)候如果需要,改驅(qū)動直接改底層就行了。

voidLed_init()
{
MX_TIM1_Init();
HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_2);//啟動PWM
}
12345

功能模塊層

根據(jù)上面的需求要求劃分為四個(gè)不同等級,同時(shí)也需要對LED驅(qū)動進(jìn)行進(jìn)一步封裝,以便滿足層與層之間不能跨級調(diào)用的原則(到這里是不是發(fā)現(xiàn)很麻煩!小項(xiàng)目就不要用啦!)

//ARR計(jì)數(shù)器設(shè)置值為0~10000
#defineLED_GRADE_00
#defineLED_GRADE_13000
#defineLED_GRADE_26000
#defineLED_GRADE_310000
//設(shè)置LED亮度功能
voidLed_Set_brightness(intGrade)
{
if(Grade==LED_GRADE_0)
{
__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_2,Grade);
HAL_TIM_PWM_Stop(&htim1,TIM_CHANNEL_2);//關(guān)閉PWM輸出
}
else
{
HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_2,Grade);
__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_2,Grade);
}
}

//啟動LED功能
voidLed_Start()
{
Led_init();
}
12345678910111213141516171819202122232425

業(yè)務(wù)邏輯層

這里僅僅以啟動層為例:

voidStart_app()
{
Led_Start();
}
1234

應(yīng)用層

基本流程是:啟動業(yè)務(wù)邏輯->讀取業(yè)務(wù)邏輯->處理業(yè)務(wù)邏輯->顯示業(yè)務(wù)邏輯。

四、總結(jié)

到這里,一個(gè)簡單的例子也解釋完畢了,通過LED這個(gè)簡單的例子,已經(jīng)大概了解到這個(gè)設(shè)計(jì)的復(fù)雜了,如果是大型項(xiàng)目,運(yùn)用起來會很爽,小型的話完全沒必要這樣分層,太麻煩了,嚴(yán)重減慢開發(fā)效率,時(shí)間都用在思考如何進(jìn)行分層才能符合框架分層的原則。

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • led
    led
    +關(guān)注

    關(guān)注

    242

    文章

    23794

    瀏覽量

    672567
  • 嵌入式
    +關(guān)注

    關(guān)注

    5146

    文章

    19599

    瀏覽量

    316310
  • 嵌入式軟件
    +關(guān)注

    關(guān)注

    4

    文章

    245

    瀏覽量

    27247
  • 架構(gòu)
    +關(guān)注

    關(guān)注

    1

    文章

    528

    瀏覽量

    25927
  • stm32cubemx
    +關(guān)注

    關(guān)注

    5

    文章

    286

    瀏覽量

    16109

原文標(biāo)題:嵌入式軟件分層框架的優(yōu)劣

文章出處:【微信號:最后一個(gè)bug,微信公眾號:最后一個(gè)bug】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點(diǎn)推薦

    嵌入式框架

    1.overview 圖1-1 嵌入式框架嵌入式系統(tǒng)分為硬件以及軟件兩大部分,大多數(shù)人參與的是嵌入式
    發(fā)表于 10-27 08:26

    嵌入式分層架構(gòu)的相關(guān)資料分享

    最近重新進(jìn)入嵌入式領(lǐng)域,有必要對嵌入式分層架構(gòu)有一個(gè)清晰的理解。經(jīng)過多方查閱以及個(gè)人的理解,本人對嵌入式分層架構(gòu)概括總結(jié)如下:比較細(xì)的層次由
    發(fā)表于 10-28 08:42

    探討一下嵌入式軟件分層設(shè)計(jì)

    嵌入式軟件分層設(shè)計(jì)嵌入式軟件就是某一項(xiàng)目的源碼文件集合,源碼文件的數(shù)量,根據(jù)項(xiàng)目復(fù)雜程度的不同而有規(guī)模和層次的差別。就拿簡單的一個(gè)芯片廠..
    發(fā)表于 02-14 07:19

    嵌入式Linux軟件測試框架的研究

    嵌入式Linux 軟件是最難測試的一類軟件。在測試過程中通過使用有效的測試框架,可以顯著提高測試效率,最終確保軟件質(zhì)量。通過對
    發(fā)表于 06-07 17:14 ?29次下載

    嵌入式軟件建立統(tǒng)一框架方法的研究

    介紹了嵌入式系統(tǒng)軟件的特點(diǎn)#說明要建立統(tǒng)一嵌入式軟件系統(tǒng)框架的原因,指出軟件系統(tǒng)的開發(fā)途徑,提出
    發(fā)表于 11-07 16:02 ?27次下載

    嵌入式應(yīng)用框架EAF詳解

    EAF是Embedded Application Framework 的縮寫,即嵌入式應(yīng)用框架。嵌入式應(yīng)用框架是 Application framework的一種, 是在
    發(fā)表于 12-02 11:30 ?3161次閱讀

    關(guān)于嵌入式應(yīng)用框架(EAF)的分析

    EAF是Embedded Application Framework 的縮寫,即嵌入式應(yīng)用框架。嵌入式應(yīng)用框架是 Application framework的一種, 是在
    發(fā)表于 01-01 09:50 ?1767次閱讀

    嵌入式軟件是什么意思_嵌入式軟件的分類有哪些

    本文首先闡述了嵌入式軟件的概念,其次介紹了嵌入式軟件的特征,最后介紹了嵌入式軟件的分類。
    發(fā)表于 08-31 15:54 ?1.6w次閱讀

    嵌入式系統(tǒng)框架----硬件篇

    1.系統(tǒng)框架圖對于一個(gè)嵌入式系統(tǒng),最重要的當(dāng)然是運(yùn)算以及存儲單元,基本的嵌入式系統(tǒng)可以簡化成如下系統(tǒng)框架圖:
    發(fā)表于 10-20 11:51 ?3次下載
    <b class='flag-5'>嵌入式</b>系統(tǒng)<b class='flag-5'>框架</b>----硬件篇

    嵌入式框架-分層

    原有的代碼。接下來嵌入式ARM便和大家分享一下,嵌入式架構(gòu)那些事兒……01嵌入式系統(tǒng)的基本架構(gòu)嵌入式系統(tǒng)一般由軟件和硬件兩個(gè)部分組成,基中
    發(fā)表于 10-20 16:06 ?24次下載
    <b class='flag-5'>嵌入式</b><b class='flag-5'>框架</b>-<b class='flag-5'>分層</b>

    嵌入式系統(tǒng)框架----軟件

    1.overview 圖1-1 嵌入式框架嵌入式系統(tǒng)分為硬件以及軟件兩大部分,大多數(shù)人參與的是
    發(fā)表于 10-20 19:21 ?6次下載
    <b class='flag-5'>嵌入式</b>系統(tǒng)<b class='flag-5'>框架</b>----<b class='flag-5'>軟件</b>篇

    嵌入式開發(fā)|嵌入式軟件框架《二》前后臺任務(wù)框架-cola os系統(tǒng)

    系列文章目錄嵌入式開發(fā)|嵌入式軟件框架《一》常用的軟件框架介紹與選擇文章目錄系列文章目錄前言一、
    發(fā)表于 11-03 13:51 ?18次下載
    <b class='flag-5'>嵌入式</b>開發(fā)|<b class='flag-5'>嵌入式</b><b class='flag-5'>軟件</b><b class='flag-5'>框架</b>《二》前后臺任務(wù)<b class='flag-5'>框架</b>-cola os系統(tǒng)

    嵌入式軟件分層隔離的典范是什么?

    嵌入式軟件開發(fā)分層、模塊化是理想狀態(tài),實(shí)際開發(fā)中因各種限制而有所取舍,但這不妨礙學(xué)習(xí)參考優(yōu)秀軟件架構(gòu),即使有部分思想在項(xiàng)目中落實(shí),也是大有裨益的。
    的頭像 發(fā)表于 01-20 11:08 ?1452次閱讀
    <b class='flag-5'>嵌入式</b><b class='flag-5'>軟件</b><b class='flag-5'>分層</b>隔離的典范是什么?

    嵌入式軟件架構(gòu)設(shè)計(jì)之程序分層

    嵌入式MCU軟件開發(fā)過程中,程序分層設(shè)計(jì)也是重中之重,關(guān)系到整個(gè)軟件開發(fā)過程中的協(xié)同開發(fā),降低系統(tǒng)軟件的復(fù)雜度(復(fù)雜問題分解)和依賴關(guān)系、
    的頭像 發(fā)表于 02-15 14:41 ?1736次閱讀
    <b class='flag-5'>嵌入式</b><b class='flag-5'>軟件</b>架構(gòu)設(shè)計(jì)之程序<b class='flag-5'>分層</b>

    聊聊嵌入式軟件分層

    今天以控制LED閃爍為例,聊聊嵌入式軟件分層
    的頭像 發(fā)表于 12-28 09:22 ?914次閱讀