據說,在中國,當老板的一般都有這么一個心態:花最少的錢,辦最多的事!
客戶大爺不能慢待,因為開源和節流不可偏廢。政府機關必須打點,畢竟“有關部門”掌握著生殺大權。于是,這“節流之道”便落在了員工的頭頂上。
只是,人心惟危,道心惟微,被教育多年的打工者都不想做活雷鋒。節流手段過于明顯的話,無異于殺雞取卵。于是,老板們八仙過海,各顯神通。
有的呢,深入落實我黨的群眾路線,和群眾們打成一片,很好地實現了“到群眾中去,讓人民服務”的目的。
有的呢,擺出一副義薄云天的架勢,和員工們勾肩搭背、稱兄道弟,以“情”感人,成功地將老實厚道的員工們加薪的請求扼殺在了萌芽狀態。
有的呢,善用權謀,假惺惺地放權,讓手下人產生“主人翁”意識,同時搞制衡之道,效仿春秋二桃殺三士的故事,讓員工們爭相效忠,總之,靠著厚黑之道,將風箏背后的那根線牢牢地掌控在自己手中。
也許是深知惹毛工程師的慘痛下場,電子類公司的老板對待工程師們更有人性一些。在畫大餅、吊胡蘿卜一段時間后也會忍著心痛犒賞犒賞大家伙。但是,開公司畢竟不是請客吃飯,還得有錢賺。
于是,不能拿人開刀的老板們就把目光放到了物料上面。
如果一件產品的物料成本能節省10塊,賣出去1萬件便是10萬,10萬件便是100萬。數學運算算得賊溜的老板們就這樣對物料清單下手了。
一
在小公司里面,老板們親自參與硬件設計不算什么稀罕事。老板經常赤膊上陣,對硬件元器件選型指手畫腳。
作為一名軟件工程師,好整以暇地在旁邊欣賞硬件工程師被老板虐得敢怒不敢言的畫風固然很愜意,但是一旦老板的魔爪伸向MCU這顆關鍵物料之時,我輩也難以事不關己高高掛起了。
那一日,晴空萬里,艷陽高照,不才正沐浴在午后的陽光中,品著茶香,感嘆著歲月靜好:“其香悠遠兮扶搖登宵,其味空靜兮潛藏于竅!”
不才搖著頭,晃著腦,感覺到歡快的自我就快要出竅,全然沒有發現悄悄來到面前的領導。
“咳咳”,一聲短促的咳嗽,帶著熟悉的壓迫感將我從浮生若夢中驚醒。不才趕緊從半躺的姿勢中坐起,差點閃著媳婦所言“用進廢退”的老腰。
“馬步君,看看我手里這個板子。”領導帶著看似神秘莫測、其實沒有什么意義的微笑,把一個電路板遞給了我。
不消說,來任務了!從天堂掉落人間的我心中一個咯噔,看著手里的電路板,內心蕩漾個不停:“這板子看著不算復雜,這等小活一般是不會安排給我的,莫非領導開恩?”
這邊廂,不才心中火光電閃,轉個不停,那邊廂,領導打開了話匣子,講起了原委。
原來,這是別的公司給我司一個客戶批量供貨的產品,現在客戶要求對產品進行升級,希望在硬件電路基本不改動的情況下,添加一些功能,客戶為了保證供貨安全,把我司列入了備胎供應商之列。
具體情況交代完之后,領導把不知從哪里搞來的原產品電路圖發給了我,讓我評估一下不改電路、完全抄板的情況下,能不能實現產品升級。
二
“我真傻,真的,”事后,我經常抬起帥氣逼人的眼睛來,祥林嫂似對同事說。“我單知道在設計新產品的時候為了控制成本,領導會插手MCU的選型;我不知道升級別人產品的時候也會這樣。”
當我把“不需要改電路,只需要換一下引腳兼容、資源更豐富一點的MCU”的結論告訴領導時,領導及時地制止了我的“無理要求”。
“客戶是把產品升級了,但是產品的價格基本未動,加的功能也不算太多,MCU就不要換了吧。想想辦法,能省一塊是一塊嘛!”
看著領導那副欠揍的笑臉,我據理力爭,“天之道,損有余而補不足......”
“別吊書袋子了,硬件資源不夠,軟件功底來湊。所以才把這么艱巨的任務交給你嘛!”
得,認命吧!
資源受限,編程自然處處是挑戰。具體到這個產品上,我發現挑戰最大的一點便是:定時應用特別多,MCU的定時器又特別地少。
硬件定時器的數量遠遠少于定時應用的數量,顯然無法為每一個定時應用單獨分配一個硬件定時器。本來一個蘿卜一個坑最好辦,現在資源不夠怎么辦?
不才就不賣關子了,方案當然是用軟件的有余彌補硬件的不足了。
為了各個定時應用的起點相同、步調一致,同時為了編程的統一,最好的方式便是在單個硬件定時器的基礎上模擬實現多個軟件定時器,以前臺硬件定時器中斷服務程序和后臺軟件定時器管理程序相結合,實現單次定時、多次定時和循環定時應用。
三
不才不屑藏私,下面就把具體的方案設計給各位看官們分享出來。
先跟大家建立這么一個概念:
程序設計=數據結構+運算
具體到這里,數據結構便是“軟件定時器”,運算便是中斷服務程序(ISR)和定時管理程序。
軟件定時器是“結構體”形式,根據定時應用的特點及分類,設計一種涵蓋單次定時、多次定時和循環定時三種類型定時的軟件定時器節點的數據結構,使用一個靜態分配的軟件定時器節點數組來定義所有的定時任務。
這個結構體有以下幾個成員變量:軟件定時器ID、激活狀態、定時次數、超時次數, 循環標識,定時值, 計時值, 回調函數,這些成員變量的意義大多數可以“顧名思義”,這里便不贅述了。
下面開始叨ISR和定時管理程序。
ISR和定時管理程序是靠一個叫“相對計時時間”(記為Timer_TIcked)的信使扭結在一起的,它表示未被軟件定時器計時的時間。
MCU上電初始化時,設置硬件定時器的中斷周期為T并使能中斷,硬件定時器以T為時間間隔,觸發MCU執行ISR。在ISR中,累加相對計時時間的數值,累加值為T,即TImer_TIcked += T。
定時器管理程序完成對軟件定時器節點數組的操作后,清零相對計時時間,所以,只要程序設計地合理,TImer_ticked不會很大,超過20ms基本可以確定您的程序設計有毛病了。
總之,通過相對計時時間,保證了所有軟件定時器節點的同步計時和準確計時。
ISR當然簡單,接下來便是稍微復雜一些的定時管理程序了。
定時管理程序是管理所有定時應用的,每個定時應用對應上述結構體數組里的一個成員,可以以“節點”來稱呼它。
定時管理程序是在后臺循環執行的,它每次都會檢查所有定時器節點的狀態,如果該定時器節點處于空閑狀態,它就跳過它不做處理,如果處于激活狀態,它就增加該定時器節點的計時值(累加值為Timer_ticked)。
然后判斷計時值是否超過了所設定的定時值。如果沒超過,那就跳過它不做處理,如果超過了,先調用它的定時回調函數,然后判斷該節點是否為循環定時器。
如果不是循環定時,跳過它不做處理,如果是,則需要重啟本定時器節點。
按照這種方法處理完所有定時器節點之后,便可以退出本次定時管理程序了。
講到這里,各位看官應該看明白了吧.
四
小米手機物美價廉,沒來由地擔上了“低價誤國”的罵名。國外的MCU廠商倒是雞賊得很,一分錢一分貨,資源豐富一點,價格就漲上去了,赤果果的資本家嘴臉。
所以,在成本的約束以及領導的威嚴下,在一個資源受限的MCU上搗鼓代碼成了嵌入式軟件工程師日常工作的常態。不過,不要抱怨,也不用憂慮和焦心,辦法總比困難多。
總的原則就是:硬件不夠,軟件來湊。
比如對于多個定時應用,單定時器就足夠!