在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁(yè) > 設(shè)計(jì)應(yīng)用 > 嵌入式軟件架構(gòu)設(shè)計(jì):建立抽象層

            嵌入式軟件架構(gòu)設(shè)計(jì):建立抽象層

            作者: 時(shí)間:2023-12-14 來(lái)源: 收藏

            這東西,眾說(shuō)紛紜,各有觀點(diǎn)。什么是,我們能在網(wǎng)上找到無(wú)數(shù)種定義。比如,我們可以這樣定義:是軟件系統(tǒng)的基本結(jié)構(gòu),體現(xiàn)在其組件、組件之間的關(guān)系、組件設(shè)計(jì)與演進(jìn)的規(guī)則,以及體現(xiàn)這些規(guī)則的基礎(chǔ)設(shè)施。怎么定義一般來(lái)說(shuō),基本上不重要,我們不是在寫(xiě)學(xué)術(shù)書(shū)籍,工程人員嘛,只關(guān)心軟件架構(gòu)能解決什么問(wèn)題。

            本文引用地址:http://www.biyoush.com/article/202312/453918.htm

            軟件架構(gòu)不是制定出來(lái)的,而是產(chǎn)品和業(yè)務(wù)需求所決定的,架構(gòu)師所做的,只是忠于需求,并合理的表達(dá)了需求。軟件架構(gòu)也從來(lái)都不是一成不變的。在產(chǎn)品或者產(chǎn)品線的整個(gè)生命周期中,隨著業(yè)務(wù)和需求的變化,軟件架構(gòu)不斷發(fā)展和變化,以適應(yīng)新的需要。

            軟件架構(gòu)不是一個(gè)簡(jiǎn)單的項(xiàng)目問(wèn)題,而是產(chǎn)品或產(chǎn)品線的技術(shù)戰(zhàn)略問(wèn)題。一個(gè)良好設(shè)計(jì)并推廣的軟件架構(gòu),能帶來(lái)如下好處。

            · 最大限度地減少不必要的返工

            · 使軟件在宏觀層面建立規(guī)劃

            · 增強(qiáng)復(fù)用性,降低開(kāi)發(fā)成本

            · 便于團(tuán)隊(duì)內(nèi)部的技術(shù)培訓(xùn)

            · 使技術(shù)積累更加容易

            經(jīng)??吹降囊粋€(gè)常見(jiàn)問(wèn)題是,新手工程師,由于經(jīng)歷與知識(shí)不足,往往看不到項(xiàng)目全貌,很難深刻理解軟件架構(gòu),他們往往要經(jīng)過(guò)多年的專業(yè)訓(xùn)練,才能逐漸建立架構(gòu)意識(shí)。

            但軟件架構(gòu)真的只是資深工程師和架構(gòu)師的專利嗎?這個(gè)也不見(jiàn)得。古人作文,講究立意為先。

            今天工程師做項(xiàng)目和產(chǎn)品,也應(yīng)該先立意。這個(gè)意,就是指要有高度。工程師入門(mén)能從軟件架構(gòu)的高度出發(fā),看待軟件問(wèn)題,相信對(duì)軟件的理解,會(huì)更加深刻一些。因此,總結(jié)了軟件架構(gòu)的六個(gè)步驟,供工程師參考。

            1. 隔離硬件相關(guān)代碼,建立

            2. 建立統(tǒng)一的軟件基礎(chǔ)設(shè)施

            3. 妥善識(shí)別和處理產(chǎn)品數(shù)據(jù)

            4. 功能分層與分解

            5. 組件及其接口設(shè)計(jì)

            6. 測(cè)試、調(diào)試與跨平臺(tái)開(kāi)發(fā)的支持

            需要注意的是,這些并不足以保證工程師學(xué)會(huì)軟件架構(gòu)。嵌入式軟件架構(gòu)師,是不可培養(yǎng)的。但至少,嵌入式工程師們,可以了解到什么是正確的努力方向,很多時(shí)候,選擇比努力更加重要。

            嵌入式軟件架構(gòu)之一 與硬件隔離

            許多新手乃至老手嵌入式工程師,在未了解軟件架構(gòu)之前,把應(yīng)用層功能和硬件相關(guān)的代碼,不由自主的攪和在一起寫(xiě)。這種做法非常普遍。比如下面的代碼:

            void modbus_rtu_write_reply(uint8_t add, uint8_t func_code, uint16_t reg, uint16_t data)
            {
                rs485.buff_tx[0] = add;
                rs485.buff_tx[1] = func_code;
                rs485.buff_tx[2] = (uint8_t)(reg >> 8);
                rs485.buff_tx[3] = (uint8_t)(reg);
                rs485.buff_tx[4] = (uint8_t)(data >> 8);
                rs485.buff_tx[5] = (uint8_t)(data);
                uint16_t crc16 = mb_crc16(rs485.buff_tx, 6);
                rs485.buff_tx[6] = (uint8_t)(crc16);
                rs485.buff_tx[7] = (uint8_t)(crc16 >> 8);
                rs485.tx_total = 8;
                rs485.tx_num = 0;
                /* Send data from the uart port. The hardware related program. */
                LL_USART_ClearFlag_TC(USART1);
                LL_USART_EnableIT_TC(USART1);
                USART1->DR = rs485.buff_tx[rs485.tx_num ++];
            }

            上面的這一段代碼,不是一個(gè)好例子。從函數(shù)LL_USART_ClearFlag_TC開(kāi)始的一句,也就意味著,這個(gè)Modbus的代碼,和MCU提供出的固件庫(kù)耦合在一起寫(xiě)了。

            著名的SOLID原則中,有個(gè)依賴倒置原則,高層模塊不應(yīng)該依賴于底層模塊,它們應(yīng)該共同依賴于抽象。此處的代碼,顯然違反了這一原則。Modbus作為高層模塊,此處對(duì)MCU固件庫(kù)的API進(jìn)行了依賴。

            對(duì)于這種將硬件相關(guān)的代碼與功能耦合在一起的軟件架構(gòu),在本文中,我們姑且稱之為“耦合架構(gòu)”;而我們要追求的,是將隔離硬件相關(guān)的軟件架構(gòu),我們稱之為“隔離架構(gòu)”。接下來(lái),我們將詳細(xì)對(duì)比,耦合架構(gòu)和隔離架構(gòu)各自的特征。

            耦合架構(gòu)的問(wèn)題

            雖然從原則上來(lái)說(shuō),耦合架構(gòu)是不對(duì)的,但萬(wàn)事皆有因,存在即合理。一般而言,大部分嵌入式軟件工程師,都出自硬件相關(guān)的專業(yè)(比如電子、自動(dòng)化等),來(lái)自于軟件工程和計(jì)算機(jī)專業(yè)的嵌入式工程師不多(他們都去互聯(lián)網(wǎng)行業(yè)了),因此從他們的知識(shí)結(jié)構(gòu)和習(xí)慣思維出發(fā),一般從硬件視角看待嵌入式系統(tǒng),而不是站在軟件抽象的視角。

            但理解歸理解,道理歸道理,既然已經(jīng)從事嵌入式軟件,哪怕是硬件專業(yè)出身的,我也建議他一定拋棄既有思維,學(xué)會(huì)抽象這一強(qiáng)大的軟件思維工具,否則他的職業(yè)天花板將非常低。

            耦合架構(gòu)帶來(lái)的問(wèn)題,也是顯而易見(jiàn)的,那就是,實(shí)實(shí)在在的難以移植。因?yàn)橐坏┯布l(fā)生變化,比如MCU停產(chǎn),芯片短缺等等(在當(dāng)前形勢(shì)下太過(guò)常見(jiàn)),嵌入式軟件就要大把修改。如果軟件規(guī)模較大,嘗試移植耦合架構(gòu)的代碼到在新MCU上,是一項(xiàng)艱巨的工作,沒(méi)人愿意干這事。因此產(chǎn)品開(kāi)發(fā)完成,更新架構(gòu)并推倒重來(lái),幾乎是不可能。

            別說(shuō)工程師不愿意,你問(wèn)問(wèn)老板答應(yīng)嗎?于是工程師們只能檢查所有代碼,把與硬件交互的每一行代碼改掉,遇到硬件交互方式大不相同的,就更糟心,還要大篇幅的改,邊改邊罵娘。比如上面的代碼,如果換一片芯片,可能要改為以下代碼。

            void modbus_rtu_write_reply(uint8_t add, uint8_t func_code, uint16_t reg, uint16_t data)
            {
                rs485.buff_tx[0] = add;
                rs485.buff_tx[1] = func_code;
                rs485.buff_tx[2] = (uint8_t)(reg >> 8);
                rs485.buff_tx[3] = (uint8_t)(reg);
                rs485.buff_tx[4] = (uint8_t)(data >> 8);
                rs485.buff_tx[5] = (uint8_t)(data);
                uint16_t crc16 = mb_crc16(rs485.buff_tx, 6);
                rs485.buff_tx[6] = (uint8_t)(crc16);
                rs485.buff_tx[7] = (uint8_t)(crc16 >> 8);
                rs485.tx_total = 8;
                rs485.tx_num = 0;
             
               /* Send data from the uart port. The hardware related program. */
                MCU_NEW_USART_ClearFlag_TC(NEW_USART1);
                MCU_NEW_USART_EnableIT_TC(NEW_USART1);
                NEW_USART1->DR = rs485
            .buff_tx[rs485.tx_num ++];
            }

            其次,耦合架構(gòu)會(huì)導(dǎo)致,在開(kāi)發(fā)環(huán)境中(如Windows或者Linux,非目標(biāo)硬件),很難對(duì)應(yīng)用程序進(jìn)行單元測(cè)試。脫離目標(biāo)硬件,跨平臺(tái)開(kāi)發(fā)嵌入式程序,是提升開(kāi)發(fā)效率的重要措施。

            對(duì)耦合架構(gòu)來(lái)說(shuō),應(yīng)用程序代碼直接調(diào)用硬件,如果要進(jìn)行完整的測(cè)試工作,就要花費(fèi)大量工作,因?yàn)闇y(cè)試程序也要去操作硬件,才能驗(yàn)證正確與錯(cuò)誤?;蛘撸枰こ處熢谟布贤瓿墒謩?dòng)測(cè)試(實(shí)際上現(xiàn)在大家就這么干的,哈哈)。

            手動(dòng)測(cè)試很繁瑣,往往讓人煩躁,工程師的主觀感受,會(huì)影響測(cè)試質(zhì)量。很多時(shí)候,為了趕進(jìn)度,或者規(guī)避繁瑣的測(cè)試工作,軟件并沒(méi)有經(jīng)過(guò)很好的測(cè)試,整體系統(tǒng)質(zhì)量受到影響。另外,手動(dòng)測(cè)試,交付軟件可能需要更長(zhǎng)的時(shí)間。而自動(dòng)測(cè)試,往往只需要一瞬間,清楚明了。

            第三,耦合架構(gòu)將存在不易擴(kuò)展的問(wèn)題。耦合架構(gòu),往往是共享數(shù)據(jù)的,也就是所謂的全局變量滿天飛。隨著軟件系統(tǒng)的擴(kuò)大,每個(gè)新功能的添加,變得更加困難,而且是越來(lái)越困難,出現(xiàn)BUG的機(jī)會(huì)急劇增加。屎山就是這么煉成的。

            但需要說(shuō)明的是,數(shù)據(jù)問(wèn)題,不是說(shuō)隔離了硬件,就能完全解決掉。數(shù)據(jù)問(wèn)題,是嵌入式軟件乃至任何軟件的核心問(wèn)題,它需要在架構(gòu)六部曲之二和之三中,通過(guò)軟件基礎(chǔ)設(shè)施的合理構(gòu)建,和數(shù)據(jù)機(jī)制的合理制定,共同得到解決。

            隔離架構(gòu)如何解決問(wèn)題?

            到這里,我們架構(gòu)的第一步,呼之欲出,那就是:將軟件架構(gòu)分離為硬件相關(guān)和硬件無(wú)關(guān)兩個(gè)部分。這就要引入這個(gè)概念。何為抽象層?抽象層有很多種,比如硬件抽象層(HAL)、設(shè)備抽象層(DAL),操作系統(tǒng)抽象層(OSAL),網(wǎng)絡(luò)抽象層,文件系統(tǒng)抽象層,F(xiàn)lash抽象層(RT-Thread里就有這個(gè))等等。

            對(duì)誰(shuí)進(jìn)行抽象,就會(huì)建立這個(gè)東西的抽象層,無(wú)一定之規(guī)。本文中的抽象層,特指硬件抽象層,或者設(shè)備抽象層,或者二者兼?zhèn)洹>唧w是誰(shuí),取決于產(chǎn)品特性。

            在硬件相關(guān)代碼和硬件獨(dú)立代碼之間創(chuàng)建抽象層,這是軟件移植的要求,實(shí)際上也是依賴倒置原則需求。在這里,我們有必要對(duì)依賴倒置原則進(jìn)行強(qiáng)調(diào):高層模塊不應(yīng)該依賴于底層模塊,它們應(yīng)該共同依賴于抽象。也就是說(shuō),應(yīng)用層代碼(硬件無(wú)關(guān)),不應(yīng)該依賴于硬件相關(guān)的代碼(驅(qū)動(dòng)代碼),他們應(yīng)該依賴于抽象層代碼。

            抽象層的創(chuàng)建,將允許將應(yīng)用代碼從一個(gè)微控制器移動(dòng)到下一個(gè)微控制器,或者一套硬件遷移到另一套硬件,應(yīng)用層代碼不必更換。抽象層打破了硬件依賴關(guān)系;換句話說(shuō),應(yīng)用程序根本不必知道,也不必關(guān)心,當(dāng)前運(yùn)行的是什么硬件,應(yīng)用程序只需要關(guān)心抽象層的API是什么樣的。

            新的硬件驅(qū)動(dòng)程序要做的,僅僅是滿足接口的要求而已。這意味著如果我們更改硬件,則只會(huì)更改硬件相關(guān)的模塊,而不是整個(gè)代碼庫(kù)。

            void modbus_rtu_write_reply(uint8_t add, uint8_t func_code, uint16_t reg, uint16_t data)
            {
                rs485.buff_tx[0] = add;
                rs485.buff_tx[1] = func_code;
                rs485.buff_tx[2] = (uint8_t)(reg >> 8);
                rs485.buff_tx[3] = (uint8_t)(reg);
                rs485.buff_tx[4] = (uint8_t)(data >> 8);
                rs485.buff_tx[5] = (uint8_t)(data);
                uint16_t crc16 = mb_crc16(rs485.buff_tx, 6);
                rs485.buff_tx[6] = (uint8_t)(crc16);
                rs485.buff_tx[7] = (uint8_t)(crc16 >> 8);
                rs485.tx_total = 8;
                rs485.tx_num = 0;
                /* Send data from the uart port. The hardware related program. */
                hal_uart_send(HAL_UART_ID_1, rs485.buff_tx, rs485.tx_total);
            }
            void hal_uart_send

            硬件相關(guān)的代碼,應(yīng)該改為如下的樣子。這尚且算不上真正的抽象層,只是抽象層最簡(jiǎn)陋的替代實(shí)現(xiàn)方法,實(shí)際工程應(yīng)用中,抽象層還有很多細(xì)節(jié)需要闡述。

            void hal_uart_send(uint8_t uart_id, void *buffer, uint32_t size)
            {
                /* Start the uart sending process, the remaning data will be send in UART ISR 
                   function. */

                MCU_NEW_USART_ClearFlag_TC(NEW_USART1);
                MCU_NEW_USART_EnableIT_TC(NEW_USART1);
                NEW_USART1->DR = rs485.buff_tx[rs485.tx_num ++];
            }

            抽象層還可以解決單元測(cè)試的許多問(wèn)題。有了抽象層,我們可以在Windows或者Linux上創(chuàng)建硬件的替身程序(mock),也可以稱為假硬件。我們可以在假硬件上給出輸入數(shù)據(jù),并通過(guò)檢查假硬件給出的輸出數(shù)據(jù)會(huì)否符合預(yù)期,來(lái)對(duì)軟件進(jìn)行單元測(cè)試。在沒(méi)有硬件的情況,也可以對(duì)應(yīng)用層程序進(jìn)行開(kāi)發(fā)。很多嵌入式程序員覺(jué)得不可能,但這時(shí)很多大公司開(kāi)發(fā)軟件的方式。

            抽象層的建立,還有一個(gè)好處。軟件不必等著硬件就緒才開(kāi)始開(kāi)發(fā),而在硬件可用之前,就開(kāi)始專注于開(kāi)發(fā)和交付應(yīng)用程序。

            這樣做的好處是,可以在項(xiàng)目早期就對(duì)客戶提供試用服務(wù),并根據(jù)客戶反饋進(jìn)行功能調(diào)整。如今,太多的團(tuán)隊(duì)專注于首先準(zhǔn)備好硬件,而核心應(yīng)用程序是事后才想到的。這樣并不利于對(duì)嵌入式軟件進(jìn)行良好的設(shè)計(jì)和實(shí)現(xiàn)。

            那么如何建立抽象層呢?抽象層的建立,涉及到幾個(gè)關(guān)鍵的因素:抽象的程度、抽象的手段以及抽象的對(duì)象。這些問(wèn)題,非常復(fù)雜,非三言兩語(yǔ)就能說(shuō)清。

            結(jié)論

            嵌入式軟件與其他軟件領(lǐng)域都不一樣,因?yàn)闆](méi)有一個(gè)軟件領(lǐng)域,和嵌入式軟件一樣,會(huì)和硬件進(jìn)行直接交互(請(qǐng)注意此處直接二字)。

            為了應(yīng)對(duì)可能出現(xiàn)的硬件變化(無(wú)論是MCU,PCBA,還是連接PCBA的設(shè)備),嵌入式軟件架構(gòu)師應(yīng)該將硬件相關(guān)的代碼獨(dú)立出去,并壓縮在一個(gè)最小的范圍內(nèi)。否則,一旦使用耦合架構(gòu),不對(duì)硬件相關(guān)代碼進(jìn)行剝離,屎山式的代碼,幾乎是注定的結(jié)局。

            一個(gè)成功的軟件架構(gòu),從來(lái)不是一蹴而就,通常是通過(guò)迭代和演進(jìn)創(chuàng)建的。這需要技術(shù)負(fù)責(zé)人,或者架構(gòu)師,主動(dòng)去推動(dòng)軟件架構(gòu)的迭代,不斷推動(dòng)軟件的優(yōu)化重構(gòu)。這就有點(diǎn)像明星的好身材,從來(lái)不是天生,都是后天自律的結(jié)果。

            但在嵌入式領(lǐng)域,無(wú)論搞什么產(chǎn)品,搞什么復(fù)雜的軟件架構(gòu),剝離硬件相關(guān),是第一步,也是最為關(guān)鍵的一步。連硬件相關(guān)代碼都剝不干凈,軟件架構(gòu)就猶如浮沙筑高臺(tái),無(wú)從談起。

            合抱之木,生于毫末,有志于提升技術(shù)水平的工程師們,先從隔離硬件開(kāi)始吧。



            評(píng)論


            相關(guān)推薦

            技術(shù)專區(qū)

            關(guān)閉