發表文章

目前顯示的是 1月, 2009的文章

文章總列表

Embedded System Studying note 1/26

About FAT File Allocation Table 是微軟的招牌檔案系統 (FS) 從 DOS 時代用到現在, 隨便找一台電腦都能讀寫 如果能讓嵌入式系統讀寫 FAT 如此嵌入式系統很容易和電腦互通, 很有移植的價值 我有抓了微軟的 FAT spec 來讀 http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx 讀得差不多, 也比對 spec 和 SD 卡的資料後, 我相信微軟說的是對的 但我沒打算寫FS, 畢竟我不是專業資訊玩家, 自己刻 FS 太辛苦了 Internet時代, 業餘玩家要懂得站在巨人的肩榜上... ---- About FatFs http://elm-chan.org/fsw/ff/00index_e.html

Embedded System Studying note 1/24

Low priority task/ Background task ---- 在寫 SD card driver 時 我希望把 driver 寫成 interrupt 的形式 但是 SD 卡的操作, 我很難包裝成 IRQ 的形式 下面的程式是 SD 卡諸多命令之一 麻煩的是上藍底的部分, 要等待 SD 卡給回應 這個 sd_wait_command() 也不是很聰明, 直接用 polling 的方式硬來 static int CMD25 ( unsigned int addr ) // WRITE_MULTIPLE_BLOCK { unsigned int i ; for ( i = 0 ; i < SD_COMMAND_RETRY_COUNT ; i ++) { sd_send_command ( 25 , addr , SD_RESPONSE_SHORT ); if ( sd_wai

Embedded System Studying note 1/17

實作出 SD card 的 READ_SINGLE_BLOCK 的指令了 這個指令能從 SD card 讀出 512byte 終於能從 SD card 讀取資料了 :D 讀出 SD card 的 address 0 的內容 這個地方放的是鼎鼎大名的MBR (Master Boot Record), 主開機區塊 ---- 對硬碟來說, x86 電腦開機會從 Cylinder=0, Header=0, Sector=1的地方拷貝512byte 到記憶體位址 0000:7C00 的地方執行, C/H/S = (0, 0, 1) 的這個區塊就是 MBR 我們會說 "硬碟如果開機磁區壞了, 就整個沒救了" 在磁碟片的時代, 我們經常說 "第 0軌壞掉的磁片, 跟報銷沒兩樣" MBR 的角色是如此的重要, 值得花點時間研究一下 !!

Embedded System Studying note 1/15

把 SD 卡初始化的程式寫出來了 真的是... 給他有點難寫... SD protocol 是不會難, 但是寫起來就是有些眉腳 這邊卡那邊卡, 短短四百行程式寫了將近三個禮拜 手邊剛好有幾張 SD 卡, 給他讀看看... TOSHIBA 128M/ 創見2G/ 創見2G 150x/ Apacer 8G ---- TOSHIBA 128MB SD Version: 1 SD RCA: 0x5F1A SD OCR: 0x80FF8000 CID information Manufacturer ID: 0x02 OEM/APP ID: 0x544D Product Name: 0x5344313238 Product Revision: 0x07 Product Serial Number: 0x665DB60F Manufacturing Date: 0x042 CSD: 0x002D0032 0x135983C0 0xF6DA4FFF 0x16400031 ----

Embedded System Studying note 12/25

DMA driver rev.0 完工 可以透過 SW 直接去 trigger DMA 這算是基本功夫吧 真正的重頭戲是用 HW 當 DMA source

Embedded System Studying note 12/21

DMA & Cache Cache 和 DMA 通常會有 coherence 的問題 這個問題在 wikipedia 有一篇不錯的文章 http://en.wikipedia.org/wiki/Direct_memory_access#Cache_coherency_problem 當 CPU 的 cache 存在某個記憶體位址的內容 而這段記憶體又被 DMA 寫入時 cache 和 DMA 就不會同步... (傷腦筋) 我現在想到兩招可以避這個問題... 1. 第一招就直接 flush Data-cache 但這樣感覺會錯殺無辜... 2. 第二招是把 DMA寫入的位置, 告訴 MMU說這個地方是 non-cacheable 但這樣存取那塊 non-cacheable記憶體, 似乎又有點慢 有沒有人知道比較好的方法的...

Embedded System Studying note 12/21

DMA, Direct Memory Access ---- DMA 是攸關系統效能的重要元件 在系統裡經常要做資料搬移 這些事一般我們會靠一個外部的硬體幫忙做掉 不然 CPU光處理這些垃圾事, 正事都不用辦了 之前寫好的 USB shell這次正好派上用場 讓我在不寫任何一行 code 的情況下, 驗證 DMA的功能... 實驗是這樣進行的 首先準備一個檔案, 大小剛好是 64KB 1. 把檔案用 wr 的命令, 寫到記憶體 0x32000000 的地方 2. 用 DMA 把資料搬到 0x32800000 3. 用 rr 命令把檔案讀出來 4. 最後用 Araxis Merge 這個變態的 merge tool 幫我做 binary 比對 照這個想法, 寫出來的命令異常的簡單... step.1 wr 0x32000000 c:\fw.bin step.2 w4 0x4B000000 0x32000000 ; source addr w4 0x4B000004 0x0 ; source addr increment w4 0x4B000008 0x32800000 ; destination addr w4 0x4B00000C 0x0

Embedded System Studying note 12/19

埋 log 是很好用的方法, 為了提供高效率的 log 函數 我在 UART driver 上下了很多功夫, 除了用 interrupt driven 以外 還寫了一個 RING buffer, 讓資料寫進去, 可以之後慢慢送 配上 C standard library, 可以用 printf() 的感覺真的很好 不過在 BSS section 沒有填 0 的狀況下... 問題就不是用 log 那麼單純 ---- 我在 code 裡寫... int (*a)(void); int main() { ...} 這個 a 是 global variable, C 語言會假設 a 的初始值為 0 在 Win32/ Linux 底下, loader 會幫你做這些事, 把初始值填 0 但是 Embedded system 這些雜事得自己做... 如果不做會怎樣 ? a 是一個 function pointer, 我很喜歡這樣寫...

Embedded System Studying note 12/18

搞定 USB 的 Flash utility 可以在 PC 和之間做資料傳遞, 以及提供 Flash Utility 再稍微加工一下, 就能方便的下載 firmware 了 r1 Read 1-byte from ARM memory r2 Read 2-byte from ARM memory r4 Read 4-byte from ARM memory rr Read a range of memory from ARM w1 Write 1-byte to ARM memory w2 Write 2-byte to ARM memory w4 Write 4-byte to ARM memory wr Write file to ARM memory flash_erase Erase one block of flash flash_read Read blocks of flash to file flash_write Write file to flash help Show this help ---- 處理掉一些滿難搞的 bug... C 在執行時, 要把 program code 要從 Flash 載入到記憶體 程式越寫越大, 忘記把載入的區塊放大 難怪程式執行起來很不正常 在進入 C environment 之前, 要先把 BSS section 清成 0... BSS section放些未給初值的 global variable 這些變數預設要清成 0 我在呼叫 clear_bss_section() 清光這些資料前 就跑去執行其他初始化, 難怪 ARM 會跑到奇怪的地方 或是抓到奇怪的指令 對自己寫的 code 太鐵齒, 以為保證不會錯, 用了這種結構... while(put_string(str) == -1); put_string() 就是有可能一直失敗,

Embedded System Studying note 12/1

Shell 加入UART的狀態, 可以觀察和清光 FIFO 同時也改進從 UART 取字串的程式 改進他的效率 ---- ARM -> (USB) -> PC 相關的 Library 完工 接下來可以來寫 USB 燒寫 Firmware 的程式 ---- Todo: 1. USB Firmware downloader 2. 研究 SD 卡怎麼存取

Embedded System Studying note 11/23

UART driver 弄得比想像中還要久一些 這支 driver 如果想要跑在 multi-tasking 的環境 而且速度要快, 必須搭配一個 ring buffer 為了要加速, 對 ring buffer 的存取要要最佳化 並且考慮 UART 硬體的限制 還有 Tera Term 的限制: 換行時, 要輸出 \n\r, 只輸出 \n 是不夠的 這部分的 driver 陸續修好了好幾次 終於有一個比較穩定的版本出來了 ---- 為了要讓我的 uC/OS II 有一個 shell 可以用 把先前開發完畢的 getopt() 拿來撰寫我的 shell 目前已經可以支援一些簡單的命令: help Show this help irq Show IRQ status, incluing IRQ name, # of ISR hooked, Call count r1 Read 1-byte from memory r2 Read 2-byte from memory r4 Read 4-byte from memory w1 Write 1-byte to memory w2 Write 2-byte to memory w4 Write 4-byte to memory 透過像這樣的命令列介面, 如果只是想看某個記憶體的數值 比起使用 Keil ARM 這樣的工具, 有時候更能直接的完成目的 其中 irq 工具會列出一張表, 紀錄所有中斷的狀態 這個是從公司的開發工具裡, 偷回來的 idea XD 寫這個 shell 的感覺很有意思, 很像在開發 DOS 作業系統裡的命令 ---- USB 的部分, 我當然不會寫 Windows Driver... 好在有 LibUSB-Win32 這個好東西... http://libusb-win32.sourceforge.net/ http://libusb.sourceforge.net/ http://www.jollen.org/blog/2008/01/libusb_hello_world.html 這東西真的有意思, 有了他, 不用自己寫 Wind

Embedded System Studying note 11/03

動起來了 !! 每天下班回來都好晚, 趁睡覺前一兩個小時累積起來 總算讓 USB動起來, 把我的版子接上電腦 Windows 終於會發出找到新裝置的聲音了 哈哈, 有圖為證 http://picasaweb.google.com/lh/photo/iEMQFSBpfZA0NWwvIzvAlA 弄了兩個禮拜, 終於完成 USB Enumeration, 讓電腦找到他了 :D :D :D ---- 接下來, 就可以來弄點 Windows 這邊的程式 Device Driver 可以拿別人寫好的先來用 我可以寫個 Windows程式, 來跟ARM 傳訊號, 傳檔案 ARM 這邊, 還有另一部份的韌體要完成... 等上面那些玩熟了, 可以把ARM 的 DMA 打開 用版子上的記憶體來實作 RAM Disk 想辦法弄懂 Mass Storage Device 怎麼運作的, 把我的版子模擬成隨身碟 這樣在 Windows 看到的就是一個磁碟, 可以直接把檔案丟進去 ---- TODO: 1. 加入一個 shell, 讓我可以下命令 * getopt() 2. 寫 USB driver * USB Device Driver * USB Host Driver

Embedded System Studying note 11/03

USB driver 確實開工了, 有兩份資料寫得很好... USB in a nutshell http://www.beyondlogic.org/usbnutshell/usb-in-a-nutshell.pdf ChamberPlus 的網站 http://chamberplus.myweb.hinet.net/ 閱讀這些資料, 配上 USB 的 spec... USB 2.0 spec http://www.usb.org/developers/docs/usb_20_040908.zip 然後中國的資料真的很多, 這個網站連範例程式碼都給了... http://0rz.tw/cb50A (RealView 的中國網站) 還有一份實驗指導書, 如果要學韌體, 中國的資源真的很豐富... http://211.64.47.133/web/shiyan/shouce/EduKitII-2410.pdf 有這麼多資料, 應該要很順利, 但有件非常重要的事被我忽略了, 以致於進度還是 0 那就是... 我電路板上的 USB-Device 接頭壞了, D+ 接腳根本就斷了 這樣一來, 任憑我韌體寫得再多, USB-Host 也不會理我... 只好等禮拜一把板子拿去公司, 拜託硬體 team 幫我 rework 一下... ---- 上個禮拜順利把 C Library 放進去跑, 這樣就可以用一些比較熟悉的函數 比如 printf(), 字串系列的函數 我打算在 uC/OS II 裡建立一個task, 他會等待使用者輸入的命令 (字串) 利用 strtok() 和 getopt(), 提供一個功能完整的 shell 可以下達一些命令, 比如對某個記憶體位置讀寫 目前已經把 strtok() 的部分完工, 使用者輸入的字串能分析成一個一個的小 token 下一輪再用 getopt() 來實作各種命令 :) TODO: 1. 加入一個 shell, 讓我可以下命令 * getopt() 2. 寫 USB driver * 電路板 rework * USB enumeration

Embedded System Studying note 10/26

下了班, 還是可以玩一下 ARM, 真是太幸福了 :D ---- 上個禮拜把 MMU (Memory Management Unit)打開 順便開了 I-Cache 和 D-Cache 程式執行立刻加快 10 倍, 相當的愉快 !! 我還沒有要用 Virtual Address 的高級屬性 (比如 read on demand) 所以先讓所有 Virtual-addr 等於 Physical-addr 這樣現有的程式都可以繼續用 我在 Interview時, 寫過一個考題是這麼問的... 對於 CPU的 special function register, 可否對他開啟 cache ? 答案是no, 開了會出事, 這些 register 可能會自己更新, 而 cache 沒有同步更新 反應在 MMU的設定裡, 就有設定每一塊記憶體區域是否 cache-able ---- Keil ARM 提供了 Standard C Library, 我很需要格式化輸出的功能 (printf) 但是 Keil 的文件真是寫得落落長, 看了半天才慢慢拼湊出一些 idea... 首先程式的進入點是 __main(), 他要做的事如下... void __main(void) { /* * According to the manual, this function performs following tasks: * 1. Copy the non-rooted execution (RO & RW) from their load addr to exec addr. * 2. Zeros the ZI regions * 3. Branches to __rt_entry() */ // In my implementation, these tasks are done by bootloader code // So I just jump to __rt_entry() __rt_entry(); } 然後 __rt_entry() 去初始化其他的東西, 包括 stack & heap, library 最後才是進入 main() void __rt_entry(void) {

Embedded System Studying note 9/29

我買了一顆 J-Link, 中國製造只要台票 2568 可以用這麼便宜的價格 ICE, 我誠心的感謝對岸同胞在破解上的努力 http://www.segger.com/jlink.html http://tw.f3.page.bid.yahoo.com/tw/auction/c37893937 拿到 ICE以後, 針對把程式寫入 NAND Flash 很慢這件事, 可以這樣改善... - 先把程式碼灌入 SDRAM 裡 - 再灌入一小段 Flash Writter 到 CPU 的記憶體 - 呼叫 CPU 執行 Flash Writter 把程式寫入 NAND Flash 概念很簡單, 很多商用的開發套件都這麼做, 但是 S3C2410 + J-Link 似乎沒人做過 開發這一小段 code 也繼承了 Embedded System 難搞的特性... 接著要移植 uC/OS II, 我手上有大量的文件, 書, 程式碼, 但做起來還是有些難度 加上有點自以為是, 別人已經跑對的 code , 我還自作主張去改 最後發現 bug都是自己製造出來的... 後記. 總算是在工作以前, 把這個小小的 project 進行到一個段落 在履歷上寫, 我有 porting uC/OS II 的經驗, 總算從說嘴變成真正做過了 以後還有空玩這顆小 ARM9 嗎~

Embedded System Studying note 7/21

這個禮拜的工作進度 ---- 延續先前的研究, 我把開發工具從 ARM Development Suite 1.2 改成 RealView MDK v3.2, 繼續我的開發 先簡單的說一下這套工具的來歷... 在 8051 的世界, Keil C51稱得上是"標準"開發工具, 幾乎是是人手一套 Keil ARM 也是 Keil 的產品, 親切的介面讓我愛不釋手, 當年靠他順利完成某個專案 ARM 買下 Keil 之後, 重新推出的產品就叫 RealView MDK 有興趣的人可以到官方網站抓... http://www.keil.com/ 註冊機在大陸的網站找得到... ---- 這個禮拜我決定自己重寫一次Bootloader, 藉此掌握新工具的特性 很多時候, 我以為我會的東西, 實作時才發現千瘡百孔... 看別人寫的code, 我是跟著作者的思路, 按照作者鋪好的道路前進; 自己動手寫, 好比單槍匹馬闖入敵營, 處處是陷阱, 每個地方都可能出錯; 兩者難度的差異, 恐怕有 1~2個 order "BootLoader開發經驗談" http://0rz.tw/da4r0 ---- 我的 CPU 是 Samsung S3C2410, 開機會到 NAND Flash 抓 4k 的程式碼 Bootloader 窩在裡面, 他必須初始化CPU 各項周邊, 比如 SDRAM 的 timing 初始化 再把 NAND Flash 的內容載入記憶體, 最後執行 OS, 把控制權移交出去 看起來很簡單... 寫起來才知道苦啊... 我知道 CPU會去抓資料, 這件事我得先驗證 我寫了一支小程式讓 LED閃爍, 讓 CPU 開機從 Flash 抓出來並執行 光驗證這件小事就夠折騰人了... 工具不大會用, 下載的速度又慢, 短短一段 code 要 1分鐘 好不容易傳完了, 重新開機只看到死寂的版子 我也不知道從何著手 debug Orz 好不容易克服這些障礙, 現在已經讓 SDRAM 動起來, 可以寫 C 了 現在正在寫 NAND Flash Driver, 等這個完成, Bootloader 就算是開發完成了 :D ---- 玩到這裡, 我決定投資一套 ICE, 來加速程式開發, 比如下載 Flash 可以秒殺 國外原廠的工具都太貴, 還

Embedded System Studying note

這是一系列的嵌入式系統學習經驗 原本的文章發表在另一個 BBS的個人版 現在全部移到 blog 上 ---- 2008/07/07 回到家, 把很久以前買的 ARM9 Linux 開發版又拿出來玩了... 感謝 Elmer 開實驗室讓我用, 簡單的焊幾條線, 稍稍對電路板進行破壞後 把開發套件裡的 JTAG cable 改裝成 Wiggler JTAG 有了這東西, 我就能對 ARM9 CPU 進行單步驟執行之類的操作... http://blog.xuite.net/kyanite0909/techshare/15457382 當年好像是看到人家說, ADS (ARM Development Suite) 是個用起來很古怪的程式 於是多年來, 懷著恐懼, 我始終未曾用過開發這個套件 (想想還真的有點莫名其妙) 克服內心的恐懼, 把 ADS 1.2 裝起來, 順利和 Wiggler JTAG 連線 在網路上找到適當的範例, 成功的顯示 Hello World 在終端機的介面上 :D ---- 惡魔通常隱藏在細節裡... 這句話真的是沒錯, 這個週末做的事情其實很簡單 只是透過 download cable, 把程式下載的版子上, 並且印一些字出來 沒什麼技術可言 但是如果要同時搞定 ARM, ADS, ARM Assembly, Hardware 光是搭建一個開發平台, 就夠讓人吃盡苦頭了 侯捷在 "深入淺出 MFC 2/e" 這本書的第一章標題下得很好: 勿在浮沙築高台 侯捷的話固然正確, 但是對大部分的初學者來講 光要把地基弄穩, 就已經是很長的故事了... 比如大家寫程式, 可能會用 Visual C++ 但是 compiler 背後的機制, 背後做了多少事, 恐怕比 C/C++ 還要複雜得多 我的感覺是, 像我這樣的DIY族/初學者, 學東西根本就是在浮沙堆中奮戰 失敗是正常的, 看似簡單的事, 路途卻是異常的曲折 總是要經過一次又一次的失敗, 才勉強學到一點東西 ---- 繼Windows Programming 之後, 我又開始玩起另一個玩具了... 其實好像也沒玩得多好, 只是簡單看一下是怎麼回事, 注意力又跑到別的東西上 反正當阿兵哥, 時間很少, 讀興趣就好... 好讀書, 不求甚解, 每有會意, 便欣然忘食