Language

Tuesday, December 18, 2012

GNU Radio Talk: A Glimpse into Developing Software-Defined Radio by Python

這是我十二月十七日在 PyHUG(一個新竹的 Python 社群, 由陳永昱(Yung-Yu Chen) 博士與我在 2011 年所組織發起的)講的講題, 內容簡介了軟體無線電的概念, 軟體無線電的硬體以及開源的專案 GNU Radio, 以及使用 GNU Radio 來開發軟體無線電的三種不同路徑的簡介。這是 GNU Radio 系列講題的第一個, 接下來的講題目前未定, 可能會從數位訊號處理的概念以及如何使用 GNU Radio 來作濾波器先切入, 然後再看聽眾反應決定接下來的主題。有任何建議都歡迎提出來!

PyHUG 目前的聚會模式是每個月的第一與第三個星期一晚上, 通常都會有一個或一個以上的二十分鐘短講, 地點在交大計中一樓訓練教室, 所有訊息都是透過 meetup 這個網頁來公告, 你可以到這裡看相關訊息。

The slides were given to PyHUG in December 17, 2012 in PyHUG, which is Python Hsinchu User Group initiated by Dr. Yung-Yu Chen and I in 2011. In this talk, I introduced the concept of software-defined radio, the free & open source software-defined radio project - GNU Radio, RF front-end hardware that can be used with GNU Radio provided by Ettus Research and Realtek, and illustrated three ways to develop software-defined radio by GNU Radio. This is the first of GNU Radio series talk, the topics for the subsequent talks are to be done, and I'll probably start from using filters in GNU Radio as well as concepts of digital signal processing. And then I'll try to decide topics depending upon feedback of attendees. Any idea or suggestions are welcome!

Currently we have regular meetings on the first and the third Monday nights every month at the training classroom in the building of computer center in National Chaio-Tung University. Normally there will be one or two 20-minute talks. All messages related to PyHUG meetings or events are distributed via meetup website, and you can find information here.

Download/view slides of "A Glimpse into Developing Software-Defined Radio by Python"

Saturday, December 15, 2012

工程訓練與人文素養


工程訓練與人文素養, 一個是左腦, 一個是右腦, 一個需要理性, 一個需要感性, 看似非常衝突的兩個面向, 但我覺得是一個工程師必須同時要具備的兩個面向。


工程師, 尤其是電子電機工程師, 在現代的社會及媒體上, 有著許多不同的稱號, 比如說: 科技宅男、竹科新貴,中國大陸還有張江男之類的稱號, 其實都帶有些許戲謔的成分在。但回首過往, 被譽為中國鐵路之父的詹天佑(1861-1919), 不就是一名工程師嗎?他幼年就留學美國, 後來回近代中國修築了中國第一條鐵路, 並且修築了難度頗高的京張鐵路, 不僅帶給當代中國交通上的便利, 更因修築了外國人認為中國人不可能辦到的鐵路而激勵了當時的華人世界。更現代一些, 我們都在國中小學課本裡面讀過的作者, 陳之藩先生(1925-2012), 寫了不少膾炙人口的文章, 被收錄在「旅美小簡」、「在春風裡」、「劍河倒影」、「一星如月」等等, 我想在台灣應該是幾乎每一個人都讀過陳之藩先生的文章, 而他是學電機的, 也是工程師出身。


工程訓練的目的是訓練一個人, 在既有的流程或基礎上, 運用自己所學的知識與理論, 事先籌劃改善的方法, 並預測改善後的成效, 然後著手實踐這個改善方法。因此, 大學的工程相關科系有著非常多的理論與實驗課程, 這些都在養成工程師基礎的知識, 與動手做的能力, 兩者缺一不可, 卻也相輔相成。沒有基礎知識, 不知道實驗結果的真正原因為何; 沒有動手做, 就不知道自己缺乏哪些知識與理論, 也不知道為什麼要學那些理論。


人文素養對一名工程師來說, 乍看之下似乎沒有必要, 畢竟工程師不需要人文素養就能夠成為一名工程師。但是若從工程的本質來看的話, 人文素養又變成不可或缺的一部分。我來給工程下個定義, 把上一段的工程訓練目的稍微擴展一下, 「工程是為了改善人類的生活, 而在既有的基礎上, 運用自己所學的知識, 事先規劃改善方法, 預測改善後的成效, 並且著手實踐它。」既然是為了改善人類的生活, 人文素養能說不重要嗎?工程師做成的產品大部分時候是要給人使用的, 如果工程師在設計的時候, 脫離了「人」來思考, 設計出來的東西不是難以使用, 就是曲高和寡。工程師如果對於人性有所了解, 懂得人, 那麼就能夠很輕易的從日常生活中, 找到改善生活的方法, 讓人類的生活更便利。市面上有一種拖把, 有個桶子, 上面有個轉盤, 在洗好拖把之後可以用腳踩使轉盤轉動, 利用離心力的原理可以輕易的把水甩乾, 就不需要用手擰乾拖把而把手弄髒, 這個產品的問世帶給所有需要打掃的人, 包括家庭主婦與幫理家務的好男人, 非常便利的生活。這個就是因為發明人, 在幫忙老婆打掃家務的時候, 對於整個流程有敏銳與細膩的觀察, 從中找到改善的方法, 並且實踐這個改善的方法。我認為這就是帶有人文素養的工程思維表現。


如果科學家的熱情是來自於研究宇宙的真理, 哲學家的熱情是來自於思考人類的問題, 那麼我覺得工程師的熱情就來自於改善人類的生活。我無法想像工程師只以賺錢為唯一的目的, 也不能是主要目的, 那會讓工程的樂趣整個消失不見, 只剩下金錢遊戲。你能想像廚師只愛賺錢, 而不以做好料理讓客人吃得愉快為熱情嗎?我並不是說賺錢不好, 相反的, 我覺得賺錢很好, 但是以賺錢為目的與熱情的, 有別的職業, 比方說學習巴菲特在股票證券市場上賺錢, 巴菲特就說過他對於賺錢有極大的熱情, 股票與金融市場的即時回報就是金錢, 你把這件事做得愈好, 賺的錢愈多, 如果你的熱情就來自於賺錢, 那麼在證券市場上的即時回報也會讓你的熱情不斷加增。而工程師的即時回報, 是把一個東西改善而變得更好, 而我們心裡知道這些小小的改善累積起來, 就會讓人類的生活變得更好更便利, 但是比較大筆的金錢也許是一年一次的回報, 如果工程師的熱情來自於金錢, 那麼在工程師生涯裡面, 你只有千分之二點七左右(1/365)的時間是有回報來增強你的熱情的, 絕大多數的時間, 你要做你不覺得有趣的事情, 我說這也太痛苦了吧!工程師生涯看似枯燥乏味, 但如果你的熱情來自於改善人類的生活, 那麼這些枯燥乏味的事情, 就會頓時變得很有趣!當你習慣於觀察周遭生活, 找出改善方法, 並且著手實踐它, 誰說下一個改善人類生活的發明家不會是你呢?


--
Albert Huang
Chun-Chieh Huang(黃俊傑)

Wednesday, December 12, 2012

寫實驗紀錄或工作日誌的重要性


從退伍之後, 真的開始有寫程式起, 我就開始寫工作日誌, 一直保持習慣到如今。我從中獲得不少的好處, 今天利用這篇文章來跟大家分享一下。



先從我為什麼開始寫工作日誌講起好了。如同 Donald E. Knuth 在 "Coders at Work"1 裡面所講的, 寫程式是一個很耗腦力, 需要全神貫注的一件事。大家應該都還記得大學要交程式作業前, 常常一寫程式就沒日沒夜, 通宵達旦, 不寫到一個段落不善罷甘休, 但是程式設計的一個段落常常又是一兩天的功夫才會到。萬一還沒寫到一個段落就先休息, 等休息回來又忘記本來的思路了, 於是只好重新思考, 如此會花更多的時間寫程式! 正因為害怕這種事情發生, 於是, 熬夜寫程式就變成了交作業前的常態。大學時作業交完了, 可以好好休息一陣子, 不用每天想程式, 一旦開始工作, 平常的週間五天就要每天寫程式了, 遇到趕專案進度的時候, 可能要一週工作六天!2 因此如何保持每天都能夠有效率的寫程式就變成了一個挑戰與學習, 熬夜變成一個儘量避免的事情, 因為熬夜很容易讓第二天的工作效率大幅下降, 而且晚上最好還是要有自己的生活, 工作才能長長久久的。所以, 我開始寫工作日誌的動機, 就是不想熬夜, 因此, 每天在下班之前, 把當天的工作進度以及對還沒實現的部份的所有想法, 儘量的寫下來, 要足夠清楚明瞭到自己心裡覺得沒什麼好寫了, 而且第二天還能夠看懂。如此一來, 一旦闔上工作日誌, 就可以下班而不會一直擔心自己會忘記原本的想法, 下班後就可以好好放鬆。第二天來辦公室工作的時候, 一看昨天的工作日誌, 也可以很快知道昨天的進度在哪裡, 馬上可以接手繼續下去。



那麼工作日誌要如何撰寫呢?工作日誌的內容可以區分成幾類: 1) 設計 2) 當日該完成事項 3) 工作紀錄 4) 實驗紀錄。



在設計的部份, 筆者的建議是儘量用圖形表示, 因為詳細的文字可能會被紀錄在文件或是程式的註解中, 而圖形是一個描述概念非常有力量的工具, 在工作日誌中就儘量以圖形加上一些重點文字來紀錄你的設計, 這樣在實作過程中可以隨時翻閱設計圖, 可以很快的從程式設計的細節中, 再度回到一個高度來鳥瞰整個叢林, 這樣才不會迷失在樹林中(實作細節)。



當日該完成事項是每天一開始的時候, 告訴自己還有哪些工作還沒完成, 每個工作的優先順序是如何, 這樣在寫任何程式之前, 可以在心中先建立一個清單, 工作效率會大幅提升。如果你有使用萬用手冊的習慣, 那麼這部份就不用太著墨, 只要在執行那個工作的時候, 把工作紀錄寫下來即可。



工作紀錄只要把重點記錄下來即可, 不必把每一個動作記錄下來, 但是要把 know-how 記錄下來, 才不會「知其然而不知其所以然。」



在追蹤某個問題的發生點時, 我們常常做的是如同建立樹狀圖一般, 從 root(issue) 一路往下追蹤到真正發生的原因(root cause), 而常常在分支點時, 都有很多個不同的追蹤方向, 有的時候, 我們會懷疑數個分支都有可能發生問題, 或是我們也許會判斷錯誤導致追蹤錯分支, 甚至有的時候, 一個 issue 是由多個錯誤累積產生的, 就有可能有數個 root cause, 所以數個分支都是問題。這時候有實驗紀錄的話, 就有非常大的幫助。實驗紀錄應該儘量詳盡的紀錄日後可能有幫助的細節, 比如說實驗的設定、過程與結果, 這些都要詳盡紀錄。如果是在追某個或某些 bug, 在分支點時, 應該把所有可能的方向、往這個分支追蹤的判斷理由、每個分支需要花費的成本估計記錄下來, 萬一日後發現不是那麼一回事, 還可以回頭往另一個方向追。或是當某個分支解決之後, 回頭來看該分支所屬的 parent, 看看那個 parent 是不是已經也被解決, 如果沒有, 就表示還有其他原因造成那個錯誤, 就要繼續追蹤其他分支。另外, 很多時候我們可以從統計上來了解我們是否解決完所有的問題, 比方說掉封包的機率(packet dropping probability), 在解網路 driver 或 physical layer 那一層相關問題的時候, 是一個頗適合的測量指標, 我們可以從掉封包的機率的改變看出我們解的問題佔的比例有多大, 是否已經解決大部分的問題。當然, 當掉封包的機率很小的時候, 也不代表我們把問題解決完了, 這時候可以用亂數的方式產生封包來找出我們可能沒發現的問題。這些猜測, 以及某個 root cause 解決完之後的掉封包機率的改變都要寫下來。以掉封包機率而言, 某個 bug 解完之後, 如果沒有一個數量級(10 倍)以上的改變, 那這個 bug 可能跟你的 issue 沒有太大相關。再來, 如果你做實驗之後發現傳送 1000 個封包之後, 掉了 1 個封包, 這時候也至少要把測試數量提升一個數量級以上, 也就是至少傳送 104 個封包來測試掉封包機率。



在每天工作要結束前, 重頭再把工作日誌翻閱一遍, 看看今日的工作還有哪些沒有完成, 然後要紀錄腦袋裡對於今日的工作還有什麼想法, 未來該追蹤的方向是什麼, 總之把心中覺得未完成的東西紀錄在紙上, 這樣心中就不會有牽掛, 之後也不會因為忘記某些非常好的想法而扼腕。



手寫的工作日誌最好有索引, 把每天的主題用一句話統一寫到那本工作日誌的開頭或結尾的地方, 以便日後快速翻閱。每個月或每一季再花一點時間把工作日誌重點整理一次, 以供日後學習之用, 如此就可以累積寶貴的經驗。



工作日誌以內頁的記號, 可以分成方格、直線、網點與空白。每個人都有不同的選擇, 方格與網點適合繪圖或實驗紀錄, 直線適合文字比較多的紀錄, 空白是比較少使用的格式, 但是限制也最少。我個人覺得方格頗適合繪圖, 會很鼓勵使用的人用圖形來表示, 比較適合創意多的設計。而直線則比較中規中矩, 會鼓勵使用的人用文字來呈現, 比較適合不需要圖形表現的紀錄。



在今天的文章裡, 我分享了過去十幾年我寫工作日誌的經驗與方法, 我從紀錄工作日誌的習慣, 以及整理工作日誌的重點, 學習到非常多自己在業界的經驗, 這些經驗都非常寶貴。各位在看完之後, 也許能夠從中獲得一些靈感, 也開始寫工作日誌, 並且享受到下班就把一切放下的愜意!有句話說:「經驗是你最好的老師」,在用工作日誌的形式來紀錄與整理你的經驗之後, 經驗絕對會變成你很好的老師!



Footnotes:



1 Peter Seibel 著、蔡學鏞 譯, 「編程的頂尖對話-閱讀 15 位軟體大師的核心思維」, 碁峰, 民 100 年。



2 筆者建議星期天還是好好休息, 以筆者過去的經驗, 如果每週工作七天沒有休息, 兩週之後每一天的工作效率大概就只剩下 50% 不到吧, 終究是要還回去的, 所以還是以每週工作六天為最大限度。





--
Albert Huang
Chun-Chieh Huang(黃俊傑)

Tuesday, December 4, 2012

平均同步訊號的意義 - 如何處理雜訊


這個世界上的事情基本上是不可預測的, 在訊號處理上, 我們把不能夠預測的部份都當作是雜訊來看待, 然後用統計的觀點來看我們想要的訊號。



在這篇文章裡, 筆者會介紹對待雜訊最基本的工具: 平均, 以及在平均這個運算上, 我們能夠得到什麼樣的好處, 也就是能夠得到多少增益(gain), 這樣我們就知道需要花多少次的平均能夠得到我們想要的結果。為了比較容易說明平均, 在這篇文章裡, 筆者只先專注在同步訊號的平均, 而這也是示波器的基本原理之一。






同步平均 (Coherent Averaging)




訊號有分非週期性與週期性序號, 要能夠同步, 必須是週期訊號, 所以像語音訊號這種非週期訊號, 我們就先不討論。週期訊號裡面, 又以正弦波在頻域上最單純, 所以我們先來看一段正弦波。這是週期為 20 的正弦波, 圖上總共兩個週期:

From SignalAveraging


我們把上述的數位訊號表列如下:




















X(0)X(1)X(2)X(3)X(4)X(5)X(6)X(7)X(8)X(9)
0.00000.30900.58780.80900.95111.00000.95110.80900.58780.3090
X(10)X(11)X(12)X(13)X(14)X(15)X(16)X(17)X(18)X(19)
0.0000-0.3090-0.5878-0.8090-0.9511-1.0000-0.9511-0.8090-0.5878-0.3090
X(20)X(21)X(22)X(23)X(24)X(25)X(26)X(27)X(28)X(29)
-0.00000.30900.58780.80900.95111.00000.95110.80900.58780.3090
X(30)X(31)X(32)X(33)X(34)X(35)X(36)X(37)X(38)X(39)
0.0000-0.3090-0.5878-0.8090-0.9511-1.0000-0.9511-0.8090-0.5878-0.3090




那麼平均這兩個週期的正弦波(週期為 20) 的動作就是:



Xavg(0) = X(0)+X(20)



Xavg(1) = X(1)+X(21)






Xavg(19) = X(19)+X(19+20)



最後 Xavg(0:19) 就會是平均後的正弦波, 如果以 N 來代表取平均的週期數, 而週期以 T 來帶進去, 那麼我們的運算式子會變成:



Xavg(i) = ( X(i) + X(i+T) + X(i+2*T) + … + X(i+(N-1)*T) ) / N, i = 0..T-1



上述的訊號還是相當的純淨沒有雜質, 看不出平均的意義, 接下來我們來看加入雜訊之後的樣子, 我們假設雜訊是 WGN(White Gaussian Noise), 意思是這些雜訊的振幅符合 Gaussian 分布, 而雜訊彼此之間沒有關聯, 白色表示頻譜一致分布在頻域上。



我們讓訊雜比是 0 dB, 意思是雜訊跟訊號的功率是一樣的, 訊號加雜訊會如下圖所示, 圖中的 N 代表平均的週期數:

From SignalAveraging


如果我們平均 2 個週期, 看起來還是跟 N=1 時差不多:
From SignalAveraging


如果我們平均 16 個週期, 稍微好一點點了:
From SignalAveraging


如果我們平均 1024 個週期, 喔, 已經開始有蠻漂亮的訊號形狀了:
From SignalAveraging


如果我們平均 4096 個週期, 哇, 訊號又更明顯了:
From SignalAveraging


如果我們平均 65536 個週期, 這個已經幾乎就跟沒有雜訊一樣了, 我們很少有機會能平均這麼多次, 放在這裡是要讓讀者明白平均的威力:
From SignalAveraging


我們把原來的純淨訊號與 N=65536 平均後的訊號放在一起看:
From SignalAveraging

From SignalAveraging


所以從上述幾張圖一路看下來, 很明顯的平均同步訊號能夠讓訊號浮現而雜訊變小, 用訊號處理的術語就是有增益(gain), 那麼我們從平均能夠得到的增益是多少呢?接下來我們來仔細算一下。







增益




假設我們想要得到的常數訊號振幅是 A, 而雜訊是 N(n) 那麼我們接收到的訊號 r(n) = A + N(n), 在統計上, 我們可以把 A 當作是這個 distribution 的平均值。雜訊的振幅, 亦即 r(n) 的標準差是 sigmain。



在雜訊本身的 distribution 不變的情況下, 取 N 個取樣做平均之後, 其標準差會變成:



sigmaavg = sigmain / sqrt(N), 亦即平均 N 次之後的標準差為原來的標準差除以根號 N。



原來的訊雜比 SNRin = A / sigmain



平均後的訊雜比 SNRavg = A / sigmaavg



Gain = SNRavg / SNRin = sigmain / sigmaavg = sqrt(N)



把增益用分貝表示: Gain = 20*log10(sqrt(N)) = 10*log10(N) dB, 第一個 log10 乘以 20 是因為這是振幅。



把之前的平均次數能夠得到的增益做成表格, 如下所示:















NGain(dB)
10
23.01
1612.04
102430.10
409636.12
6553648.16










結語




只要在現實生活中處理訊號, 免不了的就是要處理雜訊, 這是痛苦的地方, 也是這個世界迷人有趣的地方。如何與雜訊共存, 或是把雜訊對我們的影響變小, 是我們每一個要處理訊號的工程師必須要面對的問題。在這篇文章中, 我們了解到了在訊號同步的情況之下, 如何透過同步平均(coherent averaging) 來改善訊雜比, 使我們要得到的訊號「浮出水面」, 以及要作多少次平均可以得到多少增益, 將來各位如果遇到需要處理訊號的時候, 有最基本但也非常有用的工具可以把雜訊消除。







參考書目




Sheldon Ross, "A First Course in Probability," 6/e, Prentice-Hall, 2002.



Richard G. Lyons, "Understandding Digital Signal Processing," 3/e, Prentice-Hall, 2011.




--
Albert Huang
Chun-Chieh Huang(黃俊傑)

Saturday, December 1, 2012

在 MacOSX 10.8.2 上安裝 GNU Radio 3.6.2 與台幣九百元的軟體無線電硬體rtl-sdr


GNU Radio1 是一個軟體無線電的自由軟體, 是以 Python 寫成, 在需要執行速度快的元件則改用 C++ 來撰寫。我們可以把 GNU Radio 視為 Python 的訊號處理函式庫。

軟體無線電不論如何, 還是需要一個硬體來接收訊號, 你可以使用音效輸入接收來自於無線電接收機的音效輸出, 或是直接用一個無線電接收前端設備來接收來自於天線的訊號。Realtek RTL2832U 原本是 Realtek 這家晶片設計公司設計的 DVB(數位電視廣播) 接收機晶片, 他的設計就是前端接收機把類比訊號轉成數位訊號後, 就透過 USB 2.0 的介面傳送進電腦作後續的數位電視廣播解調工作, 可以說是軟體無線電的應用, 經過 hacker 們的努力以及 Realtek 還算友善的服務之後, 於是我們就可以把 Realtek RTL2832U 晶片的數位電視棒2用在 GNU Radio 的軟體上, 也就是 rtl-sdr3 這個軟體套件。

原本在 MacOSX 上面要 build GNU Radio 是困難重重啊, 但是經過 Michael Dickens 的努力之後, 現在在 MacPorts 2.1.2 上面可以非常容易的安裝 GNU Radio, 不過要安裝 rtl-sdr 還是有一點小小的技巧, 筆者就利用這篇文章來紀錄安裝過程並分享給有需要的人。



要先安裝的 MacPorts 2.1.2 套件


這些套件是要編譯 GNU Radio 所需要先安裝的 MacPorts 2.1.2 的套件,
如果你利用 MacPorts 2.1.2 來安裝 gnuradio 的話,
這些相依套件會自動被安裝, 筆者把這些套件列出來當作參考:


  • python27

  • py27-cheetah

  • cmake

  • mercurial

  • boost

  • sdcc

  • doxygen

  • sphinx

  • py27-sphinx

  • cppunit

  • fftw-3-single

  • swig

  • gsl-devel

  • guile

  • ccache

  • libusb
    libusb-devel is obsoleted by libusb

  • py27-numpy

  • py27-gtk

  • py27-scipy

  • py27-lxml

  • py27-matplotlib








Install GNU Radio 3.6.2



感謝 Michael Dickens <mlk@alum.mit.edu> 的努力, 現在 MacPorts 2.1.2 可以直接安裝 GNU Radio 3.6.2, 也可以直接安裝 GNU Radio 最新的 next branch, 安裝 gnuradio 有一些選項可以選:
$ port info gnuradio
gnuradio @3.6.2 (science)
Sub-ports:            gnuradio-devel, gnuradio-next
Variants:             debug, docs, full, grc, jack, orc, portaudio, python26,
                      python27, qtgui, sdl, swig, uhd, universal, wavelet, wxgui

Description:          GNU Radio Software Defined Radio: This port is kept up
                      with the GNU Radio release, which is typically updated
                      every few months.
Homepage:             http://gnuradio.org/

Build Dependencies:   cmake
Library Dependencies: boost, cppunit, fftw-3-single, pkgconfig
Conflicts with:       gnuradio-next, gnuradio-devel
Platforms:            darwin, macosx
License:              GPL-3
Maintainers:          michaelld@macports.org, openmaintainer@macports.org

我安裝的時候下的命令是:
$ sudo port install gnuradio +docs +grc +orc +python27 +qtgui +sdl +swig +uhd +wxgui


安裝成功後, 可以用以下命令檢查:
$ port installed gnuradio
The following ports are currently installed:
  gnuradio @3.6.2_0+docs+grc+orc+python27+qtgui+sdl+swig+uhd+wxgui (active)





Install rtl-sdr library




Check out rtl-sdr library:
$ git clone git://git.osmocom.org/rtl-sdr.git


Building with cmake:
$ cd rtl-sdr/
$ mkdir build
$ cd build
$ cmake ../ -DINSTALL_UDEV_RULES=ON
$ make
$ sudo make install


Check out gr-osmosdr
$ git clone git://git.osmocom.org/gr-osmosdr
$ cd gr-osmosdr/
$ mkdir build
$ cd build/
$ cmake -DPYTHON_EXECUTABLE=/opt/local/bin/python -DPYTHON_INCLUDE_DIR=/opt/local/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -DPYTHON_LIBRARY=/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/libpython2.7.dylib -DCMAKE_INSTALL_PREFIX:PATH=/opt/local ../
$ make
$ sudo make install


Mac 系統會把 osmosdr 這個 python 的 module 裝到 /opt/local/lib/python2.7/site-packages 裡面, 這會造成執行 gnuradio 的錯誤, 請執行以下的命令把 osmosdr 目錄搬移到 /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages 裡面:
$ sudo mv /opt/local/lib/python2.7/site-packages/osmosdr /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages


安裝完後, 大家就可以開始使用 rtl-sdr 來接收無線電訊號了, 理論上 RTL2832U 能夠達到最大的取樣率是 3.2Msps(mega sample per second), 不過每台機器都不一樣, 先來測試一下, 在你的機器上可以達到最大的取樣率是多少:
$ ./rtl_test -s 2.4e6
Found 1 device(s):
  0:  Compro Videomate U650F

Using device 0: Compro Videomate U650F
Found Elonics E4000 tuner
Supported gain values (14): -1.0 1.5 4.0 6.5 9.0 11.5 14.0 16.5 19.0 21.5 24.0 29.0 34.0 42.0 
Reading samples in async mode...



上面是筆者的 MacBook Pro core i7 能夠達到最大的取樣率 2.4Msps, 測試的方法就是從 3.2e6 不斷的往下調, 直到沒有 lost bytes 為止, 那就是在你的機器上能夠達到的最大取樣率。


另外, 每一個 RTL2832U 的 DVB dongle 都有不一樣的 tuner, 可以用以下的命令來看你能夠調整頻率的範圍:
$ ./rtl_test -t



筆者的機器上的結果是:
$ rtl_test -t
Found 1 device(s):
  0:  Compro Videomate U650F

Using device 0: Compro Videomate U650F
Found Elonics E4000 tuner
Supported gain values (14): -1.0 1.5 4.0 6.5 9.0 11.5 14.0 16.5 19.0 21.5 24.0 29.0 34.0 42.0 
Benchmarking E4000 PLL...
[E4K] PLL not locked for 52000000 Hz!
[E4K] PLL not locked for 2203000000 Hz!
[E4K] PLL not locked for 1102000000 Hz!
[E4K] PLL not locked for 1248000000 Hz!
E4K range: 53 to 2202 MHz
E4K L-band gap: 1102 to 1248 MHz




接下來就可以利用這個來接收訊號了, 可以把取樣到的訊號存在檔案, 或是利用 GNU Radio 來接收, 這個例子可以把中心頻率調到 392 MHz, 並以取樣率 1.8 Msps 抓取訊號並存在 /tmp/capture.bin 這個檔案中。
$ ./rtl_sdr /tmp/capture.bin -s 1.8e6 -f 392e6


如果要利用存下來的檔案, 可以用 這篇文章 提到的 FM 解調器(rtl2832-fm.grc) 來解開來。當然, 你要先能夠把中心頻率調到正確的位置上, 還要有清晰的 FM 訊號。


至此, 如果你的設備跟筆者的一樣, 就擁有了只花台幣九百元的軟體無線電, 可以調整的頻率範圍是 53 到 2202 MHz (1102 到 1248 MHz 不可用), 最大取樣率是 2.4 Msps 的 I/Q 訊號, 所以可處理的頻寬是 2.4 MHz, 接下來, 要怎麼做, 要接收什麼, 那就是個人的功夫啦, 在此祝各位玩軟體無線電愉快!


Footnotes:





2 筆者購買的數位電視棒是康博啟示錄 Compro U650, 在 rtl-sdr 網站所描述的 Compro Videomate U650F 與 U650 應是同一產品。


3 rtl-sdr 完整安裝過程與文件(英文): http://sdr.osmocom.org/trac/wiki/rtl-sdr






--
Albert Huang
Chun-Chieh Huang(黃俊傑)

Tuesday, November 6, 2012

如何用星座圖偵錯數位通訊系統

人類天生就是視覺與聽覺的動物, 而抽象思考能力是比較晚才發展起來的, 因此不同工程的偵錯技巧都類似, 最好使用視覺或聽覺來輔助, 才能做最有效率的偵錯。上次講「在 SoC debug 的藝術」時筆者並沒有提到這個非常重要的偵錯技巧: 視覺化! 通訊系統偵錯如果用視覺化來輔助, 可以大幅提升工作效率, 我們今天就來談談通訊系統視覺化偵錯技巧。1

首先來看什麼是星座圖。天文學上的星座圖是一組一組的星星合起來看的, 在通訊系統裡面, 星座圖就是在頻域上看解調出來的 symbol 值, 繪製在一個平面上, 將所有出現的 symbol 值同時繪製在上面的時候, 看起來就像是天文學上的星座圖, 所以就有了這個名字。不過我們並沒有把一個點稱之為星星。:-)

為什麼我們能夠把真實傳輸的訊號看作是星座圖上的一點?這牽涉到 signal space 的證明, 在這裡我們就不詳細證明了, 有興趣的可以翻閱數位通訊系統的書, 有兩本數位通訊對於 signal space 有比較詳細的證明。2

筆者打從一開始從事通訊產業就開始使用星座圖來偵錯通訊系統, 深深的為這樣的偵錯技巧著迷, 最近看到一本書3有詳盡的介紹這個偵錯技巧, 接下來我們就來看在星座圖上能夠看到通訊系統什麼樣的問題。全部的圖例都是以 16 QAM 為例子。

Carrier Recovery Loop Phase Offset

From Constellations
上圖可以看到 16 QAM 的星座點以原點為圓心, 逆時針旋轉了 8 度, 是由於 carrier recovery loop 裡面殘留的相位差所致。

Carrier Recovery Loop Unlocked

From Constellations

上圖可以看到 16 QAM 的星座點隨著時間旋轉, 這是由於 carrier recovery loop 完全沒有鎖到對方發射器的相位。通常脫鎖的話, 旋轉方向是一樣的, 也就是說你的鎖相迴路頻率比對方發射機快或是慢, 如果是一下往順時針, 然後很快就往逆時針(或是相反情況), 而且一去不回頭, 那也是脫鎖, 這有可能是一開始雙方頻率差異過大, 超過鎖相迴路能夠處理的頻寬。

Poor Phase Noise

From Constellations
上圖可以看到星座點以原點為圓心, 以正負平均 3 度的差異旋轉, 這是由於鎖相迴路的相位雜訊過大而來。正負平均(rms) 三度就可以在星座點造成這樣明顯的軌跡了。

Coherent Carrier Interference(同步載波干擾)

From Constellations
上圖是 16 QAM 的星座點受到跟接收機同步的另一個載波干擾所產生的, 受到干擾的點圍繞著理想的星座點旋轉。同步載波干擾會導致錯誤率的增加, 因為相鄰兩個星座點的距離被縮小了。

Multipath

From Constellations
上圖可以看到在多重路徑干擾下的 16 QAM 星座點。多重路徑干擾是由於對方發射機的訊號被衰減並延遲, 而接收機收到兩組或兩組以上的訊號所致。解調器會收到並且鎖住比較大的訊號, 但是在星座點上會顯示另一組衰減的星座點。在每一個理想的星座點上都可以看到完整的縮小版 16 QAM 星座點, 由於延遲的關係旋轉某一個角度。上圖的多重路徑訊號是原來訊號傳輸功率的十分之一。

IQ Phase Imbalance(IQ 相位不平衡)

From Constellations
IQ 相位不平衡(IQ Phase Imbalance) 是由於調變器或解調器的功能出問題, 當訊號區分 I 跟 Q 頻道的時候, 兩組線路的相位差異不是正好 90 度。上圖的 IQ 頻道相位差為 10 度。

IQ Amplitude Imbalance(IQ 振幅不平衡)

From Constellations
IQ 振幅不平衡(IQ Amplitude Imbalance) 也是調變器或解調器線路問題, 當訊號區分 I 與 Q 頻道後, 兩者的增益不一樣, 就會導致 IQ 振幅不平衡。

Gain Compression(增益壓縮)

From Constellations
外圈星座點相對於內圈有比較高的瞬時功率, 如果系統上有增益壓縮的問題, 外圈的星座點會被拉往內圈, 而內圈的星座點會被稍稍從理想星座點位置拉離圓心。

這個問題也會導致解調的錯誤率增加, 因為星座點之間的距離縮短了。

Improper Amounts of Gain

From Constellations
上圖所顯示的是增益太大, 使得 16 QAM 星座點往外長。

From Constellations
上圖所顯示的是增益太小, 使得 16 QAM 星座點往內縮。

Amplitude Variation beyond Automatic Gain Control Bandwidth

From Constellations
上圖可以看出來, 每一個星座點都有振幅變化, 這是由於接收機的自動增益控制趕不上訊號的振幅變化, 無法將振幅變化消除。上圖的星座點都是沿著圓心作直線變化, 表示接收機的鎖相迴路鎖得很精準。

結語

今天介紹了如何用視覺化的方式, 透過對星座點的觀察, 偵錯數位通訊系統, 這是筆者一直以來覺得非常有效率與威力的偵錯方式。在這篇文章中介紹了通訊系統會在星座點出現的現象, 但平面的文章沒辦法表現的是人類對於視覺的快速反應, 在面對 symbol rate 很快的系統, 仍然能夠很快速的反應, 讓我們很容易能夠抓出也許只有一兩個 symbol 的瞬間錯誤。在很多數位通訊儀器上面, 也都內建這種偵錯的方式, 可以好好利用。

Footnotes:

1 除了視覺化偵錯之外, 如果許可的話也可以利用聽覺, 比如說在偵錯語音頻帶數據機、業餘無線電數據機的時候, 因為頻寬在聲音頻寬內(小於 20 kHz), 所以很適合用聲音來偵錯。這樣你就知道為什麼以前的電話撥接數據機在剛開始連線的時候會開啟喇叭讓你聽到一連串的高低音了吧。

2 Wozencraft, John M., and Jacobs, Irwin Mark, "Principles of Communication Engineering," John Wiley & Sons, 1965.

Gallager, Robert G., "Principles of Digital Communication," Cambridge University Press, 2008. 可以由 http://goo.gl/glkdQ 下載。

3 McClaning, Kevin, "Wireless Receiver Design for Digital Communications, " 2/ed, SciTech Publishing Inc., 2012.


--

阿姆斯壯之死

第一個登陸月球的那個阿姆斯壯(全名是 Neil Armstrong) 逝世於 2012 年 8 月 25 日。他的身軀是死了, 但是他的精神(spirit) 卻永遠與我們同在, 我們永遠會記得他登陸月球時講過的話:「這是一個人的一小步,卻是全人類的一大步」。而另一個阿姆斯壯, Lance Armstrong, 在單車環法賽奪得了七次冠軍的那個阿姆斯壯, 他還活著。

一個單車選手要能夠奪得單車環法賽冠軍就已經很不容易了, 而 Lance Armstrong 不但奪得七次單車環法賽冠軍, 而且還是在他罹患癌症並且痊癒之後奪得, 這樣的故事可以激勵多少人心, 鼓勵多少人向上, 也因此, 他出了一本書, 書名是 "It's Not About The Bike: My Journey Back To Life" 多年前我開始騎單車的時候, 買了一本。

運動選手之所以常常是被人們所崇敬的對象, 正是因為他們秉持運動家精神, 即便目標是多麼艱難, 從不輕言放棄, 也不用不公平的方式贏得比賽。筆者還記得有一年環法賽, Lance Armstrong 長年的冠軍競爭對手, 來自德國的 Jan Ulrich 被撞倒在地上, Lance Armstrong 並沒有利用這個機會趕緊大幅超前, 而是在 Ulrich 的附近等待他再度上路之後, 才一起出發。這一幕被多少媒體與網路文章傳頌, 至今仍讓人津津樂道。這正是運動家精神表現的極致: 堅持與對手公平競爭。

Lance Armstrong 曾經罹患癌症, 但他並未放棄他熱愛的單車運動, 反而在痊癒後, 不放棄自己的訓練計畫, 也不管癌症治療後身體是多麼的虛弱, 他還是堅持奮戰不懈, 積極的訓練, 終能在 2005 年獲得第七次環法賽冠軍, 並且宣布退休。這也是運動家永遠不放棄的精神。

因為上述兩項運動家精神極致的表現, Lance Armstrong 是現任的 Apple 執行長 Tim Cook 常常掛在嘴邊的效法對象, 如果時光就停留在 2005 年的話, 一切看起來是那麼的完美: Lance Armstrong, 一個罹患癌症之後仍然奮戰不懈的鬥士, 一個贏得七次單車環法賽冠軍的英雄, 一個堅持與對手公平競爭的謙謙君子, 他的運動家精神放眼當今這個世界, 沒有幾個人能夠與他匹敵。

今年七月美國反禁藥協會(United States Anti-Doping Agency, or USADA) 以 2009 至 2010 年的血液樣本以及 Lance Armstrong 在美國郵政車隊的前隊友的證詞, 指控 Lance Armstrong 使用禁藥以提升運動表現, 並要求撤銷其七次單車環法賽的冠軍頭銜。而 Lance Armstrong 在八月底正式放棄任何上訴, 也意味著他默認了他使用禁藥的指控。

此刻, Lance Armstrong 的書很諷刺的躺在我的書架上, 還沒有機會被我閱讀, 就已經充滿了汙穢。登陸月球的阿姆斯壯, 身軀是死了, 精神卻與我們同在; 而單車英雄阿姆斯壯, 還非常健康, 精神卻已經死了。


--

Sunday, November 4, 2012

台鐵老舊車廂警報器

週日要從新竹到台北, 一時興起改搭台鐵莒光號, 當天旅客人數不少, 座位坐滿之餘走道仍有一些旅客站立。車行至楊梅一帶, 突然第七車廂廁所有人誤觸警報器, 一時間鈴聲大作, 許久都沒有人來關掉警報器, 至少十分鐘之後, 車廂有一名旅客及筆者在互相不知道的情況下先後依照警報器旁邊的告示指示, 走去第一車的車長室通知車長來處理, 在旅客人數不少的情況下, 筆者從七車走到三車時便遇到迎面而來已經被通知的列車長。列車長表示由於是老舊車廂, 警報器沒有辦法連線到車長室, 只能由旅客主動通知列車長來處理。這要是真有緊急事件, 這麼一來一回, 恐怕會失掉處理機會吧?再者, 只要車廂門關起來, 相鄰的車廂是聽不到警報器聲音的, 真的發生事情而該車廂又剛好沒有其他人, 那麼恐怕會產生莫大的遺憾。

台鐵目前積極購置全新車組淘汰舊有車廂, 但是以目前淘汰的速度來看, 舊有車廂恐怕要再用上好幾年, 在這些老舊車廂淘汰之前, 難道就只能放任這種規劃不良的警報系統繼續使用嗎? 筆者在接下來的旅程便發揮了工程師愛解決問題的毛病, 開始思考這個問題。筆者認為其實可以用低廉的價格便可以將這些警報器全部升級成為可以通報車長室的現代化連線警報器。

空話不多說, 來發想解決方案吧。

首先就是如何連線? 根據列車長所言, 看來是牽電纜有窒礙難行之處, 那麼想當然爾, 就來用無線的方式吧!但是無線的方式如何是成本最低廉的呢?台鐵列車之間的無線電通訊早已進入全面數位化的時代, 使用的是 TETRA 的數位中繼無線電系統, 原有的類比式(應該是 FM 調頻式無線電)的機器以及頻率都沒有在使用。筆者想到的其實就是使用這些頻率, 用 AFSK 1200bps1 的傳輸方式, 每一節車廂廁所警報器都配上一台 modem, 或是我們一般稱之為 TNC(Terminal Node Controller) 的無線電數據機, 每一節車廂都配上一台。當警報器響的時候, 就開始每隔一段時間傳送一個封包, 裡面包含了列車號碼、車廂號碼與警報器的型態(也許將來要擴充傳送其他訊息)等資訊, 業餘無線電裡有一個通訊協定是 AX.25, 這個通訊協定會把 TNC 收到的封包, 再廣播出去, 當然會用某種機制避免封包氾濫。如此, 每一個車廂的數據機都會幫上一個車廂的數據機的封包傳送出去, 讓下一個車廂的數據機收到, 如此層層轉送, 很快就可以送到列車長室。這樣的系統成本非常低廉, 甚至有可能利用原有以淘汰的無線電對講設備來使用, 在這些車廂淘汰之前, 至少讓旅客覺得台鐵有可靠且安全的服務。

Footnotes:

1 AFSK 是一種用兩種頻率的聲音來代表 0 與 1 的調變方式, 只要用接上對講機使用聲音發射即可, 構造簡單成本極低, 在 VHF/UHF 可以達到 1200 bps 以上的速度。


--

Friday, November 2, 2012

在 SoC debug 的藝術

今天要談一下, 在 SoC(System-on-Chip) debug 的藝術, 首先我先界定一下何謂 SoC, Wikipedia 對於 "System on a chip" 的解釋是 "A system on a chip or system on chip (SoC or SOC) is an integrated circuit (IC) that integrates all components of a computer or other electronic system into a single chip." 對於在 SoC 上面寫程式與 debug, 我認為最大的特點是:

  • 任何地方都有可能會錯

讀者可能會想, 我在任何地方寫程式的特性也是這樣啊, 但是 SoC 還有一個很致命的缺點, 即便是處理器已經驗證過, 都仍然有可能會發生指令集的錯誤, 尤其是組合語言程式設計師每個人的寫法都不一樣, 很有可能會踩到之前沒有驗證過的指令集組合而發生錯誤!

是的, 在 SoC 上寫程式, 驗證工具不管做得再好, 都只是減少錯誤發生的機率而已, 實際上遇到的問題, 還是要有這樣的心態來面對會比較正確。因為在一般的情況下, 我們會把 CPU/DSP 當做已經驗證沒有問題來寫程式, 但是在 SoC 上面, CPU/DSP 非常有可能會因為在新的設計上, 某個或某些組合的 CPU/DSP instruction 在某一級 pipeline 發生問題, 而導致錯誤的結果。即便是大廠如 AMD, 經過了很多的驗證程序之後, 還是有可能出現問題, 如: AMD processor incorrectly updates the stack pointer

在這樣的 SoC 上面寫程式與 debug, 需要有一些藝術與技巧, 筆者就來分享一下我的經驗。筆者分享的是筆者在通訊 SoC 晶片上發展的經驗, 但我想很多部分都可以類推到其他系統晶片上。一般說來, 在這樣的 SoC 上面會出現的錯誤來源有幾個:

  • 自己的程式
  • CPU/DSP instruction 的邏輯錯誤
  • CPU/DSP instruction 的時序錯誤
  • IC 硬體區塊的錯誤
  • IC 內部 Bus 傳輸錯誤
  • IC 與 IC 之間外部 Bus 傳輸錯誤
  • 別家晶片上對於通訊訊號或協定上的錯誤

由於通訊基頻系統大部分都含有一顆或多顆 DSP 負責基頻訊號處理, 所以 DSP programmer 常常身負驗證各個 functional block 的責任, 或是在使用的過程中由奇特的現象來發現驗證團隊之前沒有發現到的錯誤。不管錯誤來源有多少, 解錯誤的首要, 就是先把整個系統以及演算法的原理搞清楚, 清楚之後, 就要依據錯誤出現的現象, 猜測問題出現的點, 然後設計實驗來確認錯誤發生的地方。猜測問題發生的點, 依靠的是對於這個系統的直覺, 而這個直覺是透過你對系統的了解與經驗累積而來的。另外, 就是需要重建錯誤發生時所發生的事情。如果有 simulator 可以使用, 那麼常常在 simulator 上就可以觀察到錯誤的前後發生的事情, 但是像是通訊訊號或協定上的錯誤, 則常常需要有時序上的事件紀錄來重建錯誤發生當時的原貌, 或是有時候沒有現成的分析工具, 就要自己寫一些程式來記錄與觀察變數的變化與事件的流程; 而選擇觀察的物件, 也反映了你對於系統的了解程度。

第一個就是要確定自己的程式沒有問題, 程式可能出錯的來源有兩種: 一種是程式設計師自己寫錯, 另一個是 CPU/DSP instructions 出錯導致程式有錯。前者有很多的程式設計相關書籍都有提到如何避免, 以筆者的經驗, 在寫任何 DSP 程式, 特別是組合語言之前, 一定要先想好怎麼測試自己所寫的程式, 以及怎麼樣算是測試成功及失敗。這部分的觀念, 筆者後來發現軟體業界早已經講了很多, 讀者有興趣的話可以參考 TDD(Test Driven Development) 的觀念。TDD 的導入也能夠幫助我們找到第二、三個 CPU/DSP 指令集上的錯誤。

程式出錯另一個來源就是 CPU/DSP 指令集上的錯誤, 可以略分成兩種: 一種是指令集邏輯上的錯誤, 另一種是指令集時序上的錯誤。一般來說如果 CPU/DSP 有 test pattern 的話, 前者邏輯上的錯誤應該都已經抓完, 剩下的時序上的錯誤, 也就是指令前後組合的問題, 由於樣本數太大, 一般都只能隨機測試, 所以後者時序上的錯誤是 DSP programmer 比較容易遇到的地雷。如果 DSP programmer 是用組合語言撰寫程式, 而不是 C 語言, 那麼踩到地雷的機會更大。如果有編譯器的話, 通常編譯器就可以當作是一個測試的程式, 可以抓到某些編譯器 codegen 愛用的組合語言時序組合的 bug, 但是組合語言程式設計師每個人愛用的組合語言寫法都不同, 就很容易在某個人的寫法上就踩到地雷。而時序上的錯誤其實也是比較難抓的問題, 通常只能依靠 DSP programmer 在使用上的時候, 發現某些奇特的現象, 把搜尋範圍縮小之後才能夠找到。上一節講的 TDD 就能夠幫助 programmer 找到那些奇特的現象在哪裡。另外, 一般來說, 通訊 SoC 的計畫時程短則三年, 長則五年以上, 要求把整本 DSP 架構讀得滾瓜爛熟不也是很合理的嗎? 對於 CPU/DSP 架構的熟悉程度, 也會幫助你可以很快的找到指令時序上的錯誤。

前三項都確定沒問題之後, 接下來要排除的錯誤才是困難的開始, 在此, 筆者建議大家一定要維持寫實驗記錄或是工作記錄的習慣, 筆者常常遇到一解就是一兩週的 bug, 常常解到後來需要與一兩週之前的結果一起比較才能判斷錯誤在哪裡, 因此工作記錄非常重要, 而且有了工作記錄之後, 每天回家才不會心裡一直掛念這件事。要排除這邊的錯誤, 通常是已經有一個錯誤發生了, 這個錯誤也許要做很多次才能重複, 但是一定要確定如何能夠重複這個錯誤, 這點很重要, 因為接下來你會需要一直讓這個錯誤發生才能夠 debug. 讓錯誤發生是一個「點」, 要找出錯誤發生真正的原因(root cause), 常常需要其他的「點」, 讓你連成數條線才能夠把搜尋範圍變小找到真正發生的原因。

找 root cause 的過程, 我個人覺得就像是 binary search 一樣, 不斷的找一個點做判斷, 決定要往左跑, 還是往右跑。當然, 有的時候還是會判斷錯誤, 跑錯方向, 所以就要回溯到當初的切割點, 知道當時的實驗資料是什麼, 為什麼做這樣的判斷, 才能對整個問題有更全面性的了解。這時候仰賴的還是當初的實驗記錄, 所以實驗記錄很重要吧!

除了解單一錯誤以外, 有的時候會需要解多重錯誤。筆者碰觸到的大部分是通訊或訊號處理的問題, 穩定度很重要, 多重錯誤常常會表現在穩定度上, 所以我們常常要記錄錯誤率, 才能知道自己是否已經解完所有的錯誤, 或是剛剛解掉的那個錯誤是否佔的比例最大。另外, 我覺得在這樣的系統上 debug, 還要「大膽的假設,小心的求證」, 有的時候, 我們需要處理的是通訊 physical layer 或是 protocol layer 的問題, 需要猜測對方怎麼做, 這時候就需要大膽的假設, 然後小心的求證。有的時候, 錯誤的可能是另一家公司的晶片, 因此「大膽的假設,小心的求證」是必要的。在這個情況下, 考驗的就是你對整個通訊系統以及原理的掌握程度了。另外, 晶片內部的錯誤, 也是需要「大膽的假設,小心的求證」, 因為這時候, 能夠觀察的工具變少了, 有時候需要猜測。還有, 對已知事物的掌握程度, 也會影響到猜測的精準度, 比如說各個硬體的規格, 使用到的演算法的原理, 通訊 physical layer or protocl layer 的原理, 通訊系統的規格, CPU/DSP instruction set, 等等, 都能夠提昇猜測的效率。對已知事物掌握程度高, 才能夠專心的面對未知的事物。

在此, 筆者試圖將我的經驗整理成幾點原則:

  • 先想清楚 test plan
  • 熟悉 CPU/DSP 架構
  • 熟悉待測物的功能、規格、演算法
  • 確保知道如何重複產生 bug
  • 知道 bug 發生點之後, 嘗試往前一級測試問題
  • 紀錄所有測試數據以及判斷的依據, 以便回頭仔細檢視

身為一個使用組合語言的通訊 DSP 程式設計師, 除了通訊演算法以外, debug 大概就佔掉絕大多數的時間, 真正寫 code 反而是這些工作裡面佔比例最少的。因此, debug 的效率與正確性, 對於程式甚至是晶片的品質, 有著決定性的影響。每個人都有每個人的方法, 筆者在這一篇文章裡, 試圖分享我個人的方法與經驗, 希望能對即將跨入或剛剛跨入這一個領域的工程師有點幫助, 而在這個領域很有經驗的工程師也歡迎大家一起交流心得。


--

Sunday, October 28, 2012

Emacs Wiki 簡易使用指南

這是我之前發表在 Newzilla 線上雜誌上的文章,不確定能否直接轉錄回我的 blog,先用連結吧。

點進去看吧

Emacs Wiki 後一章 -- 專案、遠端連線與註腳模式


原文撰寫於 2005 年 3 月 2 日,本來是接受某線上雜誌邀稿,該雜誌因故停刊,故未刊出,這其實只是草稿而已,我也懶得改寫了。

黃俊傑 jjhuang AT cm-nctu-edu-tw

前言

上一期中, 我們學習了如何用 Emacs Wiki 來快速產生網頁, 本期我們將會介紹 Emacs Wiki 相關的工具; 使用 Emacs Wiki 的專案功能來管理不同的網頁, 將網頁傳到遠端的網頁伺服器上, 以及使用 Emacs 內建的註腳次要模式(footnote-mode) 來幫助我們輸入註腳。

Emacs Wiki 專案

如果你像筆者這樣有好幾個獨立的 Wiki 要編輯, 那麼你很可能需要使用到 Emacs Wiki 專案來管理這些檔案。 新增專案的方法如下,首先你要先進入 Emacs 的 customization
M-x customize-group  emacs-wiki 
然後再進入 Emacs Wiki Project 這個目錄, 進入之後把 Emacs Wiki Projects 這個變數打開來。 一開始 Emacs Wiki 是沒有任何專案的, 只有 default 這個專案, 而這個專案是沒有列在這個變數中。 若要新增一個專案, 首先要按 INS 這個按鈕, 然後輸入專案名稱於 Project name: 一欄, 接下來在 Project name: 的下方中間也有一個 INS 按鈕, 請按下這個按鈕, 然後輸入開啟這個專案時要改變的變數。 筆者所知道需要改變的變數至少有下列幾個:
emacs-wiki-publishing-directory
這個專案的網頁放置目錄
emacs-wiki-directories
這個專案的 Wiki 檔案放置目錄
記得 emacs-wiki-directories 是複數名詞, 代表這是一個 list, 所以在 Value 那一欄必需將你的目錄用括號刮起來, 如:
("~/Documents/MyWebPage")
增加完成之後, 記得按 State 這個按鈕把這次改變的專案設定儲存起來。 以後要使用專案, 可以直接開啟該專案的檔案, 或是在 Emacs Wiki Mode 中下 C-c C-v 改變專案。

傳送網頁至遠端伺服器

目前 Emacs Wiki 要編輯遠端的網頁, 可以放在本地端, 然後再用 rsync 等同步程式來做同步, 或是把專案放置在遠端的機器上。 要把專案放置載遠端的機器上, 可以把 emacs-wiki-directory 放在本地端, 把 emacs-wiki-publishing-directory 填上
"/user@host:/path/to/your/web/page"
如此, 當你下 C-c C-p (emacs-wiki-publish) 時, Emacs 就會透過 tramp 程式把檔案送到遠端的伺服器上。 M-x emacs-wiki-publish 會將所有的 Wiki 檔案都轉換成 html, 並且傳送到遠端, 在頻寬較小的情況下, 相當的耗費時間, 可以利用 M-x emacs-wiki-publish-this-page 來傳送目前編輯的頁面。
如果你嫌每次都要按 M-x emacs-wiki-publish-this-page 打太多字, 可以參考 Emacs Wiki 專案首頁的建議1, 將 C-x C-p 按鍵定義成 M-x emacs-wiki-publish-this-page, 只要你在 ~/.emacs 加入以下幾行即可:
(add-hook 'emacs-wiki-mode-hook
       (lambda () (global-set-key "\C-x\C-p" 'emacs-wiki-publish-this-page)))
這樣就會在每一次進入 Emacs Wiki 模式時將此按鍵加入。 你就可以在每一次編輯完一個檔案, 想要上傳時, 按 C-x C-p 來上傳目前編輯的檔案, 以節省傳輸時間。

註腳模式

說明

註腳模式(footnote-mode) 是一個次要模式(minor mode), 與 Emacs Wiki 並無直接關聯, 是 Emacs 內建的次要模式。 筆者通常用這個模式配合 gnus 使用, 在編輯文章的時候加一些註腳用。 Emacs Wiki 採用的註腳格式與註腳模式產生出來的格式完全一樣, 所以我們也可以利用註腳模式來協助編輯 Emacs Wiki 檔案。
與其他的次要模式一樣, 註腳模式的命令可以開啟或關閉註腳模式。 註腳模式的命令是
M-x footnote-mode
當註腳模式開啟的時候, Emacs 視窗下方的模式列會顯示 FN 的字樣。 當我們要新增一個註腳的時候, 只要在想要新增的位置鍵入
M-x footnote-add-footnote
接下來註腳模式會自動在新增的位置填上一個數字前後加上方括號, 並且跳到文章的最後, 加上註腳(Footnote) 字樣, 游標會停在要編輯的註腳後面等待使用者輸入註腳的說明文字。 輸入完之後, 我們可以輸入
M-x footnote-back-to-message
然後游標會回到剛剛新增註腳的位置, 使用者可以繼續本文的編輯。 其餘的註腳模式功能請參考快速鍵列表, Emacs Wiki 可以完全處理註腳模式產生的格式, 這篇文章就是利用註腳模式來來產生註腳的。

快速鍵列表

註腳模式的快速鍵不多, 只有六個, 表列如下:
按鍵命令(鍵入之前先按 M-x)說明
C-c ! aM-x footnote-add-footnote增加註腳
C-c ! bM-x footnote-back-to-message由註腳說明處回到引用處
C-c ! dM-x footnote-delete-footnote刪除註腳
C-c ! gM-x footnote-goto-footnote跳到註腳解釋
C-c ! rM-x footnote-renumber-footnotes重新編排註腳號碼
C-c ! cM-x footnote-cycle-style變換註腳形式


[1] Emacs Wiki 專案首頁, http://repose.cx/emacs/wiki/#sec5

Monday, October 15, 2012

How to use HHKB Pro 2 as an external keyboard to an iPad


Happy Hacking Keyboard Professional 2 (HHKB Pro 2), which is produced by PFU Limited of Japan, is a great keyboard with a small footprint, and it contains only 60 keys. As a new iPad owner, I wonder if I can combine these two gadgets and write notes on-the-go.

After some trial-and-error, finally I make it work! Here is how to make it. First you need to buy iPad Camera Connectivity Kit from Apple. This kit is designed for connecting to a digital camera, so if you ask any salesperson in Apple store, he or she will probably tell you it's not designed to connect to an external keyboard. Never mind what he or she says, just buy it. And then you'll need a USB hub with external power supplied, i.e. you actually need to plug the external power cord to a power source because HHKB Pro 2 draws larger current from USB port than an iPad can supply. Now connect your HHKB Pro 2 to the USB hub with external power supplied, and then connect the USB hub to your iPad via the camera connectivity kit. Open any text-oriented application, e.g. OmniOutliner, and then you can type by your HHKB Pro 2!

To use these gadgets on-the-go, I bought a mobile battery with me so that the USB hub can be supplied by the battery. Here are the photos of them:

What you need

How to connect HHKB Pro 2 to a new iPad


Requirements:
- a new iPad, or iPad 3
- a Happy Hacking Keyboard Professional 2
- a USB hub with external power source
- a mobile battery if you want to use them on-the-go

Note I'm not sure if older iPad works this way.

Friday, October 12, 2012

Emacs etags 簡介


這也是筆者多年前發表在 NNTP news 上的文章,留存備份。

etags 簡介 -*- Outline -*-

* 前言
  有許多的 IDE(Integrated Development Environment) 都提供了函數名稱的
  自動完成功能( 亦即,輸入前面幾個字元之後,編輯器可以自動幫你完成後面
  的函數名稱)。Vi 裡面有 ctags 可以做到這件事,那麼 Emacs 呢?答案是
  etags. 在這篇文章裡,我會簡短的介紹如何使用 etags.

* etags 使用方法
** 建立函數及關鍵字列表
   在使用之前,你必須先在你的發展環境目錄底下建立列表; 假設你的發展環
   境目錄名稱叫做 /path/to/developer/, 建立列表的方法如下:

   % cd /path/to/developer/
   % etags *.h *.c

   這樣就建立完成了,根據 etags/ctags 的手冊, etags/ctags 可以處理的語
   言有 C, Objective C, C++, Java, Fortran, Ada, Cobol, Erlang, LaTeX,
   Emacs Lisp/Common Lisp, makefiles, Pascal, Perl, Postscript,
   Python,  Prolog, Scheme  and most assembler-like  syntaxes.
   預設的列表檔名是 TAGS.

** 把函數及關鍵字列表讀進 Emacs
   開始用 Emacs 編輯檔案, 比如說你正在編輯 foo.c, 你先用 C-x C-f 把
   foo.c 讀進來之後,你需要使用 etags 的功能,那麼你就執行
   M-x visit-tags-table /path/to/developer/TAGS
   把 /path/to/developer/TAGS 檔案讀進來。註: 表示 Return 鍵,或
   是在鍵盤上通常標示為 Enter.

** 在 Emacs 中搜尋函數內容
   有的時候我們會想要直接跳到某個函數裡面去修改他的內容,你可以使用
   M-. (沒錯,就是 Meta 跟一個句點) 然後輸入函數名稱就會跳到該函數的
   code 那裡去; 如果你按 M-. 的時候游標指著一個函數名稱,你可以在輸入
   函數名稱的時候直接按 即可跳到該函數源碼的地方。跳過去之後,如
   果你想要回來原來地方,你可以用 M-* 來做到。

   如果你想要在另一個視窗內看到該函數源碼,而不是你現在的這個視窗(對照
   方便), 那麼你可以用 C-x 4 . TAG 來達成這件事。

   如果你要搜尋某些函數與關鍵字,你可以用 M-x tags-search 的功能,這個
   可以用 regular expression 來搜尋。當你用 M-x tags-search
   REGEXP 之後,你可以用 M-, (Meta 逗點), 找下一個搜尋到的函數名
   或關鍵字。

** 函數及關鍵字自動完成
   etags 並沒有提供函數及關鍵字自動完成(auto-completion)的功能, 但是
   Emacs 有提供一個功能可以達成這件事,叫做 dynamic abbreviation
   expansion. 這個功能事實上是把去找在開啟的 buffer 裡面有那些字串是你
   輸入字串的完整字串,而 TAGS 列表就在一個 buffer 裡面,所以可以達成
   函數及關鍵字自動列表。當你輸入一個函數名稱或是一個變數名稱的前面幾
   個字母,比如說: foo-, 然後按 M-/, 這時候 Emacs 會把所有可能的字串找
   到,並把第一個可能的字串直接完成,所以你按了一次 M-/ 之後可能會變成
   foo-bar-function, 你繼續按 M-/ 可以變換成其他可能的字串,直到沒有為
   止。或者是你也可以按 C-M-/, 這時候 Emacs 會像其他時候的
   auto-completion 的行為一樣,跳出一個視窗把所有的可能列表列出來給你
   選擇。

* 結語
  當我開始使用 etags 的功能之後,我就沒有辦法不用這個功能了,因為實在
  是太方便了。etags 也可以幫你自動完成標準函式庫裡的名稱,只要你在
  etags 的時候把 /usr/include 裡的表頭檔案也包含進來就可以了。etags 還
  有其他比較進階的功能,我沒有一一列出來,有興趣的人可以去看看 M-x
  info 裡的 Emacs 手冊。最後我做一個這次提到的功能列表,供讀者參考用。

* 按鍵列表
  M-x visit-tags-table TAGS-file
      把 TAGS-file 檔案讀進 Emacs
  M-. TAG 尋找函數或關鍵字定義的源碼
  C-x 4 . TAG 在另一個視窗尋找函數或關鍵字定義
  M-* 回到尋找關鍵字定義之前的地方
  M-x tags-search REGEXP 用正規表示式搜尋函數或關鍵字定義
  M-, 找下一個搜尋到的函數或關鍵字
  M-/ 自動完成可能的函數或關鍵字
  C-M-/ 列出所有函數或關鍵字名稱的自動完成列表

Emacs 大綱模式簡介(Outline mode)

這是筆者很多年前寫的文章,發表在 NNTP news 上面,留存在本 blog 中。


* 簡介 
我想很多人在作筆記或是絞盡腦汁想問題的時候,常常會用大綱來把自己的想法 
記錄下來,比如說像以下的方法: 
I. 棒球 
A. 職棒 
1. 台灣職棒 

2. 美國職棒 
a. 國家聯盟 
b. 

3. 日本職棒 
a. 中央聯盟 
b. 太平洋聯盟 

B. 業餘棒球 

II. 籃球 
A. 職籃 

這樣的階層架構可以在 Emacs 中使用他的大綱模式(outline mode) 來做到,幫 
助我們來紀錄我們的想法或是像筆者就常常在聽完演講之後,把用筆記上的演講 
大綱筆記,用 Emacs outline mode 記錄下來,供日後查詢。Emacs 也可以把這 
些 outline 轉換成其他格式,比如說: LaTeX 或是 Info 檔格式。在本文中提 
到的 Emacs 以 GNU Emacs 為準,XEmacs 應該也是差不多,不過我建議你們用 
GNU Emacs, 因為 Emacs 處理字型比較清晰,而且對於中文支援較佳。 

* Outline mode 
** 進入大綱模式 
使用者可以用 M-x outline-mode 來進入大綱模式,打完這個命令之後就可以看 
到目錄列上出現 "Headings" "Show" "Hide" 三個下拉式選單項目,不過,先別 
急,先了解一些基本概念再來使用。如果你有開啟 font-lock-mode 的話,你打 
完上述命令之後就可以看到這篇文章的標題顏色變了,因為筆者就是用 
outline-mode 來打這篇文章的。如果沒有看到顏色,你可以用 M-x 
font-lock-mode 來啟動。M-x 意思是按住 Alt(Emacs 裡稱為 Meta 鍵) 以及 
x, 然後輸入 outline-mode,再按 [Enter] 即可。 

** 階層架構 
Outline mode 的階層架構是以幾個 "*" 符號來分隔的,就如同本文章一樣。一 
個星號("*") 的就是最高層,也就是類似簡介的例子中的 I, II, 等等,而兩個 
星號則是第二層,類似例子中的 A, B, 等等。但是要注意的是這些星號一定要 
在該行的最前面。如果沒有星號開頭的就是該層(或稱為該標題)下的本文。 

** 顯示及隱藏標題與本文 
*** 隱藏 
想要隱藏某個標題下的全部文字,你可以選擇目錄選單『Hide->Entry』,你可 
以將游標移到這裡,然後選擇『Hide-Entry』,如果你沒有看到選單,你可以直 
接輸入 C-c C-c (連續兩個 Control C)。好,現在就輸入 C-c C-c 

*** 顯示 
別急別急,看不到隱藏的文字了?先看看隱藏兩字後面是不是出現了三個句點 
"..."? 那就表示那個標題以下的文字被隱藏了。你可以用目錄選單 
『Show->Entry』來回復剛剛的文字,或是按 C-c C-e 來顯示隱藏的文字。 

*** 在標題間移動 
有的時候你會想要在同個層級的標題間移動,這樣比較方便寫作。那麼你可以使 
用『Headings->Previous Same Level』,或是按 C-c C-b 到前一個同層級的標 
題。如果你照指示的話,你會看到現在游標停在『顯示』那一行上面。如果要上 
一個層級,你可以選擇『Headings->Up』,或是 C-c C-u, 如果你照做的話,你 
的游標現在會是在『顯示及隱藏標題及本文』那一行。 

* 結語 
有沒有搞錯?這麼快就要結束了?沒錯,我已經把主要功能介紹完了,其他的功 
能,請自行看下拉式選單,全部都在 Headings, Show, Hide 裡面。或是找 
Emacs manual 裡的 Outline Mode 一節,有更詳盡的說明。 

大綱模式是一個很小,但很方便的功能。筆者曾經有一次要做 simulation 
program 的除錯, 我把所有的 events 全部輸出到一個檔案裡,但是 events 很 
多啊,那可是上千上萬的。Events 有分不同的層級,上層的是比較高階的動作, 
下層是比較細節的動作,如果分層輸出到不同個檔案可以解決 events 太多的問 
題,但是卻比較不容易看出不同層級的時間先後。於是筆者便將 events 依照層 
級在那一行的最前面加上星號,全部輸出到一個檔案裡(最後還是有分檔案啦, 
不過是五千個 events 一個檔案,而不是分層級)。這樣,我就可以分顏色看到 
events 的層級,我也可以顯示或隱藏某一個 events 以下做的事,要找下一個 
同層級的 event 也很快。如果你想照做,筆者提醒你,Windows 版的Emacs 處 
理這樣大的檔案會頗慢的,這也是筆者改用 Linux 的原因之一。 

Friday, October 5, 2012

在 GNU Emacs 的 Help 文件系統


GNU Emacs 有一個功能很好用, 他的 key binding 一般來說是 C-h S, 或是 M-x info-lookup-symbol, 使用的方法是把游標移到你要查詢的 symbol 上面, 然後按下 C-h S, 這時候 Emacs 會自動幫你找到相對應的 Info 文章, 並顯示在另一個視窗(這裡的視窗是 Emacs 的術語) 上。



如果你想要試用這個功能, 可以試著開啟任何一個 Emacs Lisp 檔案, 然後對著任何一個 function 鍵入 C-h S, 就會出現文件, 舉例來說, 如果對著 require 按下 C-h S, 在筆者的 Emacs 24.1.1 就會出現下列的文件:





-- Function: *require* feature &optional filename noerror
This function checks whether FEATURE is present in the current
Emacs session (using `(featurep FEATURE)'; see below). The
argument FEATURE must be a symbol.

If the feature is not present, then `require' loads FILENAME with
`load'. If FILENAME is not supplied, then the name of the symbol
FEATURE is used as the base file name to load. However, in this
case, `require' insists on finding FEATURE with an added `.el' or
`.elc' suffix (possibly extended with a compression suffix); a
file whose name is just FEATURE won't be used. (The variable
`load-suffixes' specifies the exact required Lisp suffixes.)

If NOERROR is non-`nil', that suppresses errors from actual
loading of the file. In that case, `require' returns `nil' if
loading the file fails. Normally, `require' returns FEATURE.

If loading the file succeeds but does not provide FEATURE,
`require' signals an error, `Required feature FEATURE was not
provided'.





上述作法是當你目前的 major mode 有相對應的 Info 檔案的時候, 可以直接使用 C-h S 來查詢, 如果沒有的話, Emacs 會先問你要使用哪一個 major mode 的 help 檔案, 然後再查詢該 symbol 的文件。那麼, 如果要為新的 major mode 增加 Info 文件呢? 這時候你可以在 .emacs 裡加上 info-lookup-maybe-add-help 來把某個 Info 檔案加入 major mode 裡面, 範例如下:





(require 'info-look)

(info-lookup-maybe-add-help
:mode 'asm56k-mode :topic 'symbol
:regexp "[a-zA-Z]+"
:doc-spec '(("(dsp563xx)Index")
("(dsp563xx)Concept Index")))





上述的範例是指定 major mode asm56k-mode 的 Info 文件是 dsp563xx, 這個檔案必須在 Info 系統能找到的路徑上, 透過 Index 與 Concept Index 這兩個 Info node 來查詢關鍵字的 Info 文件, 而可以被查詢的關鍵字的 regular expression 則由 :regexp 來指定, 本範例的關鍵字是由純英文字母組成。上述的範例是筆者為了要在 GNU Emacs 裡面寫 Motorola DSP56300 的組合語言而增加的, 這樣筆者在 asm56k-mode 編輯組合語言的時候, 就可以隨時透過 C-h S 來查詢某個助憶碼(mnemonic) 的用法以及 instruction encoding, 而這些是存在另一個 Info 文件上。



Info 檔案在 GNU Emacs 中是一個重要的文件系統, 可以由 Texinfo 檔案編譯而成, 現在也有很多文件系統也可以產生 Texinfo 的格式, 比如 Sphinx, 對 Texinfo 有興趣的讀者可以參考一下 Arnold Robbins 在 Linux Journal 所寫的介紹文章 What's GNU: Texinfo. 不管是用什麼方法產生 Info 檔案之後, 透過設定, 結合 C-h S 的便利性, 你就可以在 GNU Emacs 裡面很便利的查詢文件。


--

Friday, August 31, 2012

再談指數濾波器

上週我們在動平均濾波器一篇文章中提到了「指數平均濾波器」, 這是一個簡單又有效的濾波器, 今天我們再來詳談一下指數平均濾波器的應用。 全文 PDF

Friday, August 24, 2012

淺談動平均濾波器

動平均濾波器 (moving average filter) 可說是世界上使用最廣泛的一種濾波器了; 在股市裡面, 每天都可以看到動平均濾波器的應用, 股價趨勢圖裡面的週線、月線與年線, 都是長度不等的動平均輸出圖形。我們在實作訊號處理的時候, 也很常應用這個簡單又有效率的動平均濾波器。 由於它應用廣泛, 許多程式設計師也許沒有修過數位訊號處理的課程, 不熟悉數位訊號處理分析方式, 但是又需要寫這樣的程式。因此, 在這一篇文章中, 筆者將會儘量以實例來介紹動平均濾波器的概念, 幾種不同的實作方式以及優缺點。

詳全文請點: 全文 PDF

Friday, August 17, 2012

定點數表示法

筆者今天要來介紹定點數表示法, 也就是 fixed-point representation. 讀者可能會很納悶, 現在有浮點數的機器非常普遍, 而且速度都很快, 比如說 Intel Core i7 處理器,開啟 AVX SIMD 的情況下, 可以一次處理四個 64 位元浮點數的乘法。但是在很多地方, 比如說訊號處理、控制系統、或者很多手機內部的處理器, 都欠缺浮點運算能力,這時候就必須使用定點數。...全文 PDF

Monday, June 18, 2012

用 Linear Filter(IIR) 來實作 Fibonacci 序列


PyCon.TW 2012 在日前圓滿落幕, 會中的 keynote speaker Travis Oliphant 講
了一個使用 linear filter 實作 Fibonacci 的例子, 在演講中只有一張投影片,
在這裡我嘗試做分解動作解釋一下。投影片內容在 http://www.slideshare.net/pycontw/largescale-arrayoriented-computing-with-python



我們知道 Fibonacci 序列是 x(n) = x(n-1) + x(n-2), 而 x(0) = 0, x(1)
= 1. Fibonacci 序列的產生也常常是教科書介紹 recursive 的好範例, 不過就
如 Travis Oliphant 所示, 用 recursive 實作的複雜度是 exponential 成長的,
而我們也可以用 SciPy 裡面的 linear filter 來實作這件事, 方法如下:




from scipy.signal import lfilter
from numpy import zeros
b = array([1.0])
a = array([1., -1, -1])
zi = array([0, 1.0])
def fib3a(N):
y, zf = lfilter(b, a, zeros(N, dtype=float), zi=zi)
return y




我來慢動作分解一下上面的實作方法。首先 lfilter 在 b = array([1.0]) 以及
a=array([1.,-1,-1]) 的情況下會產生b(0)x(n) = a(0)y(n) + a(1)y(n-1) +
a(2)y(n-2) 的式子, 代入 a,b, 我們可以得到 x(n) = y(n) - y(n-1) -
y(n-2),而 lfilter 的第三個參數就是 x 的序列, 是 zeros(N, dtype=float),
也就是說輸入全為零,上述的式子就會變成 0 = y(n) - y(n-1) - y(n-2), 把 y(n) 移到等式的左方, 就可以得到 y(n) = y(n-1) + y(n-2), 這就是 Fibonacci 數列的表示法啦! 最後的 y(n) 就是 Fibonacci 的第 n 個數列。另外,
zi=array([0,1.0]) 就是當 lfilter 開始執行的時候, delay element 裡面的元
素, 也就是 y(0) 與 y(1) 的值。



以濾波器的角度而言, 這個濾波器在輸入全為零的狀況下, 自己產生
0,1,1,2,3,5,… 這種發散的數列, 等於自己在震盪, 是我們在實際上不會去使
用的濾波器, 拿來實作 Fibonacci 數列, 實在是有趣。



--

Saturday, April 7, 2012

LaTeX PSTricks 訊號處理範例: z-Transform


上一篇的 moving average filter y(n) = (15/16)*y(n-1) + (1/16)*x(n) 的
z-transform 有一個 pole 在 z=(15/16, 0) 的點上, 要畫這個 z-Transform 在
z-plane 上的表示圖, 可以用下列的 PSTricks 來表示。




\usepackage{pstricks}
\usepackage{pst-sigsys}





圖形如下表示:
http://farm6.staticflickr.com/5238/7053583759_5fbddb20fc.jpg





\begin{center}
\begin{pspicture}[showgrid](-2,-2)(2,2)
\pscircle[linecolor=gray](0,0){1} % unit circle
\pspole(0.9375,0){z1}
\nput{0}{z1}{$(\frac{15}{16},0)$}
\end{pspicture}
\end{center}





--

LaTeX PSTricks 訊號處理範例: Moving Average Filter


今天要介紹的是如何用 PSTricks 來繪製訊號處理的 functional diagram, 假設
我們要描述的訊號處理方程式是: y(n) = (15/16)*y(n-1) + (1/16)*x(n). 這是
一個動平均濾波器, y(n) 是目前的輸出值, x(n) 是目前的輸入值, y(n-1) 則是上一次的輸出值,
那他的 functional diagram 會是如下圖所示:
http://farm6.staticflickr.com/5320/6907485526_81ef0d8ab5.jpg



上述圖形使用了 PSTricks 以及 PSTricks 的 pst-sigsys 套件,所以要在 preamble 的部份如下宣告:




\usepackage{pstricks}
\usepackage{pst-sigsys}





描述這個濾波器的 LaTeX source code 如下:




\begin{center}
% To describe y(n) = (15/16)*y(n-1) + (1/16)*x(n)
\begin{pspicture}(-2,-1)(10,2)
\pssignal(0,1){x}{$x(n)$}
\pscircleop[oplength=0.25,operation=times](2,1){op1}
\pssignal(2,0){coefx}{$\frac{1}{16}$}
\pscircleop[oplength=0.25](4,1){op2}
\pssignal(8,1){y}{$y(n)$}
\dotnode(6,1){ydot}
\psblock(6,0){delay}{$z^{-1}$}
\pscircleop[oplength=0.25,operation=times](4,0){op3}
\pssignal(3,0){coefy}{$\frac{15}{16}$}
\nclist{->}{ncline}{x,op1,op2,y}
\nclist{->}{ncline}{coefx,op1}
\nclist{->}{ncline}{ydot,delay,op3,op2}
\nclist{->}{ncline}{coefy,op3}
\end{pspicture}
\end{center}






--

Wednesday, February 22, 2012

gcc for Andes compile 出來的 assembly


為了要做 24-bit signed integer to 32-bit signed integer 的 signed extension 測試,我寫了以下的一小段 code 來測試, 在這裡順便稍微提一下 optimization, 我們先看 c code:




void testSign()
{
unsigned int test=0x00800000;
int test_s;
test_s = ((int)test << 8 ) >> 8;
}





除去 prologue 或 epilogue 的部份,我們來看主體:




00000614 <testSign>:
......
61c: 46 00 08 00 sethi $r0,#2048
620: 14 0e 7f fd swi $r0,[$fp+#-12]
624: 04 0e 7f fd lwi $r0,[$fp+#-12]
628: 40 00 20 08 slli $r0,$r0,#0x8
62c: 90 08 srai45 $r0,#0x8
62e: 14 0e 7f fe swi $r0,[$fp+#-8]




解釋如下:


sethi $r0,#2048

$r0 = 0x00800000

swi $r0,[$fp+#-12]

把 $r0 存回 test 的儲存空間

lwi $r0,[$fp+#-12]

把變數 test 值抓到 $r0

slli $r0,$r0,#0x8

把 $r0 做 logical left shift by 8 bits, $r0 = 0x80000000

srai45 $r0,#0x8

把 $r0 做 arithmetic right shift by 8 bits, $r0 = 0xff800000

swi $r0,[$fp+#-8]

存回 tests 的儲存空間。





而如果我們把這個 c code 改成如下:




int testSign(unsigned int value)
{
return ((int)test << 8) >> 8;
}





產生出來的 assembly 就會變成:




000005f8 <testSign>:
5f8: 40 00 20 08 slli $r0,$r0,#0x8
5fc: 90 08 srai45 $r0,#0x8
5fe: dd 9e ret5 $lp




這個版本完全沒有任何 local variables, 傳入的參數也只有一個, 當傳入參數
只有一個的時候, 會使用 $r0 這個暫存器傳入, 回傳值也是在 $r0 回傳,
所以這樣子最省空間了,也是我們 assembly programmer 會寫出來的樣子。注意
如果沒有做 (int) 的 explicit cast, 編譯器並不會使用 srai45 這個
arithmetic right shift 指令製造 signed extension, 即便是最後的回傳值是
有號數。


--
My Emacs Files At GitHub

Thursday, January 26, 2012

Emacs 的 org-googlecl 會把標題的 $ 吃掉


在上一篇「超便宜的 TI C6670 EVM, 只要 USD$599!」中,原本的文章因為 $ 在標題中被吃掉,所以變成了「超便宜的 TI C6670 EVM, 只要 USD99!」,想必標題相當吸引人,呵呵。


--
My Emacs Files At GitHub

超便宜的 TI C6670 EVM, 只要 USD$599!


參考連結: http://www.ti.com/tool/tmdxevm6670
這是 TI 的 TMS320C6670 EVM 的連結,這一顆 DSP 擁有四個 C66x 的核心,每一個核心都可執行 SIMD 指令,可以同時執行 8 組 32-bit 指令。TI 稱呼這個叫做 static VLIW, i.e. Very Long Instruction Word. 另外, C6670 有 Turbo encoder/decoder coprocessor、Viterbi decoder coprocessor、CDMA 用的 RAKE 加速器,還有 FFT coprocessor 等,頗適合拿來實作 WCDMA/CDMA2000/LTE 等各種 cellular communication 的基地台。當然,要拿來其他通訊模式也非常 powerful. 這麼強大的一顆 DSP, EVM 含 emulator 只要 USD$599 喔!



--
My Emacs Files At GitHub

SimPy slides in our company and PyHUG meeting


This is my presentation on discrete-event simulation given to engineers in our company and PyHUG, which is Python Hsinchu User Group. I think it might be useful for somebody on the Internet.
https://docs.google.com/open?id=0B0rtbYTzCZWN2Y5MmY4M2ItYzJkYy00ZTA2LWI5N2UtNmUxNjI5YzNjZTg0



http://dl.dropbox.com/u/31960195/Introduction-to-SimPy-20111017-PyHUG.pdf



--
My Emacs Files At GitHub