ZigBee文章 OSAL API的翻译
Z-Stack 操作系统抽像层应用程序编程接口
文档编号:F8W-2003-0002 Version 1.5
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-结构成员