二月 15, 2016
» 假太陽

這則《假太陽》我是還在學時閱讀,那時啃完後覺得滿震撼的。故事是說人類最熟悉的天體,每天抬頭就可以看到的太陽,竟然是假的!原本真的那個太陽供應的能源只夠地球演化出猿猴,現在這個「假」太陽是被「人」調包過的!這則《假太陽》故事有點宗教味道,但又不脫(倪匡筆下)科幻橋段,初次閱讀的應該不少人會跟我一樣,整個腦袋瓜轟轟的吧 XD在 GodspeedLee 的分享下得知《時間迴旋》一書也有假太陽的設定。趁年假,花了一天的時間,順手把《時間迴旋》啃完了。就科幻的部分,《時間迴旋》描寫更細膩,它除了會說明太陽跟地球的演化史外,也針對太陽被替換的方式,提出一系列合理的影響。例如說,夜空沒了星斗,月亮也不見了,甚至極光也消失了。這些是很好的科幻素材,依附在上面的人事物也由此帶出。不過也因為內容描述太過詳盡,加上敘事方式不是很連貫,所以我是覺得有點囉唆。不符合我啃書喜歡挑重點的習慣 :p

二月 3, 2016
» Embedded Systems 中的 Resource 管理

開發 Embedded Systems 常常會碰到 f/w 要用到圖、字型、甚至音樂等 resource 的情況。實務上一種處理方式是將這些 resource 轉換後串成一個大的 C array 。然後再用 resource ID 去讀取它們。一些書上稱這種轉換的工具叫 Resource Maker 。不過我不會採取這種作法,雖然還是透過 resource ID 讀取,但不把 resource 轉成 C array ,而是直接轉成 binary 格式,要用時才去 storage 裡 load 進來,因為這樣比較節省記憶體空間。多年前我就用 Python 寫了類似的工具,那時我把這支程式稱作 weave 。後來慢慢精練,演變成今天要介紹的 ResourceLink 。同樣地,這裡我主要也是著重在 ResourceLink 裡用到的領域專用語言,來看看我怎麼描述這些 resource

二月 1, 2016
» 利用 LangConvert 工具處理多國語言

開發 Embedded Systems 相關應用時,常得處理多國語言。而系統資源受限的的場合,就算掛了 OS,往往也沒內建多國語言。這時候只能捲起袖子自己處理了。自幹的過程,很直覺地,多數人都會想到要有個類似右圖這樣的 Excel 字典檔當作翻譯表。有了翻譯表後,我們還要有個字庫(font)。為了存取字庫裡的字,我們要先決定字序(character order)。有了字序後,我們就能根據字序,把翻譯表裡面的多國語言訊息,一一轉換成字序的串列(a sequence of character orders)。要秀某個訊息時,就根據這個字序列,回過頭把字庫裡的字形(glyph)抽取出來顯示。如果要通吃幾乎各國的語言,一個奢侈的做法是直接用 Unicode 當字序,建立完整的字庫。不過這不適合用在資源受限的場合。多年前,我遇到決定字序的問題時,想了一種簡單又好用的表示法。以 ASCII code

一月 28, 2016
» 以 EnumLookup 查詢 C enumerator

前陣子我把 AWK 撿回來練習,順便研究一下 Windows 下怎麼跑 GAWK 跟 AWKA 之類的工具。這期間,我想了幾個簡單的題目來練習。其中有個我稱作 EnumLookup 的工具,一些慣 C 的人應該會用到,所以在這裡做個分享。 顧名思義,這個工具的目的是針對 enum ,它可以在多個 C enumerations 上查詢 enumerator 或它們對應的值。這裡是安裝跟執行說明文件,大家可以根據上面的指引,直接下載內含執行檔的下載包來試用。這個工具有個搭配的 enum.bat ,執行後可以雙向查詢:可反覆敲進數字來查對應的名字(enumerator),或者敲入名字(enumerator)來查對應的索引數字。需要注意的是,這個工具沒有真的去實作完整的 C enum parser ,只是認「通常」情況下的 enum 特徵。下面這種寫成一行的寫法,無法正確執行:typedef

» 利用 PicCrop 工具來切圖

記得小學製作海報時,會用剪貼的方式分工,快速拼湊出一張教室海報。時代進步了,現在大家都用電腦,我好幾次觀察到現在美術人員幫忙設計 UI 時,也常常會先把整體畫出來,然後再一塊塊的剪下來。這些剪下來的圖,還有個貼切的稱呼,叫「切圖」 現在有很多現成的切圖工具,幾乎都搭配 Photoshop 使用,甚至 Phothoshop 本身對這道工序也提供一定的支援。不過我沒打算在這介紹這些搭配 Photoshop 的圖形化工具,而是想設計一個專用的語言,來執行這個切圖的動作。 這個語言要告知原始圖檔,然後再列出每張被切下來的圖的位置、大小、甚至名字等。舉個例子,假設我要把圖中八個紅線匡起來的部分,一一切下來存檔。 最簡單的描述方式,大概就長這樣子: # source picture #--------------- ipod-touch-5th-black.png # x, y,

一月 24, 2016
» The Menu Show

接連多日的年假已接近尾聲,吃吃喝喝之餘,很自然地就想到一個跟吃喝有關的練習。雖然年假前在公司搞的相框產品確實用到各式 UI 選單(menu),但我在這裡要聊的是名副其實的菜單(menu)。 為了製作精美的菜單,我用 Google 搜來幾張食物的圖片準備用作底圖,除了一張用作食物主選單底圖外,其餘三張分別用作飲料類、水果類和蔬菜類等用途。考慮到要製作的菜單不只一張,且每張菜單的內容會一直修改,所以我不打算用繪圖軟體繪製菜單,這個重任當然要照慣例,委託給爬說語。要執行這支程式,必須先以 YAML 語法,利用文字編輯器寫下菜單的內容及呈現方式,存成 menu.yaml 。程式執行時會自動讀進這個描述檔,然後描繪出期望的菜單來。例如說,有張菜單長成這樣: 這是一張飲料類的菜單,它有 Coffee, Juice, Soda Water, Tea 等選項,要產生這張菜單, menu.yaml

» Commands of the NAND

到電子商場逛一圈就會發現一堆產品都有 NAND flash 的身影(例如大拇哥,記憶卡,MP3 player,數位相框,甚至 PC 等)。前陣子和 simayi 閒聊時,他就提到:既然大家都愛用 NAND flash ,要是有人為它搞個 IP 或函式庫之類的,勢必可大幅節省開發時間。 相信處理過 NAND flash 的 firmware 人員,在啃讀 datasheet 的過程,難免得謹慎地交叉比對,好好推敲那也佔了不少篇幅的時序圖,以免自己還是不夠小心,誤解文意……不知道大家看了那一疊 waveform 後,有什麼感想?我的看法是,那疊圖雖補足了許多重要細節,卻沒能好好強調重點,抽象度不夠。這根本是在折磨 firmware 人員,使我們構思演算法時綁手綁腳。因此,在 K 完文件後,我為這疊 command waveforms 作的第一件事就是--提昇抽象度,強調重點,用

一月 17, 2014
» FFT in Python

想知道一段訊號的頻譜,實務上我們會運用數位訊號處理,對這段訊號抽樣,得到一段時間序列;並計算時間序列的離散傅立葉轉換(Discrete Fourier transform, DFT)。然後據以估算出離散時間傅立葉轉換(Discrete-time Fourier transform, DTFT),最後再視需要,將頻域橫軸由離散時間的數位頻率(Ωk = ωkTs = 2π fk/Fs)換算回連續時間的訊號頻率(fk)。 張智星老師的 on-line book《音訊處理與辨識》〈離散傅立葉轉換〉這個章節,有許多運用快速傅立葉轉換(Fast Fourier transform, FFT)的教學, FFT 其實就是 DFT 的快速算法。張老師是以 Matlab 作為程式範例;經實際嘗試,我發現可以很容易轉成 Python code ,以下就看看執行結果截圖: 其程式如下:

十二月 16, 2013
» The Art of Design

為甚麼好的設計會來自於差的設計呢? Scott 在 Why Good Design Comes from Bad Design 提到攻讀 CMU Computer Science 博士時選了門介面設計課,第一堂課上他發現一位年輕人素描著隨身聽的各種變異版本,而且圖紙上已經堆積了三、四十種不同考量的版本了。 Scott 於是湊過去問這個小伙子「幹嘛費勁畫那麼多草稿?」,小伙子發楞了好一會才笑著回說: I don't know what a good idea looks like until I've seen the bad ones. 經過時日洗煉, Scott 後來也體會到當初認為多餘的作法,其背後的精神,他提到: Each new idea I sketched out was more informed than the last. Each bad idea

八月 9, 2009
» Python 與 CSV

許多資料,像通訊錄或試算表之類的,很適合列表呈現。而 comma-separated values, CSV是微軟牌視窗軟體存放表格資料常用的檔案格式。這種純文字的檔案格式是以逗號(comma)來為每筆(record)資料的欄位(field)作分隔。 舉個實際的例子,不久前我因論文需要,由 Davis 那取得了 1999 年美國千大企業的董事會成員資料。內容包括這些董事(directors)的公司、職稱、年齡等等。 由於我只關心每間公司的董事有哪些,所以就輕快地以 Python 語寫了一個 function ,要電腦讀入這個 CSV 檔後,順便吐出各公司的董事們: def LoadBoards_v0(fn='direct99.csv'): """Loads directors of companies from a CSV file and

» The Fraction from a Decimal

定點數運算常用於 embedded systems 中,因為大部分低階的 MCU (例如: 8051, PIC, AVR 等)開發環境雖提供浮點運算,卻是軟體模擬的,除了慢,還明顯佔用原本就少得可憐的記憶體空間。 C/C++ 語言雖無定點數運算專用語法,程式員卻可通過手動調整,有效以整數運算完成相同效果。 定點數運作的原理,簡言之,就是將原來的實數(real number)或者小數(decimal),改寫成分數(fraction):如果 x 是個含小數的實數,我們可以找來兩個整數(p, q),將它們相除,來近似原來的 x (p/q ~= x)。 實務上人們可能還會要求上述的 q 要是 2 的冪次,因為電腦處理的都是 0, 1 的二進位運算, q 表示成 2 的冪次可以達到較高的精度;另一個原因我想是許多 f/w 程式員都患了 shift 偏執症 :p 有個友人前

七月 4, 2009
» NAND Flash 簡介

撬開一張 SD 卡,裡面最顯眼的,當然就是那大大一顆的 NAND flash ,我們餵給 SD 卡的資料都儲存在裡面;在 NAND flash 旁邊,還可看到一顆小一號的,那就是 controller IC , 要確保資料的儲存是安全可靠的,有九成的責任都要算在 controller 身上。 在硬體介面方面, NAND Flash 雖有 bus 結構,卻沒去區分 address bus 及 data bus 。在 NAND Flash 上進行任何操作(如 read, write, erase 等),都要透過 command ,且無論 address, data, 或 command,都以同一組 I/O bus 傳輸。 此外, NAND flash 在資料 program 或保存過程,還會隨機出錯,所以廠商才會建議搭配 ECC (Error Correcting Coding)

» Be Pythonic -- 字正腔圓說 Python

學任一種語言,要說得道地,關鍵是融入語言的風格特色中,體會語言社群的風土,知道他們的慣用法。 既然 Python 寫的 code 有 executable pseudo code 的美稱,想寫出 Pythonic 的 code ,當然要站在一定的高度,讓寫出來的 code 夠 pseudo... Pythonic 一詞被用來形容合於 Python 慣用法的 code 。Pythonic 的 code 除了讓人們更好理解外,機器執行時,也往往更具效率--語言設計者會絞盡腦汁最佳化語言慣用法的執行效率。這在 Python 這類高階、動態的語言,尤其明顯 :) 幾個 Pythonic 的準則: 讓程式結構盡量扁平(flat) 降低 Loops 的複雜度 少用 counter ,偶爾用一下 iterator 改採 Functional

» Analyze the Sunspots

上次以 Python 搭配 matplotlib 改寫張智星老師傅立葉轉換教學例子。後來逛到 Anders Andreasen 的專文,裡面有個分析太陽黑子活動週期的例子,相同的例子竟然也出現在 Mathworks 展示 Matlab FFT 用法的網頁上。既然大家那麼愛用太陽黑子,我也來攪和攪和,再次以 Python 搭配 matplotlib 改寫: <!--DOCUMENT_FRAGMENT--> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66

» Two Ways to Solve a Problem

這些年下來,我反覆觀察到一個現象:程式員各有一套慣用的方法來克服自己遭遇到的問題,這些解題習慣可區分成兩種,工程師多只專精其一,只有少數能任意在兩者間自在地切換。 在很多情況下,無論程式員採用哪種作法,都可輕易把問題解掉;但是另有一些問題,卻不是這樣隨性而為就解得掉的--這就值得我們好好玩味了…… 以 1..n 的正整數相加這個例子來說,我知道程式員應該利用現成的副程式,以爬說語來寫,應該要長成這樣: n = 100 y = sum(range(1, n+1)) 假裝我們沒有現成的,像 sum 這樣的副程式可用。那麼,一種可能的寫法如下: y = 0 for i in range(1, n+1): y += i 這是標準的合成(Synthesis)法。以這個例子來說,如果不考慮時間複雜度要 O(n) ,這個方法其實

» The Analog Clock

……秒針急急忙忙的去撥動每一根短棒,使它們產生意義。然後分針慢吞吞的做同樣的事,使那些短棒產生另一種意義。三種針的位置和關係不斷變更,在錶面上切割出許多角來,夾住那不可捉摸的時間。……(摘自作文七巧:P86) 算一算日子,在現任公司混吃也有九個月了。很幸運的,一進來就參與一顆 ASIC 的開發,從一開始的寫 tools 測試 FPGA 功能,後來的寫 f/w 測試 ASIC ,到最後的參與產品開發。照規劃,一開始只打算拿來秀秀圖,偶爾也秀秀時間日期。後來為了把這顆小 MCU 的能耐完全壓榨出來,前些日子我還幫它加了類比鐘(Analog Clock)。自此,相框就不再僅僅只是相框了: 想起專科的畢業專題,我實作過一組函式庫,用來執行 3D 投影及相關的座標轉換。一晃眼已經十多年了,最近為了完成的這個類比鐘,竟然連描點畫線的程式都得自己手寫……

五月 20, 2009
» The Floating Gate

浮動閘(floating gate)一詞會讓我銘記於心,是因為閱讀了《矽眼》,該書提到以浮動閘紀錄類神經元突觸加權值,這是「類比」儲存的一個應用。 然而,對多數內嵌系統設計人員來說,浮動閘是用在「數位」儲存的,諸如 EPROM, EEPROM, NOR flash, NAND flash 等。 無論是 EPROM, EEPROM 或 NOR flash ,早先都是設計來在上面直接跑程式的(不用 copy 到 RAM 上跑,術語叫做 execute in place, XIP),所以有獨立的 data bus 及 address bus 。 為了省空間,後來很多 MCU 都把 EPROM, EEPROM 或 NOR flash 包進同一棵 chip 了,這造成外部的 EEPROM 或 Flash 開始走 serial 路線。 serial EEPROM 或 serial

二月 9, 2009
» Fingering of Keys

按鍵是很普遍的人機介面,也常用於內嵌系統(Embedded Systems)。既然大家那麼愛用按鍵,很自然地, Embedded Systems 軔體開發人員就常常得處理按鍵的偵測、編碼等議題。此外,為了按鍵操作流暢,我們還必須為按鍵設計適當的指法(fingering)及明確、統一的功能定義(function definition)。 不久前筆者設計了一款相框產品,它雖然只有三個按鍵,但除了要能執行基本操作,如上一張、下一張、設定自動換張的間隔時間等;也要能夠流暢地切換功能,如手動換張、自動換張、顯示日期時鐘、功能設定等;此外,最好還能透過這些操作,讓使用者充分感受到它優越的秀圖速度。 老實說,把這些操作通通塞進三個按鍵內並不是多困難的事,比較需要我們傷腦筋的是怎麼讓使用者覺得操作是簡單流暢、符合預期的。 這裡不是要跟你扯怎麼設計美美的畫面,雖然美美的畫面很重要,但畫面設計還是

二月 2, 2009
» Parser Generators

在軟體開發過程,我們很可能得寫大量的程式碼來完成一些繁瑣、平凡的工作,避開這個窠臼的辦法就是「自動化」。誠如 Kernighan 和 Pike 在 The Practice of Programming 一書所闡述的,優秀的軟體設計運用幾個基本原則:簡單(simplicity)、清晰(clarity)、一般性(generality)、自動化(automation)。 舉個例子, IC designers 常會跟 f/w 人員一起關起門來,私下協調出各種用途的 registers (memory mapped I/O),這些開放給 f/w 人員使用的 register 介面,會有一份以 Verilog 形式存在,另一份則以 C code 的形式存在,在 IC 開發過程,這些 registers 會經歷多次的變更(例如改名字、改位址、添加 registers、刪減

七月 13, 2008
» Phases of a Compiler

先前曾經探討,像我們這種靠寫程式混吃的,最好備有兩把刷子,當發現其中一把刷子無法刷掉問題時,趕緊換上另一把刷刷看。通常一次只要用上一把,就可以把問題刷掉,偏偏有些問題比較棘手,要同時用上兩把刷子,左右開弓,才刷得乾淨! 這些要左右開弓的問題中,有個最典型的例子,那就是實作一個程式語言的編譯器(Compiler),它運作時恰好要經歷「分析」及「合成」兩個階段,這實在太妙了,所以我將它整理整理,簡述如下: Analysis Phases Linear Analysis alias: scanning, lexical analysis output: token stream language: Regular Expression Hierarchical Analysis alias: parsing,

biggo.com.tw

A Django site.