Wednesday, February 03, 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 files ,以下是個 res.lst 的例子:

:0x00       # start offset (default is 0x00)

:kind=A     # kind A for the enumeration
bat.png     # file size: 2877 bytes

:kind=B     # kind B for the enumeration
:4096       # offset to address: 4096
broom.png   # file size: 3083 bytes
candle.png  # file size: 2771 bytes
  • 這個文字檔列出了 bat.png, broom.png, candle.png 等三張圖檔檔名,當作 resource
  • # 一直到行尾代表註解。
  • : 接數字代表接下來的檔案要放的位置,單位為 bytes
  • :kind=name 用來對產生的 enumerator 作分類。
    • 除了用來區分 resource 的 type 外,我還常利用這個機制來處理多國語言。

把這個 res.lst ,餵給 ResourceLink 後,可以產生 ResID.h, ResMap.i, 跟 res.bin 。

res.bin 就是這些 resource 檔案(三張圖檔)連結成的單一檔案。

ResID.h 為每一個 resource 都指定一個 enumerator ID:

// Generated by the Resource Link v1.14
//    !author: Jiang Yu-Kuan 
//    !trail: reslnk.py id -oResID.h res.lst
#ifndef _RES_ID_H
#define _RES_ID_H


/** IDs of Resources */
typedef enum {
    RES_A_BEGIN,
    RES_PNG_bat = RES_A_BEGIN,
    RES_A_END,

    RES_B_BEGIN = RES_A_END,
    RES_PNG_broom = RES_B_BEGIN,
    RES_PNG_candle,
    RES_B_END,

    RES_End = RES_B_END,
    RES_Total = RES_End
} ResID;


#endif // _RES_ID_H

ResMap.i 是用來描述每個資源檔的偏移植跟大小的:

// Generated by the Resource Link v1.14
//    !author: Jiang Yu-Kuan 
//    !trail: reslnk.py map -dres -oResMap.i -a4 res.lst

//   offset,       size     (in bytes)
{         0,       2877},   // RES_PNG_bat (bat.png)
{      4096,       3083},   // RES_PNG_broom (broom.png)
{      7180,       2771},   // RES_PNG_candle (candle.png)

0 comments: