5164|2

248

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

Zstack中如何实现自己的任务 [复制链接]

在Zstack(TI的Zigbee协议栈)中,对于每个用户自己新建立的任务通常需要两个相关的处理函数,包括:
      (1).用于初始化的函数,如:SampleApp_Init(), 这个函数是在osalInitTasks()这个osal(Zstack中自带的小操作系统)中去调用的,其目的就是把一些用户自己写的任务中的一些变量,网络模式,网络终端类型等进行初始化;
      (2).用于引起该任务状态变化的事件发生后所需要执行的事件处理函数,如:
SampleApp_ProcessEvent(),这个函数是首先在const pTaskEventHandlerFn tasksArr[ ] 中进行设置(绑定),然后在osalInitTasks()中如果发生事件进行调用绑定的事件处理函数.
     下面分3个部分分析.
1.用户自己设计的任务代码在Zstack中的调用过程
(1).main() 执行(在ZMain.c中)
main() ---> osal_init_system()
(2). osal_init_system()调用osalInitTasks(), (在OSAL.c中)
osal_init_system() ---> osalInitTasks()
(3). osalInitTasks()调用SampleApp_Init() , (在OSAL_SampleApp.c中)
osalInitTasks() ---> SampleApp_Init()
在osalInitTasks()中实现了多个任务初始化的设置,其中macTaskInit( taskID++ )到ZDApp_Init( taskID++ )的几行代码表示对于几个系统运行初始化任务的调用,而用户自己实现的SampleApp_Init()在最后,这里taskID随着任务的增加也随之递增.所以用户自己实现的任务的初始化操作应该在osalInitTasks()中增加.
void osalInitTasks( void )
{
uint8 taskID = 0;
//这里很重要, 调用osal_mem_alloc()为当前OSAL中的各任务分配存储空间(实际上是一个任//务数组),并用tasksEvents指向该任务数组(任务队列).
tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);
osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt));  //将taskSEvents所指向的空间清零
macTaskInit( taskID++ );
nwk_init( taskID++ );
Hal_Init( taskID++ );
#if defined( MT_TASK )
MT_TaskInit( taskID++ );
#endif
APS_Init( taskID++ );
ZDApp_Init( taskID++ );
SampleApp_Init( taskID );  //用户自己需要添加的任务
}
2.任务处理调用的重要数据结构
这里要解释一下,在Zstack里,对于同一个任务可能有多种事件发生,那么需要执行不同的事件处理,为了方便,对于每个任务的事件处理函数都统一在一个事件处理函数中实现,然后根据任务的ID号(task_id)和该任务的具体事件(events)调用某个任务的事件处理函数,进入了该任务的事件处理函数之后,再根据events再来判别是该任务的哪一种事件发生,进而执行相应的事件处理.pTaskEventHandlerFn 是一个指向函数(事件处理函数)的指针,这里实现的每一个数组元素各对应于一个任务的事件处理函数,比如SampleApp_ProcessEvent对于用户自行实现的事件处理函数uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events ),所以这里如果我们实现了一个任务,还需要把实现的该任务的事件处理函数在这里添加.
const pTaskEventHandlerFn tasksArr[] = {
macEventLoop,
nwk_event_loop,
Hal_ProcessEvent,
#if defined( MT_TASK )    //一个MT任务命令
MT_ProcessEvent,
#endif
APS_event_loop,
ZDApp_event_loop,
SampleApp_ProcessEvent
};
    注意, tasksEvents和tasksArr[]里的顺序是一一对应的, tasksArr[]中的第i个事件处理函数对应于tasksEvents中的第i个任务的事件.
//计算出任务的数量
const uint8 tasksCnt = sizeof( tasksArr ) / sizeof( tasksArr[0] );
uint16 *tasksEvents;
3. 对于不同事件发生后的任务处理函数的调用
osal_start_system() 很重要,决定了当某个任务的事件发生后调用对应的事件处理函数
void osal_start_system(void)
{
#if !defined ( ZBIT )
for(;;) // Forever Loop
#endif
{
     uint8 idx = 0;
     Hal_ProcessPoll(); // This replaces MT_SerialPoll() and osal_check_timer().
//这里是轮训任务队列,并检查是否有某个任务的事件发生
     do {
       if (tasksEvents[idx]) // Task is highest priority that is ready.
       {
         break;
       }
     } while (++idx < tasksCnt);
     if (idx < tasksCnt)
     {
       uint16 events;
       halIntState_t intState;
       HAL_ENTER_CRITICAL_SECTION(intState);
       events = tasksEvents[idx];   //处理该idx的任务事件, 是第idx个任务的事件发生了
       tasksEvents[idx] = 0; // Clear the Events for this task.
       HAL_EXIT_CRITICAL_SECTION(intState);
       //对应调用第idx个任务的事件处理函数,用events说明是什么事件
       events = (tasksArr[idx])( idx, events );

       //当没有处理完,把返回的events继续放到tasksEvents[idx]当中
       HAL_ENTER_CRITICAL_SECTION(intState);
     tasksEvents[idx] |= events; // Add back unprocessed events to the current task.
       HAL_EXIT_CRITICAL_SECTION(intState);
       }
#if defined( POWER_SAVING )
     else // Complete pass through all task events with no activity?
     {
       osal_pwrmgr_powerconserve(); // Put the processor/system into sleep
     }
#endif
     }
}
此帖出自无线连接论坛

最新回复

感觉还没说完,楼主能不能写个教程?  详情 回复 发表于 2013-1-10 09:45
点赞 关注
 

回复
举报

134

帖子

0

TA的资源

一粒金砂(中级)

沙发
 
学习中!希望能有更多的资料分享
此帖出自无线连接论坛
 
 

回复

39

帖子

2

TA的资源

一粒金砂(中级)

板凳
 
感觉还没说完,楼主能不能写个教程?
此帖出自无线连接论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
快速回复 返回顶部 返回列表