剛好來公司也一個月了。就談談一個月時間我對公司產品的軟件框架的理解。
所有的程序其實都是一個死循環,尤其是在學單片機的時候這種感覺最明顯。那時候寫的一些簡單的程序都是直接放在 `main()` 函數的主循環裏。後來要寫複雜一點,功能比較多的程序的時候再用這種寫法其實就很不合適了,這時候就需要用到分時多任務管理框架,更複雜的一些產品還會用到實時操作系統。
但不管是使用分時多任務,還是實時系統,其實主要目的都是為了把一個複雜的系統分成多個任務或線程,讓他們彼此相對獨立的去運行。一般要去維護這種項目都是先看他有多少個任務,再按照先易後難的順序把一個個任務的功能邏輯搞清楚,這樣一個新的項目就算基本上手了。不過我們公司的產品是在芯片廠商提供的一種 SDK 開發包的基礎上二次開發。他既沒有實時系統,也沒有任務管理函數(其實不是沒有,而是 SDK 隱藏起來了對開發人員不可見)。
以網關的 ESP8266 為列, 樂鑫 SDK 隻給了一個 `user_init()` 函數,隻能在他給的這個函數裏執行上電初始化,和配置之類的工作,初始化完了之後系統運行到哪裏去了,完全不知道,剩下的所有業務邏輯都是在各種回調函數裏執行的。各種各樣的回調函數,讓人摸不著頭腦。而且我對網絡這方面不是很懂,所以對他的業務流程、邏輯也不清楚,讓我一下子有一種找不著北的感覺。
好在這種感覺持續沒多久,很快就找到了其中的一些套路。比如說 SDK 會提供軟件定時器,用戶可以初始化一個定時器,在初始化的時候指定這個定時器的時間、和回調函數,這樣這個定時器就會每隔指定的時間間隔,運行一次那個回調函數,這種機製就可以看成是一個任務管理函數。那個回調函數就相當於一個任務。其他的功能函數也是類似的模式。
串口接收數據,就是串口開啟了一個中斷,當中斷接收到指定長度的數據後就會調用配置好的一個串口接收函數。用戶對串口數據的處理就寫在這個串口接收函數裏。其他的 TCP HTTP 的客戶端和服務端也是一樣的,先創建一個 TCP 套件字,再指定套接字的各種回調函數,接收到數據就會執行一次接收回調函數,用戶可以在回調函數裏處理接收到的數據。他們就像單片機裏的各種模塊的中斷,不過單片機裏的是一種硬件中斷,執行中斷程序的時候會獨占 CPU 資源,系統的節拍就不能正常的更新(可以理解為系統心跳停止),會導緻其他的應用函數延時變大(實時性降低),所以單片機是要求中斷裏的程序盡可能的簡潔,***隻做一個標記,由其他的應用層任務通過相關標記去處理具體的事件。
樂鑫的 SDK 提供的回調函數,應該是一種用軟件模擬的中斷,不是真的在硬件中斷裏執行的。所以他提供的這些回調函數可以理解成是一個個線程,平時沒事事件的時候他們不會被執行,相當於處於一種休眠狀態,但是一旦有相關的事件發生他們就會被後台調用(後台應該也是一種分時多任務管理函數)。
***的總結(個人觀點)
1. 對於一個項目的熟悉和了解需要從兩個維度去看——橫向和縱向。
2. 橫向就是對於各個不同的任務或線程的理解。
3. 縱向就是從硬件的操作和到應用層的業務流程,也就是從底層到應用層。
您好,請點擊在線客服進行在線溝通!