7.23.2009

SD card, Command and Response

SD Card 的 Command 依照SD Card 的"回應"有很多"類型"。
回應就是"Response",一樣利用 SD card interface 的 "CMD" pin 來傳送。
= 所以 CMD line 是雙向 line

host 從CMD 送出command 後,讓 CMD維持 high-impendance,SD card 就可以拉動 CMD line,做出回應。
  • Spec 4.12 Timings 有詳細說明bus 的 timing.
Spec 上用 R1, R2, R3, R6 來區分Response 的內容。
每個 Response 的 data 數量不一樣。

每個Command都有規定的 Response 。

像 CMD2, CMD10 就要回應 R2。

7.21.2009

CE.NET Advance Memory Management

MSDN : CE.NET Advance Memory Management

大概說明空間的利用方式


記憶體管理就是管理記憶體位址空間 (memory address)。
32 bit 有 4G 的 address。
CE分成兩半來用,High-half 給 OS,Low-half給 Process。

Address 決定了,並不會立刻佔用phyical memory,直到這個Address的內容真得被利用到,才會真的把phyical memory mapping過來 (稱為 commit)。

CE 使用記憶體位址的規則是:

每個Process 有 32M 的 address 可以用。 但是要從 0x10000 開始用起。

由下往上依次是:
  1. Program Code
  2. Read Only Data
  3. Read Write Data
  4. Resource
  5. 預留的 Heap 空間
  6. 預留的 Stack 空間
剩下的就是 Free Space 和 RAM-Base DLL 用。

RAM Base DLL 會從 32M 開始往下 Load。

=> 所以 Free Space 是被 Process Code, DATA, STACK 和 RAM-DLL 夾著。

process 在執行過程中如果create seperate heap或call VirtualAlloc 會接在剛剛"預留的STACK空間"上面開始,找第一個符合的位址區。

接著講 VirtualAlloc 這個API.

是以 1k 或 4k 為 alloc 的單位。同時會對齊 64k。 <== 這個點問題,應該要怎樣"以4k 為單位,而且對齊 64k? 對齊 64k 不就是以 64k 為單位?

所以下面的code在CE里會fail:

for(i=0;i<512;i++)
pMem[i] = VirtualAlloc(0,PAGE_SIZE, MEM_RESERVE | MEM_COMMIT, PAGER_READWRITE);

因為這樣實際上 會alloc 掉的記憶體(Address space and physical memory) 是 512 * 64k Byte.
超過 32M.
=>雖然你只需要 512 * 4k Byte

所以要利用 Allocate Address 和 Commite Physical Memory 兩段式動作的方式來作:

pBase = VirtualAlloc (0, 512 * PAGE_SIZE, MEM_RESERVE, PAGE_READWRITE);

for(i=0;i<512;i++)
pMem[i] = VirtualAlloc(pBase+(i*PAGE_SIZE),PAGE_SIZE, MEM_COMMIT, PAGE_READWRITE);
這樣就只會用掉 512*4k的位置空間了。(同時又commit到實際記憶體)

接下來說明Load DLL 的記憶體使用情形

已經知道RAM-DLL 是從每個process的32M邊界往前(下)使用。
除此之外,所謂DLL,就是有"共用"的特性。所以有可以一個DLL被2個 process使用。

因為CE的同一個DLL在不同的Process中需要在相同的Virtual Address (why?)。
所以在load DLL的時候,必須考慮到避開其他process 的 DLL 已經使用的位址。
一個process只有32M已經很慘了,DLL還要考慮自己不用的DLL要避開!!
Process Load A, B DLL -- Memory = A.B
Process Load A, C DLL -- Memory = A.(B).C
Process Load A, D DLL -- Memory = A.(B).(C).D
其中( )的部份在該process看來是空下來的部份


CE 5.0 是不是也是一樣?

7.20.2009

PostThreadMessage

雖然在Message Overview 里都只有說明有Windows 才有的Message/Queue 相關操作,但是從 PostThreadMessage ( ) 這個 function 來看,沒有Windows 的 Thread,也有 Message Queue。

但是有一些限制,Thread的 Message Queue不是在Thread 產生就Create好的,只有在Thread 有 call 過 Message 相關 funciton 後,才會產生。

同時,在Thread 的 Message Queue未產生之前,PostThreadMessage( )給他的話,Message會被丟掉 (同時 return FALSE)。

MSDN 提供兩個方法來避免這個問題:
  1. PostThreadMessage的人check return value,fail 的話就Sleep( )一段時間,等 對方把 MessageQueue 開出來
  2. 利用同步機制(Event) 來同步雙方的動作。 收Message的Thread 啟動時就call一次 PeekMessage( )同時指定不拿出message,
    PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE)
    經過這次呼叫,Thread 的 MessageQueue 就會被 Create,然後用 SetEvent( )通知要PostThreadMessage給他的Thread。範例。
收Message的Thread 有三種收Message的Argument
  1. 收 Post 給 該 Thread 的 Window 的 Message
  2. 收 Post 給 該 Thread 的 Message
  3. 都收
1. 的話,要是有Windows 的Thread 才有效。

7.15.2009

interrupt handling in CE

CE 的 hardware interrupt 由 ISR ,kernel,IST 三者合作。

每個hardware的中斷都會被指定一個ISR來處理 (ISR可以共用)

當中斷發生時,會kernel會呼叫ISR,ISR執行完後,會return一個值。
kernel 由這個值檢查有哪些event 和他相關,set 這些 event。

IST 內會有wait event 的code,這樣就會被通知到。

新支援的 Installtable ISR (IISR)。
可以達成 chain-interrupt 的行為:
kernel 依照該hardware IRQ 註冊的 ISR,一個一個 call,每個 ISR要確認是不是自己要處
理。
如果不是,就return SYS_CHAIN,kernel 就會call下一個 ISR。
如果是,就retrurn 其他的職,kernel 就不會call下一個 ISR。

IISR Sample Code 在 \Public\Common\Oak\Drivers\GIISR

* 有關IRQ disable,enable 的時機,在書中有一張圖說得很清楚。
基本上,就是..一但發生,所有interrupt都disable,ISR處理時,就把其他interrupt打開,自己的還是關。一直到 IST call InterruptDone( ) 該 IRQ 才會再被打開。