2011年7月30日 星期六

寫韌體,就不需要懂軟體嗎?

軟體、韌體傻傻分不清,這個討論我相信已經討論1x年了,小弟不才,也許更久。相信時代變遷得如此快速,1x多年的老前輩應該有深深的感觸吧。但如果想知道實際上的分別,還是到wiki上詳細閱讀吧。


我想分享的是:寫韌體,就不需要懂軟體嗎?


如果問多數人,韌體工程師的工作。我籠統點說,絕大多數人會認為:"看spec操作IO的工作"、"寫MCU"、"寫一台機器的軟體,但機器看起來不像電腦",就是韌體工程師的工作,所以公司與個人也是以軔體工程師去求才或求職。所以韌體工程師的確是此類工作的代名詞。這種工作有很多的竅門與專業知識,比如說:使用示波器、邏輯分析、電表、甚至頻譜分析儀來協助工作,也要看懂電路圖,以及電子電路的常識。但是這僅止於driver的部份,也就是你的產品想要賣錢,不是只要把driver做好就可以,一定還要有軟體才能完成一個產品。

天不從人願,哪有韌體工程師只要寫driver這個好康的事?當然要繼續往上開發出功能才行阿!不然你都會C語言了,老闆當然覺得你應該可以勝任。這時你應該知道如果推辭或擺爛,那你就被打入永遠寫driver的冷宮,老闆就會再找軟體的人來取代你,或是跟你合作,你就賺不到更多錢。我奉勸此類的朋友,持續的向上學習才是王道。所以這文章也是寫給努力向上的人看的。OK,既然要合作或是學習,韌體工程師就不能置身事外。韌體工程師最終還是要關心軟體領域會發生的問題,縱使你寫的軟體是放在flash或eeprom,而變成自詡為韌體工程師,但你卻因此不繼續探索軟體領域的解決方法,這想必是緣木求魚。

韌體要coding,軟體要coding。只要是一群人合作一起coding,不管他是coding來控制硬體,還是coding來UI的,還是coding來網頁的,甚至是用嘴巴coding的,都一定會遭遇到一些問題:

  1. 版本管理
  2. debug,而且具有非常不平衡的性質。就是可能改錯1個字,或是一行,都有可能造成嚴重錯誤。
  3. 不可預測性,常常計畫趕不上老闆一句話,韌體有時也是會牽連修改。只要修改,就可能有bug。
這些問題,如果不知道方法處理的team,就是以吵架收場。不知道該怎麼去處理,一而再再而三的prj延宕,讓老闆失去耐心後,你不解決問題,就是等著被老闆解決。

這些問題只是軟體開發的冰山一角,韌體開發的coding,還可以再寫一堆落落長的注意事項...。看,不可否認,即使你原本是韌體工程師,可能只寫driver或MCU的程式,最後還是會遇到這些問題。所以我只講版本管理就好,就像是使用svn、git這類工具,即使你是寫8051或寫driver或者是寫 " 放在rom裡的軟體 " ,你都必須管理版本。當然軟體的領域不只有版本管理這個項目,Bug tracking system、Jenkins CI、Agile、UML...這些也只是團隊合作上的工具,在整個軟體系統建構的過程中,還有好多好多東西要學的。先前分享的書裡面就有提到很多像是coding、design pattern、testing..etc.:



無論你是用什麼程式語言,無論你寫完的程式是放在哪裡跑,這些知識都有助於你解決問題。韌體這名詞對我來說,可說是寫完的軟體放到比較不容易修改的ROM裡面的Release方式罷了。所以我認為,絕不要因為自稱為韌體工程師就不去使用自認為"純軟體"在用的工具知識,或者認為自己不吃軟體工程這一套。只要是對解決問題有幫助的知識,就應該持續向上學習與虛心的跟別人合作,才是工程師的生存之道。


我結論是:原本寫韌體,想要更上層樓,就要朝向軟體發展。因為簡單來說沒有韌体工程這門學科。




2011年7月21日 星期四

當一個很大包的程式(之後稱”母體”),逐漸變成一個怪物時,會有很多人抱怨寫的太亂,寫得太難看懂。或是你的專案賺錢後,請了越來越多的人,發現到一直在重覆處理相同的問題。這時候要進行分解的動作,好讓你下面的人可以繼續專業分工。但是怎麼分解才不會影響到程式的穩定,與保持版本追蹤。我有一套流程。我分為幾個面向:

I. Source Code

為新模組寫一個新的makefile。makefile裡面重新加上要編在library裡面相關的.o與.a。



當然make以後會發現到有很多未定義的symbol。因為已經從母體分出,當然會有很多與母體連結的symbol。現在要將之拆散,勢必要重新實作出這些東西。所以事先規畫非常重要,你要先找出一個耦合度最低的部分來分解。



這些東西要實作在哪邊呢。我是新增一個.c檔,通常稱作xxx_Interface.c,將所有未定義的symbol,先定在這個.c中,使library通過編譯,讓自己對這library有個概觀,也形成一個骨架。未來再回來把內容補滿 。



II. Git版本操作

A. git branch xxxlibrary,加上#define的同時,也加上一個branch。從這個branch加入library。

B. 如要移動檔案,先改make裡面的路徑,而不要先移動檔案。因為移動了檔案,檔案如果需要修改,將來變得很難比對。先改makefile裡的檔案路徑,完成commit之後,再進行移動檔案。

C. 改完後commit。



III. Release

當library建立完成後,跟主線merge,並且在母體的Makefile裡面加上類似-Dxxxlib的定義。好讓source code裡面能選擇要不要link到新的library。這樣子就能夠在git中,追蹤新library以及原本未切出的部分了。

Jenkins notes

wget -q -O - http://pkg.jenkins-ci.org/debian/jenkins-ci.org.key

sudo apt-key add -

sudo sh -c 'echo deb http://pkg.jenkins-ci.org/debian binary/ > /etc/apt/sources.list.d/jenkins.list'

sudo aptitude update

sudo aptitude install jenkins





sudo aptitude install apache2

sudo a2enmod proxy

sudo a2enmod proxy_http

sudo a2enmod vhost_alias







************************改Port************************



Change /etc/default/hudson and add this to passed in arguments:

HUDSON_ARGS="--httpPort=8081 --webroot=/var/run/hudson/war"





************************為jenkins加上gitosis的ssh key************************



參考http://shreevatsa.wordpress.com/2005/11/17/ssh-keygen-as-another-user/



主要是在自己的帳戶路徑內,產生一個key pair,然後將.pub這個publish key,cp到你要登入目標的.ssh/authorized_keys裡面。

這等於連去對方的時候,對方的ssh會對照.ssh/authorized_keys是否與你擁有的private key是一對的。



然後就可以登入

sudo ssh -i id_rda_jenkins jenkins@10.1.5.203







************************設定目標專案的sudo免打密碼************************



在最後一行加上,sudo的權限是從上到下,任何最下面的設定都會蓋過上面的

hawk ALL=(ALL) NOPASSWD: ALL





************************設定某個repository被git push後,觸發jenkins************************



在server上bare git repository裡面的hooks 裡面加上一個名為post-update的可執行檔,內容是:

curl http://${JENKINS_SERVER}:${PORT}/job/${PROJECT_NAME}/build?delay=0sec

就會在有人作了push動作以後,執行jenkins裡設定的build script。

Build Script裡面就可以寫個repo sync去同步所有的git。





************************安裝jenkins衝到其他網頁************************



將http://10.1.5.203/jenkins 引導到8081

在default的最尾巴加上proxy的設定



#sudo vi /etc/apache2/sites-available/default







...



ServerName ci.company.com

ServerAlias ci

ProxyRequests Off



Order deny,allow

Allow from all



ProxyPreserveHost on

ProxyPass /jenkins http://localhost:8081/jenkins







#sudo a2ensite default



參考http://www.zzorn.net/2009/11/setting-up-hudson-on-port-80-on-debian.html

2011年7月17日 星期日

一種漸進式的記憶體配置策略

相信很多人都有想過這個問題:到底要不要用malloc來配置記憶體呢?要?或不要?都有人贊成與反對。我剛好腦袋突然閃過一個想法,可以回答這個問題。

大家都知道malloc是配置記憶體在heap中,一定要有一個free來將記憶體釋放。但常常都會聽到memory leak這個惡名昭彰的後果。除非就是在程式一開始的時候就要妥善安排一個介面來保證讓malloc與free成對出現。但是有這麼多的人要coding,有這麼多人的要寫thread,最後還是有可能會漏掉。除非你們的team,有採用更好的處理方式以及更嚴謹的code review流程,否則這個夢饜是如影隨形的。

我過去參予了一個DVR的案子,覺得這個方法不錯,這也是某一個老大規定這麼做的。規定其實很簡單,就是專案一開始就不要使用malloc。我覺得有點道理,因為在嵌入式系統的專案中,每一個功能都是需要能運作,幾乎沒有什麼"這個程式即將關閉"的介面讓使用者能夠選擇是否繼續執行。既然每個功能都要保證能動,那記憶體一定要夠執行所有工作才行。

這時,誓死使用malloc的看官一定已經要轉台了。別急,其實這麼做是有道理的。"專案一開始"不使用malloc,這讓我想到用Continue Integration(CI)的精神來解釋。

專案一開始的程式,一定是相對穩定的。如果您不懂我的意思,我舉個極端例子,當你一開始從main開始的時候,裡面只有一行printf("foo");。請問,這樣子會有bug存在嗎?

好,CI的精神就是靠著連續地整合,讓版本之間都彼此有關聯,如果一有問題就能夠藉由每次的版本來找出問題所在。如果一開始就不使用malloc,是不是整合到最後的版本,也都不可能會有memory leak,對吧?

所以,在你的run time時期的記憶體大小還許可的情況下,都不要開始使用malloc。讓你開心地解掉bug,而且完全不需去考慮某個解不掉的bug是否為memory leak的問題。直到你的穩定版本釋出後,如果記憶體真的不足了,或是老闆想要cost down,再考慮以"穩定"的版本去使用malloc,利用CI甚至Unit Test,來讓你的版本一直穩定下去。

但如果平台記憶體非常的少,一定要使用malloc才能繼續開發下去,那就要另尋他法了...。

整修紀實

話說,住在小套房已經4年了,度過了1300個日子。婚事,工作都已搞定,接下來就要搬到大一點的房子了,原本的9坪小套房實在是塞不下即將要出生的小朋友與他的東西。


套房裡的客廳


這算是...臥房吧,,,

是不是已經太擠了呢?照片都覺得擠了,更別說在裡面住了。不過先前從淡水的4坪套房搬來時,覺得9坪好大喔~~。但隨著時間增加,囤積的"商品"也越來越多。接下來又有一位男士要出生了,他的東西也會繼續囤積,所以非搬不可了。

中間找房的過程就別在這兒說了,反正就是狠下心就對了啦!!  在台北生活的重點就是工作,物價雖然高,但薪水卻還可以支付。反正買下去就是努力工作就對了,希望我賣我的專業能提供我撐到下次金融海嘯來...。


於是就來看看原本的隔間,原本是個老太太在這邊生活,她的裝潢都是木工的,我想當初的價錢應該蠻貴的吧。

走道,有開個窗戶


整體評估下來,覺得隔間太多了,並沒有空曠的大廳。因此我就自己用google sketch規劃了一個格局。這一畫下來,整個搬家過程就很清楚,格局完工以後傢俱可一次到位,不會喬來喬去的。


現代人比較喜歡一進門就是寬敞的大廳,跟上一代的廳明房暗不同,所以把L型的轉角拆掉,形成一個客廳。並且運用原本的走道來放電視,這樣子客廳就會變得寬敞許多。

把原本的木造格局拆掉,拆的過程中其實有點不捨,因為木工很貴。
木工格局拆掉後,改用輕鋼架來格出一間小房間,預計當做書房

輕鋼架半完成,我把原本屋主古色古香的木頭窗框留下來,給房間通風用,也讓整個空間感覺活潑點。

因為坐落民生西路大馬路,不裝氣密窗實在有夠吵的

原本的鋁門窗,並沒有把中間填實,如果外面防水有漏洞,水就會積在裡面造成璧癌。

我請的這間鋁門窗就把它用水泥填平了。不然很多鋁門窗都不搞泥作,會叫你另外請水泥師父。但這間泥作不加錢,作完讓我蠻放心的。

氣密窗裝完了,雖然還是有噪音。但是以量化來講,噪音大約從70分貝降到了40到50分貝
我用Android的Sound Master量的


2011年7月16日 星期六

好忙的民國100年

99年,9月:得知懷孕,開始計畫成家事宜。
99年,10月:在苗栗被一個阿罵撞,還說要告我...。
100年,1/23:於台北國際飯店結婚。
100年,2/28:於高雄富苑餐廳補請。
100年,3月:北高工作大抉擇。
100年,4月:找房子,看是要租還是買。
100年,5月:找到房子了,自己找輕隔間、油漆、水電、鋁門窗、搬家,真的超累的...。
100年,6月:5/31兒子出生。
100年,7月:終於....有一個家了,有一個字,累...。