1. 程式人生 > >Z-Stack 作業系統抽像層應用程式程式設計介面

Z-Stack 作業系統抽像層應用程式程式設計介面

【轉】http://bbs.eeworld.com.cn/thread-375521-1-1.html
1.介紹
1.1目的
本檔案的目的是詳細說明作業系統抽象層(OSAL)API 。該API允許Z-stack寫自己內部的軟體元件而與具體的作業系統、核心、或者任務環境無關(包括控制迴圈或連線到中斷系統)。該OSAL在目標上應用。
1.2適用範圍
這份檔案列舉了由OSAL提供的所有的函式呼叫 。這些函式呼叫說明的十分詳細,以便允許程式設計師去執行它。
1.3縮略語
API      應用程式程式設計介面
OSAL     作業系統( OS )抽象層
PC       個人計算機
SPI      序列介面


2.1概況
作業系統抽象層是用來從具體的處理環境中遮蔽Z-Stack軟體元件。它以獨立於處理環境的方式提供下列功能。
1.任務註冊,初始化,啟動
2.任務間的訊息交換
3.任務同步
4.中斷處理
5.定時器管理
6.記憶體分配


3.訊息管理API
3.1介紹
訊息管理API提供了一種任務間訊息交換機制或處理單元用不同的處理環境(例如,中斷服務程式或一個迴圈控制內函式呼叫)。用這個API的函式使一個任務能夠分配和釋放訊息緩衝,給另一個任務傳送命令訊息和接收到回覆的訊息。
3.2 osal_msg_allocate()
3.2.1描述
一個任務呼叫這個函式來分配一個訊息緩衝區,任務/函式將向這個緩衝區填充訊息並呼叫osal_msg_send()將訊息傳送給另一個任務。如果緩衝區不能分配,msg_ptr將被設定為NULL(即返回值為NULL)。
注意:這個函式不要與osal_mem_alloc()混淆了,這個函式是用來分配一個緩衝區給任務之間傳送訊息[使用osal_msg_send()]。使用osal_mem_allocz()用來分配記憶體塊。
3.2.2函式原型
byte* osal_msg_allocate(uint16 len)
3.2.3引數說明
len是訊息的長度。
3.2.4返回值
返回值指向為訊息分配的緩衝區。返回NULL指示訊息分配操作失敗。

3.3 osal_msg_deallocate()
3.3.1描述
這個函式用來釋放一個訊息緩衝區。一個任務(或處理程式)處理完一個接收訊息後呼叫此函式。
3.3.2函式原型
byte osal_msg_deallocate (byte* msg_ptr )
3.3.3引數說明
msg_ptr指向一個需要釋放的訊息緩衝區
3.3.4返回值
返回值指示操作的結果
表.略

3.4 osal_msg_send()
3.4.1描述
一個任務呼叫osal_msg_send函式去傳送一個命令或者資料訊息給另一個任務或者處理程式。 destination_task識別符號欄位必須指向一個有效的系統任務。當osal_create_task ( )(注:好像1.4.3的OSAL好像不再使用這個函數了)呼叫來啟動一個任務時,任務識別符號被分配。該osal_msg_send ( )函式也將設定SYS_EVENT_MSG事件在目標任務事件清單裡。
3.4.2函式原型
byte osal_msg_send(byte destination_task,byte *msg_ptr)
3.4.3引數說明
destination_task是接收訊息任務的ID。
msg_ptr是一個指向包含訊息的緩衝區。 Msg_ptr必須指向通過osal_msg_allocate()分配的一個有效訊息緩衝區 。
3.4.4返回值
返回值是一個1位元組的欄位指示操作的結果。
表.略

3.5 osal_msg_receive()
3.5.1描述
一個任務要取用接收到的命令訊息時則呼叫這個函式。呼叫任務在處理完這個訊息後必須呼叫osal_msg_deallocate()釋放這個訊息的緩衝區.
3.5.2函式原型
byte* osal_msg_receive (byte task_id )
3.5.3引數說明
task_id是正呼叫任務的識別符號(指示這個訊息將執行哪裡)
3.5.4返回
返回值是一個指向包含訊息緩衝的指標。或者如果沒有接收到的訊息時則返回NULL.

4 任務同步API
4.2.1描述
允許任務等待事件發生並在等待時返回控制資訊,在這個API中的函式可以用來為一個任務設定事件和一旦任何一個事件被設定通知這個任務(意思說,為你準備的事件發生了,你這個任務該要處理它了)。
4.2 osal_set_event()
4.2.1描述
這個函式用來為一個任務設定事件標誌。
4.2.2函式原型
byte osal_set_event(byte task_id, UINT16 event_flag)
4.2.3引數詳細
task_id是需要事件設定而觸發的任務識別符號。
event_flag是一個兩位元組的位欄位,每一個位指定為一個事件。只有一個系統事件(SYS_EVENT_MSG),其餘的事件/位段由接收任務指定;
4.2.4返回
返回值指示操作的結果。
表.略

5.定時器管理API
5.1介紹
API(指OSAL所提供的API)能夠通過內部任務(Z-stack),也可以通過外部任務(應用級)來使用定時器。
該API提供了啟動和停止定時器的函式。定時器能夠設定成以1ms遞增。
5.2 osal_start_timer()
5.2.1描述(也就是說呼叫這個函式的任務將掛起直到溢位為止,目前好像沒有使用這個函數了)
這個函式用來啟動一個定時器。當定時器溢位,給定的事件位將被設定。
呼叫osal_start_timer函式的任務將設定這個事件。
要具體地指定任務的id,要使用函式osal_start_timerEx()來代替osal_start_timer().。
5.2.2函式原型
byte osal_start_timer(UINT16 event_id, UINT16 timeout_value);
5.2.3引數說明
event_id:是一個使用者定義的事件位。當計數器溢位,呼叫任務(指呼叫osal_start_timer函式的任務)將被通知(事件)。
timeout_value:溢位時間(以毫秒為單位)
5.2.4返回值
返回值指示操作的結果。
表.略

5.3 osal_start_timerEx()時間到了是為taskID設定event,還是由taskID來設定
5.3.1描述
這個函式與osal_start_timer()非常相似,增加了taskID引數。這允許呼叫者為另一個任務設定定時器。當不能肯定時,使用上面介紹的osal_start_timer()函式。
5.3.2 函式原型
byte osal_start_timerEx( byte taskID, UINT16 event_id, UINT16 timeout_value);
5.3.3引數說明
taskID指當定時器溢位時,為task ID的任務將開始作業。
event_id是一個使用者定義的事件位。當計數器溢位,呼叫任務將被通告(事件)。
timeout_value溢位時間(以毫秒為單位)
5.3.4返回
返回值指示操作的結果。
表.略

5.4 osal_stop_timer()(好像沒有使用了)
5.4.1描述
這個函式被呼叫來停止一個已經開始的計數器。如果成功,函式將取消定時並阻止與呼叫任務設定的定時相關聯的事件。使用osal_stop_timer()函式意味著定時器正在執行,這種情況下任務才呼叫osal_stop_timer().要在不同的任務中停止定時器,使用osal_stop_timerEx()替代osal_stop_timer()。
5.4.2函式原型
byte osal_stop_timer( UINT16 event_id );
5.4.3引數說明
event_id是定時器將要停止的識別符號號.
5.4.4返回
返回值指示操作的結果。
表.略

5.5 osal_stop_timerEx()
5.5.1描述
這個函式與osal_stop_timer()相似,例外的是在呼叫osal_stop_timerEx可以指定task_id.
5.5.2函式原型
byte osal_stop_timerEx( byte task_id, UINT16 event_id );
5.5.3引數說明
task_id是對應要為其停止定時器的任務
event_id是定時器將要停止的識別符號.
5.5.4返回
返回值指示操作的結果

5.6 osal_GetSystemClock()
5.6.1描述
這個函式用來讀取系統的時鐘.
5.6.2函式原型
uint32 osal_GetSystemClock( void );
5.6.3引數說明

5.6.4返回值
系統時鐘的單位用毫秒錶示.


6中斷管理API
6.1介紹
這個API使任務能夠與外部中斷進行介面。
用這些API中的函式允許一個任務與具體的每一箇中斷服務程式相關聯.中斷可以使能或者禁用。在服務程式裡,可以為其它的任務設定事件.

6.2 osal_int_enable()
6.2.1描述
這個函式用來使能一箇中斷。一旦使能,中斷的發生將導致呼叫與中斷相關聯的服務程式。
6.2.2函式原型
byte osal_int_enable( byte interrupt_id )(其實這裡實現的是:EA=1;)
6.2.3引數說明
interrupt_id確定使能中斷。
6.2.4返回
返回值指示操作的結果
表.略

6.3 osal_int_disable()
6.3.1說明
這個函式用來禁用一箇中斷.當一個禁止的中斷產生了中斷,與這個中斷相關聯的服務程式將不會呼叫。
6.3.2函式原型
byte osal_int_disable( byte interrupt_id )
6.3.3引數說明
interrupt_id確定要禁止的中斷.
6.3.4返回
返回值指示操作的結果



7.任務管理API
7.1介紹
在OSAL系統中使用這些API來新增和管理任務。
每一個任務由一個初始化函式和一個事件處理函式組成。
OSAL呼叫osalInitTasks()[應用程式提供,也就是說,這個函式由使用者自己來寫]來初始化任務(tasks)和OSAL利用一個任務表(const pTaskEventHandlerFn tasksArr[])來為每一個任務去呼叫事件處理程式。
例如一個任務表的實現:
const pTaskEventHandlerFn tasksArr[] =
{
    macEventLoop,
    nwk_event_loop,
    Hal_ProcessEvent,
    MT_ProcessEvent,
    APS_event_loop,
    ZDApp_event_loop,
};
const uint8 tasksCnt = sizeof( tasksArr ) / sizeof( tasksArr[0] );


例如一個osalInitTasks()的實現:
void osalInitTasks( void )
{
   uint8 taskID = 0;
   tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);
   osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt));
   macTaskInit( taskID++ );
   nwk_init( taskID++ );
   Hal_Init( taskID++ );
   MT_TaskInit( taskID++ );
   APS_Init( taskID++ );
   ZDApp_Init( taskID++ );
}

7.2 osal_init_system()
7.2.1描述
這個函式初始化OSAL系統。
在使用其它OSAL函式之前必須先呼叫這個函式來啟動。
7.2.2函式原型
byte osal_init_system( void )
7.2.引數說明

7.2.4 返回
返回值指示操作的結果。

7.3 osal_start_system()
7.3.1描述
這個函式是任務系統的主迴圈函式。它將監視所有任務事件並負責為任務的事件呼叫任務事件處理函式。如果有特定任務的事件,函式將呼叫那個任務的事件處理程式來處理這個事件。相應任務的事件處理程式每次處理一個事件。在一個事件被處理後,剩餘的事件將被返回到主迴圈中等待下一輪。如果沒有事件發生(所有的任務),這個函式迫使處理器進入睡眠模式。
7.3.2函式原型
void osal_start_system( void )
7.3.3引數說明

7.3.4返回


7.4 osal_self()
7.4.1描述
此函式已經棄用並不再支援。

7.5 osalTaskAdd()
7.5.1描述
此函式已經棄用並不再支援。有關OSAL任務初始化和事件處理參考7.1。


8 .記憶體管理API
8.1介紹
這些API描述了一個簡單的記憶體分配系統。這些函式允許動態記憶體分配。
8.2 osal_mem_alloc()
8.2.1描述
這個函式是返回一個指向緩衝區的指標(如果分配成功)的簡單的記憶體分配函式。
8.2.2函式原型
void *osal_mem_alloc( uint16 size );
8.2.3引數說明
size---想從緩衝區獲得的位元組數
8.2.4返回值
一個void指標(這個指標應該轉換成打算的緩衝型別,也就說指標型別轉換)指向新分配緩衝區,如果失敗則返回指向NULL的指標。如果沒有足夠的記憶體來分配就返回一個NULL指標。

8.3 osal_mem_free()
8.3.1描述
這個函式釋放分配的記憶體以便再次被使用。如果記憶體已經由osal_mem_alloc()分配,才使用這個函式。
8.3.2函式原型
void osal_mem_free( void *ptr );
8.3.3引數說明
ptr-- 指向釋放的緩衝區。這個快取區必須在之前已經由osal_mem_alloc()分配
8.3.4返回值



9電源管理API
9.1介紹
本節描述OSAL的電源管理系統。
系統為applicatios/tasks 提供了一個方法用來通知OSAL什麼時候可以安全關閉接收器或外部裝置並使處理器進入休眠。
有2個函式來控制電源管理。
首先,osal_pwrmgr_device() 用來設定裝置的標準模式(省電或者不用省電)。然後有任務的電源狀態,每一個任務可以呼叫osal_pwrmgr_task_state( PWRMGR_HOLD )來從節約電源延緩電源管理。
如果有一個任務“HOLD”了電源管理,就需要呼叫osal_pwrmgr_task_state( PWRMGR_CONSERVE )允許電源管理繼續在節約電源模式。
預設情況下,當任務初始化時,每個任務的電源狀態被設定為PWRMGR_CONSERVE,如果任務不想暫緩節約電源(不改變),他不需要呼叫 osal_pwrmgr_task_state().
   電源管理將在進入電源保護狀態之前察看裝置模式和收集所有任務的電源狀態。


9.2 osal_pwrmgr_device()
9.2.1描述
This function is called on power- up or whenever the power requirements change (ex. Battery backed coordinator).
在上電時呼叫這個函式或者任何時候電源要求改變(例如.電池支援的協調器Battery backed coordinator)。
這個函式設定整個裝置電源管理的ON/OFF狀態。該函式應當從中央控制實體(如ZDO)被呼叫。
9.2.2函式原型
void osal_pwrmgr_state( byte pwrmgr_device );
9.2.3引數詳細
Pwrmgr_device --更改或設定節電模式
    引數型別                  描述
PWRMGR_ALWAYS_ON          用這個引數選擇不用省電,這種方式最有可能在主供電                             裝置

PWRMGR_BATTERY            省電模式
9.2.4返回值


9.3 osal_pwrmgr_task_state()
9.3.1描述
每一個任務呼叫這個函式來表態這個任務是否想節約電源(conserve power)。
任務將呼叫這個函式提議是否讓OSAL執行節約電源或者希望暫緩省電。
預設情況下,當一個任務建立後,它自己的電源狀態設定為節約電源(conserve)。
如果任務總是想節約電源,他就完全不用呼叫這個函數了。(因預設已經為節約電源模式,所有如果總是想節約電源,則不必再呼叫這個函數了)。
9.3.2函式原型
byte osal_pwrmgr_task_state( byte task_id, byte state );
9.3.3引數說明
state--改變一個任務的電源狀態
    型別                描述
  PWRMGR_CONSERVE     開啟省電模式,所有任務必須同意.當一個任務初始化時,這是預設狀態。

  PWRMGR_HOLD         關掉省電模式

9.3.4返回值
返回值表示操作的結果
表.略


10.非易失性記憶體API
10.1介紹
本節描述OSAL的非易失性記憶體(NV)系統。系統為應用程式提供了一種儲存資訊到裝置的永久性記憶體裡的方法。stack使用它作為永久性儲存ZigBee規格書要求的某些專案(Item)。NV函式設計用來讀和寫使用者定義的任意資料型別組成的專案,如結構或陣列。 使用者可以讀或寫整個專案或者通過設定適當的偏移量和長度來讀寫可以專案中的一個元素。這些API獨立於NV的儲存介質,並可以為快閃記憶體或EEPROM來應用。
每個NV專案具有一個唯一ID。應用程式有一個具體的ID值範圍而有些ID的值保留或者被stack或者應用平臺使用。如果你的應用程式建立了一個自己的NV專案,它必須在應用程式取值範圍內選擇一個ID。見下面的表格:

  值               使用者

0x0000              保留

0x0001-0x0020       OSAL

0x0021-0x0040       NWK

0x0041-0x0060       APS

0x0061-0x0080       安全

0x0081-0x00A0       ZDO

0x00A1-0x0200       保留

0x0201-0x0FFF       應用

0x1000-0xFFFF       保留

在使用這些API時有一些重要的考慮因素:
1:這些操作將阻塞函式的呼叫並且一個操作也許需要若干毫秒才能完成。
這一點尤其適用於對NV的寫操作(也就是說寫操作佔用時間長)。另外,中斷可能會禁止若干毫秒。執行這些函式最好的時間是他們和時序要求嚴格的的操作不發生衝突。
例如,當接收器被關掉時,寫NV專案是很好的時間段。
2:儘量減少執行NV寫操作。它將用掉時間和功耗,當然很多快閃記憶體裝置有一個有限的擦除週期的次數。
3:如果一個數據結構裡的一個或多個NV專案要改變,特別是當從一個z-stack升級到另一個z-stack版本,它是必需擦除和重新初始化NV記憶體。否則,在NV專案上的讀和寫操作的改變將失敗或產生錯誤的結果。

10.2 osal_nv_item_init()
10.2.1說明
在NV裡初始化一個專案。這個函式檢查在NV裡是否存在一個專案。如果不存在,它將被建立和用傳給這個函式的資料進行初始化,若有的話(if any).
這個函式必須在呼叫osal_nv_read() or osal_nv_write()之前被呼叫。
10.2.2函式原型
byte osal_nv_item_init( uint16 id, uint16 len, void *buf );
10.2.3引數說明
id-使用者自定義的專案ID。
len-以位元組為單位的專案長度
*buf-指向專案初始化的資料.如果沒有初始化的資料.設定為NULL。
10.2.4返回值
返回值指示操作的結果。
表.略

10.3 osal_nv_read()
10.3.1描述
從NV中讀取資料。這個函式可以從NV中讀取整個專案或者通過索引進入專案的偏移量來得到一個專案中的一個元素。讀取資料複製到*buf中。
10.3.2函式原型
byte osal_nv_read( uint16 id, uint16 offset, uint16 len, void *buf );
10.3.3引數說明
id--使用者定義的專案編號。
offset--以位元組為單位的在專案內的記憶體偏移量。
len--以位元組為單位的專案長度
*buf-資料讀入這個緩衝區
10.3.4返回值
返回值表示操作的結果

10.4 osal_nv_write()
10.4.1說明
資料寫入NV.這個函式可以用來把整個專案寫入NV中或者通過索引進入專案的偏移量來寫入一個專案中的一個元素。
10.4.2函式原型
byte osal_nv_write( uint16 id, uint16 offset, uint16 len, void *buf );
10.3.3引數說明
id--使用者自定義的專案ID。
offset---以位元組為單位的在專案內的記憶體偏移量。
len--以位元組為單位的專案長度
*buf--這裡所指向的資料是呆寫入的資料
10.3.4返回值
返回值指示操作的結果


10.5 osal_offsetof()
10.5.1描述
這個巨集計算出一個元素在資料結構內的記憶體偏移量。NV API函式使用這個函式來計算偏移量引數是很有用。(就像上面提到的對專案內的單個引數進行讀和寫)。
10.5.2函式原型
osal_offsetof(type, member)
10.3.10引數說明
type –結構型別
member-結構成員