Chinaunix首页 | 论坛 | 博客
  • 博客访问: 40789
  • 博文数量: 18
  • 博客积分: 1400
  • 博客等级: 上尉
  • 技术积分: 200
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-05 10:27
文章分类
文章存档

2011年(1)

2009年(1)

2008年(16)

我的朋友

分类:

2008-10-31 09:54:40

 

 

 

 

 

 

 

 

 

 

 

 

 

 

V2 源代碼剖析

 

 


一.基礎認識

       SMedia IC中內置了一顆32 bitsRISC,在源代碼一切行為判斷也都是驅駛這顆心臟來完成的,在這個RISC之上我們採了作業系統是FreeRTOS,這是個免費的作業系統,相信可以很方便的找到相關訊息。關於FreeRTOS的源代碼,我們可以在文件夾”\freertos”中看到,不過基本上不會特地去動這部份。

       在開始看UI部份的代碼前,有幾件事情要先了解:我們採用的FreeRTOS是個多序(Multi-Thread)的作業系統,所以我們在設計軟件時充份利用了這個優點,在整個軟件中我們大略分為幾個thread,整個UI是一個ThreadAudio解碼部份為一個ThreadVideo解碼一個及JPEG編解碼一個。也語於UI介面為單獨的一個Thread,所以有一點一定要注意不要使用”while”迴圈放在其中,避免造成無窮迴圈而造成系統死機的情況。而存取memory的方式是使用malloc/free的方式。至於一些UI上的反應行為,我們主要是事件式(Event)的方式來處理,從dpf/main.cMainLoop中,可以看出目前主要接收兩種事件,按鍵(Key)及定時(Timer)。下面做個總結,我們的系統有幾點特性:

Ø  Proprietary Multi-Thread OS

Ø  Multi-Thread Application

Ø  DO NOT contains internal while-loop in code

Ø  Event driving programming style (windows like)

Ø  Malloc/Free method for memory allocation

 

整個UI的源代碼起點,是從”\dpf\main.c”中的main(void)開始,做完了初始化的動作後,就進入了MainLoop中,在這個MainLoop,他會去接收兩類的Event,也就是上述所說的keytimer,而收到這兩種Event,會將訊息傳遞到當時的狀態(State),再由每個state根據情況來實現其工作。

除了state之外,我們還把除了介面樣板的其他功能切出來,我們把這些切出來的部份叫做method

 

 

二.State

       所謂的State,其實就是看到的每一種UI樣板,目前在V2中我們已經先定義好一些state,可以state.h文件中的SMTK_STATE_ID看到列表,每一個state的實體源代碼,我們可以在文件名以state_開頭的文件中找到。另外,在menu state中,還會再往下傳遞sub state,這些sub sata是以menu_開頭的文件中可以找到。

每一個state它必須處理好三件事:

(1) Initialize  (2) Proc  (3) Terminate

所以我們在每個相對state的文件中,都可以找得到上述三個名字的函式。

Initialize,當我們在畫面上看到華麗的效果及質感精緻的UI時,通常須要特別的照片圖示來建構,所以在Initialize中,我們會把所需要的這些元件準備好,也就是將相對應的資源取出來放在Memory中,準備之後的應用。如每一個介面上的小圖,先從jpeg文件解壓出來之類的準備動作。

Proc,上述有提過,當接收到keytimer的事件時,會傳遞到每一個狀況中處理,處理這些事件的就是在Proc中,畫面上的一些動作就是在每一個進來的timer中一格一格畫出來的。以下是兩個eventID SMTK_MSG_ID_TIMERSMTK_MSG_ID_KEY_DOWN

Terminate,也就是把每一個state關閉掉時需要做的事,我們就是把memory或是surfacerelease掉,這裡有一個原則,在initialize中越先malloc或是creatememory或是surface,要越晚free。這樣可以避免掉memory fragment的問題。

 

l  如何建立自己的state

有關於state的一切動作,也就是event的傳遞、決定state的主體,都是靠著state.cstate.h來運作,所以當我們要新增一個state也是要對這兩個文件下手。

首先看到state.h中的

typedef enum SMTK_STATE_ID_TAG

{

    SMTK_STATE_SPLASH,

    SMTK_STATE_MAINTOP,

    SMTK_STATE_THUMBNAIL,

    SMTK_STATE_BROWSE,

    SMTK_STATE_SLIDE_SHOW,

    SMTK_STATE_VIDEO,

    SMTK_STATE_AUDIO,

    SMTK_STATE_SYSTEMSETTING,

    SMTK_STATE_MENU,

    SMTK_STATE_CARD,

      SMTK_STATE_CLIENT,

    SMTK_STATE_POWER_OFF,

    SMTK_STATE_BURN_FLASH,

    SMTK_STATE_ALARM,

    SMTK_STATE_CALENDAR,

#ifdef SMTK_COIN_STATE_ENABLE

    SMTK_STATE_COIN,

#endif

} SMTK_STATE_ID;

       以上述的SMTK_STATE_ALARM為例,在這個列表中加入你要先增的state,然後建立自己的state的文件,這裡是state_alarm.c先建立

SMTK_STATE smtkAlarmState =

{

    Initialize,

    Terminate,

    Proc

};

還有上述所說的三個state基本function

static MMP_INT Initialize(void)

static MMP_INT Proc(MMP_UINT id, MMP_ULONG arg1, MMP_ULONG   arg2)

static MMP_INT Terminate(void)

接下來在state.h中,先取得smtkAlarmState,所以要加上:

extern SMTK_STATE smtkAlarmState;

另外在以下的列表中,將function pointer指定進來

static SMTK_STATE* stateEntries[] =

{

    &smtkSplashState,

    &smtkMainTopState,

    &smtkThumbnailState,

    &smtkBrowseState,

    &smtkSlideShowState,

    &smtkVideoState,

    &smtkAudioState,

    &smtkSystemSettingState,

    &smtkMenuState,

    &smtkCardState,

    &smtkClientState,

    &smtkPowerOffState,

    &smtkBurnFlashState,

    &smtkAlarmState,

    &smtkCalendarState,

#ifdef SMTK_COIN_STATE_ENABLE

    &smtkCoinState,

#endif};

三.畫面建構的概念

       在整個UI做初始化的時候,我們就會先去alloc兩塊空間,這兩塊空間都是為了給屏顯示用的,一塊是當前畫面,另一塊則是在讓下一個畫面先填入所有的元素,然後在適當的時間來轉換這兩個memory,讓下一個畫面顯示在屏上面。為什麼要這樣來做呢?若只有一個空間的時候,我們每貼上一個元件在畫面上就會出現一個,在視覺上就會看到每一個不同圖片貼上去的過程,所以我們會先在背後先貼完,然後直接切換LCD屏顯示memory的位置,這樣就可以避免這樣的情況發生。在gui.c中的smtkGuiMgrInitialize,可以看到我們create兩個surface(使用mmpM2dGetScreenSurface)dispSurfAdispSurfB,這個空間的大小會根據屏的長寬來定。用來切換這兩塊空間的function是:

                     MMP_INT smtkGuiMgrFlip(void)

而使用以下function先得到背面的surface

                     MMP_SURFACE smtkGuiMgrGetDisplaySurface(void)

       State_splash.c中的function DrawSplash為例,一開始的時候就可以看到去做smtkGuiMgrGetDisplaySurface,然後做完要做的相對應貼圖之後,在整個function的後半段,呼叫smtkGuiMgrFlip來切換顯示buffer,畫面就可以看到剛才畫完的結果了。

 

阅读(603) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~