在(臺灣的)電子材料行或拍賣網站中,除了嵌入式系統開發板本身,會一起出現的設備是燒錄器、編程器、下載器、仿真器、除錯/偵錯/調試器,隱隱約約知道他們好像是用來把程式下載到開發板上的。

有這麼多名稱且設備外觀都有點小差異不打緊,但價格還差很多。拍賣網站上幾乎所有賣家的說明和圖片都照抄淘寶。電子材料行有些也不解釋,或是商品名稱顯然也來自淘寶,包裝上號稱有教材網址,有些連結也失效或是需要登入,隱隱約約找到的一些文件都是直接下載一些官方工具用在賣家自己非官方的板子上...總之我是看得很茫。經過一些搜尋之後大概猜了一下這些東西名字的由來,以及確切的功能。因為資料一堆都出現在問答也難以查證,所以全文只是自己查完資料的推測,不保證任何正確性。

首先是燒錄器、編程器和下載器,這幾個名稱應該是從 programmable logic 中的 ROM 發展出來的,其中一種早期的 ROM 叫做 PROM(Programmable Read-Only Memory ,可程式化唯讀記憶體),是以內部的熔絲是否接通來表達 1 和 0 ,資料必須以施加電壓燒斷熔絲的方式寫入。而動詞 program 則持續使用到當今寫入快閃記憶體(flash memory)的過程。因此燒斷熔絲的方式被稱為「燒錄」,動詞 program 就成為「編程」。下載器則是強調現代這種裝置將電腦上編譯、連結完成的程式「下載」到嵌入式系統的 ROM 的過程。所以在我的解讀中,這三個詞是相同的東西,應該都直接對應到英文的 programmers 。

仿真/模擬器和偵錯/除錯/調試器就是原本功能有差異的裝置了,它們都是透過硬體線路達成程式除錯的裝置,所以分別稱做 in-circuit emulator(ICE) 和 in-circuit debugger(ICD) ,前者是以比目標平台稍強的處理器模擬目標平台的行為,並以此獲得目標平台內部除錯用的狀態,不會使用到目標平台自身的資源。後者則是使用類似 boundary scan 的技術,透過目標處理器本身安排的線路,將除錯用的訊號以特定的協定(JTAG/SWD)和 debugger 溝通。理論上來說,前者可以有最好的除錯環境,因為可以在不耗費目標處理器資源下發送一些很高階的除錯訊息(例如使用 printf)。但上面的解釋和現況其實有些出入,第一個是中文市場中仿真器和偵錯器看起來外觀幾乎是一樣的,但幾乎找不到長得和 in-circuit emulator 的圖片搜尋結果一樣的商品。第二個是仿真器如果自己能模擬目標平台,那外觀上還有一個要和開發板相連的接口要幹嘛?

第二個問題其實比較好想像,就是那個接口可以讓仿真器和開發板上的周邊裝置(IO、bus 等)溝通(雖然也有進一步的問題,但排句子好麻煩就不寫了)。而對於第一個問題,原本在想自己是不是其實把 in-circuit emulator 和仿真器的定義讀錯了,但後來看到了國外網站的一段問答,發現也有一些產品似乎本身是除錯器,但產品是以 ICE 命名。問答中也提到, in-circuit emulator 在嵌入式系統越來越複雜且運作時脈也越來越高的情況下,製造的成本會變得非常高,而且電路佈局也不允許處理器被拉到外面這麼遠的距離來模擬。因此逐漸由 ICD 處理除錯的大部分需求。所以我的推測是:現在中文市場裡外形和偵錯器一樣的仿真器其實都是偵錯器,真正的仿真器則可能已經消失在歷史洪流中,或是在簡單的晶片+複雜的程式+大量的預算(我猜是射火箭吧?)的情境才會用到。

現在的理解是第一組名詞基本是一樣的東西、第二組名詞只有一個好好地留到現在,那麼第一組和第二組名詞有什麼區別嗎?同樣就我的理解來說, debugger 通常包含 program 系統上 ROM 的指令,所以包含了 programmer 的功能。而反過來的情況,技術上是可以不包含 debugger 功能的(例如板子內建的 DFU mode),但我自己還沒有真正買過,所以也不確定是不是真的有不包含 debugger 單獨販售的 programmer。買 debugger 或「仿真器」 感覺一般來說不會錯了,也許等我有錢,一切真相就會大白(O)。

查到這裡完全可以感覺得到 Arduino 為什麼可以成功,打從一開始就讓除錯器不要出現在字典裏,讓紛擾留在 setup 和 loop 裡,和很久以後才有機會爆炸的 code (X)。就算是後續各種廠商對 IoT 應用特別設計的板子,也都遵循慣例避開了這個大部分學習嵌入式平臺會第一個需要面對的問題。

這篇文章是為了 STM32 打的,可能也適用於 8051 之類微處理器的情況,但對於 FPGA 雖然有一些相近的標準,但可能 debugger 們做的就是完全不同世界的事了。

Reference

单片机的仿真器和下载器是一个东西吗?

烧写器,烧录器,编程器,下载器,仿真器,调试器有神马区别?

Introduction to In-Circuit Emulators

What is the functional difference between an in-circuit-debugger and an in-circuit emulator?