學生三年,職場兩年。五年之內,雖無大成,然心中有感,不禁自發(fā)。
一、學生三年
1.1 初次接觸嵌入式
一名渾噩的大學生
我不清楚具體有多少人初入大學確定專業(yè)時就感覺上錯了船,但我覺得不在少數。轉專業(yè)似乎是條出路,但是很奇怪的邏輯是:
一般只有專業(yè)成績前10~20%才有機會。
不過這只是一個托辭,自身渾渾噩噩才是問題的根本。
記得很清楚,大一課堂上,清醒的時候不多,從來也沒坐過前幾排。被輔導員批評過,也在期末等成績的時候膽戰(zhàn)心驚,但從沒想過自己要做什么。就這樣,一年。
謝謝通識教育
有幸學校開設了較多的通識教育課,作為水利水電工程專業(yè)的學生,雖然不少同學對《C/C++語言程序設計》和《電工與電子技術》這兩門課不感興趣,但是幫我打開了一扇窗。
初次接觸 C 語言,讓我看到了程序世界的精彩。慢慢地,我沉迷其中,如癡如醉。那本教材,是我讀過最多的課本,細節(jié)之處都寫下筆記,或是心得,亦有不解。作業(yè)和考試不再是應付,最終也取得不錯的成績。
后來報考計算機二級,也毫不猶豫地選擇 C 語言,并順利通過。
而《電工與電子技術》這門課,真正讓我接觸硬件知識。我很喜歡開設的電子實驗課,理論用于實踐,動手完成各種硬件電路的搭建。
弱水三千,只取一瓢飲
信息技術領域有眾多行業(yè)和職業(yè)方向,當初我也是面臨諸多選擇。往上,可以選擇純軟件;往下,可以選擇軟硬件結合。在探究和調研職業(yè)方向的路上,我接觸了較多的東西。
那段時間,我泡在圖書館,在計算機科學那么多排的書架前,如饑似渴翻閱著。這期間,我學習了網站建設、計算機輔助技術、嵌入式開發(fā)、自動化與工業(yè)控制以及數字電路等等。我沒有特別仔細的研讀,也刻意不去了解技術細節(jié),目的是抽絲剝繭找到自己的最終方向。
選擇嵌入式軟件,看重的是物聯網,也因為自己喜歡底層開發(fā),與硬件打交道樂此不疲。在單片機和嵌入式 Linux 這兩塊,我優(yōu)先選擇了單片機開發(fā),將 Linux 往后放一放。
1.2 堅定轉行
魚與熊掌不可兼得。本專業(yè)的學習在自己看來也算不上魚,給自己定下的目標就是專業(yè)不掛科,一身心撲到正業(yè)上。
課堂上,埋頭看《微機原理》;宿舍中,學習單片機開發(fā)。只有在期中或期末的考試周,才將時間用在專業(yè)考試準備上。
當然,自我學習并沒有那么順利,遇到諸多的問題,自我管理的能力也有一定的問題。
1.3 尋求出路
臨近畢業(yè)之時,便不得不尋求自己的出路。首先,本專業(yè)的工作是不愁的,但并非心之所愿;而后有兩條路:跨專業(yè)考研和跨專業(yè)找工作。
深思熟慮過后,決定兩條路同時走。無論何時,好好學習是不會錯的。以備考之學,滋求職之事,齊頭并進,較為穩(wěn)妥。事后證明,這樣的選擇是正確的。
在備考的過程中,系統地學習了計算機科學幾門基礎課程,例如《計算機組成原理》、《計算機操作系統》、《計算機網絡》、《數據庫原理及應用》和《數據結構與算法》等等。這些知識內容對后面的應聘面試大有裨益,順利獲得心儀的職位。
至于考研之事,初試表現平平,后因求職定局,復試的心思有所浮動,最終并未被錄取。倒也沒有太多的后悔,當時家里房貸壓力較大,也有意早日工作為父母分擔。
二、工作兩年
遙記得畢業(yè)不到幾天,便入職新公司。公司深耕工業(yè)互聯網領域,致力于工業(yè)生產設備安全與可靠性管理的研究與開發(fā),我在終端開發(fā)部門擔任嵌入式軟件助理工程師一職。
2.1 職場新人
公司為客戶提供端到端——硬件產品端到系統平臺端——的解決方案。作為新人,工作之初并沒有直接參與終端產品軟件開發(fā),而是負責各個項目硬件終端到系統平臺的配置和數據接入,以及終端設備的測試工作。
這樣的崗位安排有助于自己了解整個公司的業(yè)務架構,若只是參與某項終端產品的開發(fā),則猶如管中窺豹。而測試的工作也讓自己熟悉了終端設備,并且深刻體會到測試工作的意義和重要性。
至此半年,完成了職場新人之蛻變。
2.2 獨當一面
2020年不易,不僅是生活上,還有工作。在這一年里,我完成了一款量產產品和三款試產產品的軟件開發(fā)。說是四款產品,其實大部分的軟硬件設計是一樣的,所以以下從其中之一詳述,并解釋其他三款產品設計的不同點。
第一款產品
前文說到,公司致力于工業(yè)生產設備安全與可靠性管理的研究與開發(fā),其重點就是設備振動分析,因此終端開發(fā)部門的產品大多是振動檢測器。無線振動溫度檢測器是我經手的第一個項目,也并不是從零開始的,是從初代產品軟硬件迭代而來。
無線振動溫度檢測器采集振動溫度傳感器數據,進行初步的邊緣計算,然后將原始數據和分析數據通過無線通信方式傳輸到網關設備。具體的硬件設計方案不便闡述,這里作簡單介紹。
振動數據采集電路中,微控制器提供給模數轉換芯片的時鐘信號控制后者的采樣頻率,提供給濾波器的時鐘信號控制其截止頻率;
加速度傳感器的模擬信號通過濾波器濾波后作為模數轉換芯片的輸入信號,模數轉換芯片自動將模擬信號轉換為數字信號;
微控制器和模數轉換芯片通過串行外設接口(SPI)總線通信,讀取振動數字信號。溫度數據采集電路中,微控制器和溫度芯片通過集成電路總線(I2C)通信,獲取溫度數據。
微控制器和 ZigBee 通信模組之間通過通用異步收發(fā)傳輸器(UART)進行通信,將傳感器原始數據或者處理過的數據上傳至網關設備;
同時 ZigBee 通信模組也可以接收網關設備下發(fā)的各種指令,通過UART接口發(fā)送給微控制器。
軟件上采用多線程設計方案,基于國產實時操作系統 RT-Thread OS。主線程負責硬件初始化、數據采集和上傳應用以及休眠管理,通信線程由主線程在進行數據上傳業(yè)務時創(chuàng)建,看門狗線程在軟件異常時進行系統復位。以黑盒的角度觀察,設備周期喚醒采集和上傳數據,然后進入休眠。參數配置也通過無線通信進行修改。
其余三款產品
第二款產品設計時,在第一款產品硬件基礎上更換了新的加速度傳感器,可以直接輸出三軸加速度數字信號,因此也搭配了更大內存容量的微控制器。軟件設計上和之前沒有太多差別,通信協議上作了兼容修改,以滿足多軸振動數據。
第三款產品設計時,在第一款產品硬件基礎上采用 NB-IoT 通信模組進行數據傳輸。軟件重新進行設計,主線程負責硬件初始化和休眠管理,主線程創(chuàng)建指令線程和通信線程;
指令線程負責從指令隊列取指執(zhí)行,指令類型分為內部指令和遠程指令,同時也可能產生通信任務;
通信線程負責從通信任務隊列中獲取任務執(zhí)行,同時接收服務器遠程指令;
看門狗線程在軟件異常時進行系統復位。
因為指令執(zhí)行時可能產生通信任務,通信時也可能收到新的指令,所以在指令線程和通信線程中,用到了優(yōu)先級翻轉,確保這兩個線程始終是第一和第二優(yōu)先級。
當無指令且無通信任務時,才由主線程接管控制權進行休眠和喚醒管理。由于更換了通信模組,因此驅動層和網絡層重新編寫代碼,好在 RT-Thread OS 有現成的 AT 組件,方便了驅動層的設計和編碼。
協議方面,參照選用的物聯網平臺文檔和實際應用重新設計,充分考慮未來的擴展性。
第四款產品也是基于第一款產品的設計,從低成本的角度出發(fā),在其他硬件原理不變的情況下,使用復用器,將振動增加到四通道。
軟件上大部分內容可以從之前代碼移植甚至不需要修改,但是仍然帶來一些變化。
首先,之前的時間管理和參數管理是一維的,即數據上傳周期和各類參數都只需要一個。例如原先有電池電量、溫度、振動時域數據和特征數據四個獨立的上傳周期,那么對于現在四通道的產品,需不需要十六個獨立的上傳周期?
同樣的,對于參數管理,某些與傳感器個體特性相關的參數(如靈敏度)則必須擴展成四個,其他的參數則需要單獨評估。
其次,四通道的使能和失能是否應該是可配置的。例如通過修改通道選擇參數的二進制編碼,可以靈活控制使用哪些通道,但這同時又涉及到傳輸協議。
因為有些技術細節(jié)沒有介紹,因此難免會引起讀者的困惑抑或是質疑,這里不過多闡述,總之這是一款需要短時間交付、只有簡單的需求文檔、限于技術要求的產品。
2.3 二三心得
這一年半的工作當中,確實學到了很多,也踩過不少的坑。有一些摸索出來的淺顯經驗,也有一些一直都懂但沒做好的道理,在此將這二三心得付諸文字,與君共勉。
軟件需要設計,且需要好好設計
也許是帶我的良師覺得我開發(fā)經驗尚淺,害怕我寫出來的軟件 Bug 頻出,又或許他有意識培養(yǎng)我先設計后實現的良好習慣,總之在這過程中我明白了一個直白的道理——良好的軟件是設計出來的,當軟件被設計好過后,程序員只是在用具體的程序設計語言翻譯它罷了。
如果設計和構思階段不能理清自己的思路,那么實現時也不可能清晰明了,這不僅僅是軟件開發(fā)領域的原則。
盡早測試和自動化測試
在工作的一年半內,我做過相當多的測試工作。除了自己的軟件需要充分的測試,其他的產品也需要,但是這過程不是很輕松和順意。資料缺失,人工投入較多,沒有良好的測試規(guī)范和指導,這些都是弊病。
測試驅動開發(fā)不是所有人能玩得轉的,但開發(fā)中持續(xù)測試應當重視。盡早測試可以在代碼體量不龐大的時候抓住害蟲,試想在幾百行代碼和幾萬行代碼中找出問題,哪個更加簡單?
自動化測試則是把人從繁雜的工作中解放出來,單元測試、集成測試、系統測試和回歸測試都是必需且重要的,據我了解,這些在嵌入式軟件開發(fā)領域還不是很流行。
文檔
不知道你有沒有遇到以下這些問題:
產品使用者總是詢問開發(fā)人員某些細節(jié),是不是讓你很苦惱?
聯調時,和同事的交流是不是占用你太多的時間?
工作交接的過程中,有沒有足夠的資料讓接手人員快速進入工作?
諸如此類的問題數不勝數,解決問題的核心要素就是文檔,詳盡有用的文檔。
缺乏文檔已經是程序員日常工作中排名前幾的難題。代碼文檔化也是近年來風靡的概念,并且有較多工具可以幫助我們快速實現這一目標。
在寫代碼時,依據特定的規(guī)則添加注釋,便可以借助類似 Doxygen 這樣的工具生成開發(fā)文檔,非常有助于提高工作效率和進行信息交換。
文檔代碼化也同樣值得注意,將文檔以類代碼的領域特定語言的方式編寫,并借鑒軟件開發(fā)的方式(如源碼管理、部署)進行管理。
二進制文檔的優(yōu)勢和劣勢都相當明顯,而使用 Markdown 這類標記語言寫出來的文檔,雖然缺乏豐富的表現力(因為設計目標就是輕量),但對于軟件開發(fā)領域絕對夠用,并且可以解決二進制文檔版本管理難的問題。
2.3.4 最快的成長是學習優(yōu)秀的人,而不是自己領悟
沒人一開始就能領悟各種設計模式和開發(fā)原則,養(yǎng)成良好的代碼風格和習慣。在沒有學習和別人斧正的情況下,也許工作一輩子還只是個代碼民工。為了較好地闡明這兩句話其中的含義,在這分享一次我閱讀別人代碼的真實經歷。
有一次老板讓我和一位硬件同事重新生產一款早期的終端產品,用于公司創(chuàng)立初期承接的項目中損壞產品的替換。
需要強調的是,小公司創(chuàng)業(yè)初期沒有完善的產品設計開發(fā)和生產的流程,資料也是混亂不堪。
本以為不需要做什么事情,但很明顯我低估了這項任務,因為生產出來的產品工作異常,深入調試過后才解決問題。
我打開從同事那拷貝過來的工程文件,沒錯,資料都是拷貝的,沒有使用版本管理工具。這是一份 MDK Keil 工程文件,主控是 STM32 系列,一個幾百行的主函數包含了所有應用邏輯。單從主函數就能看出相當多的問題。
Hal 庫和寄存器混用
整個工程應該是使用 STM32CubeMX 生成的,基于 Hal 庫,但摻雜著大量的寄存器操作,并絕不是因為效率。
標識符命名停留在初學者水平
uint32_t ii 和 uint16_t i 讓人無語;大小駝峰命名和小寫字母下劃線命名混用;
隨處可見的幻數,可讀性極差,容易出錯
毫無章法的喂看門狗,感覺像是調試時隨性加上
條件語句濫用,根本沒考慮擴展性
沒有架構設計,直接處理通信協議的組包和拆包我一個初出茅廬的職場新人都看出這么多問題,簡直可以當作 Code Review 的反面教材,據說當時的開發(fā)人員也是有好幾年工作經驗的。
站在巨人的肩膀上才能看得更遠。
因此,多逛逛 Github,深入學習優(yōu)秀的案例,多看書。
2.3.5 適當參加面試
面試可以為了跳槽,也可以為了增長見識,摸摸自己的底,這里我主要想談談后者。
在公司,可能沒有人會考察你的基礎知識是否扎實,但面試時一定會。工作一年多,慢慢忘了大小端和字節(jié)對齊的一些細節(jié),也沒有再寫基礎數據結構和算法代碼。
而面試就是考場,能夠讓自己清楚自己的不足,同時也能知道企業(yè)需要什么樣的人才,有助于找到自己的職業(yè)方向甚至是事業(yè)。
三、寫在最后
五年,很慶幸自己仍然熱愛選定的方向。
五年,自認為沒有虛度如金的光陰。
新的一年,我們的故事還將繼續(xù)。
編輯:hfy
-
計算機
+關注
關注
19文章
7511瀏覽量
88078 -
C語言
+關注
關注
180文章
7605瀏覽量
137003 -
計算機網絡
+關注
關注
3文章
339瀏覽量
22180 -
數據采集電路
+關注
關注
1文章
5瀏覽量
7460
發(fā)布評論請先 登錄
相關推薦
評論