Zstack中如何实现自己的任务(3)

2019-06-17 10:39

zmain_dev_info(); #ifdef LCD_SUPPORTED zmain_lcd_init(); #endif

#ifdef WDT_IN_PM1

WatchDogEnable( WDTIMX ); #endif

osal_start_system(); return 0; }

主函数要做的事情非常简单,首先进行了一些初始化,包括各层的初始化,硬件初始化,以及任务的初始化等,然后就进入到操作系统当中,即

osal_start_system(); 就再也出不来了。操作系统的作用就是如果有事件发生,就把这个消息通知给处理该事件的事件处理函数去执行,然后一直的循环查找有没有事件发生。另外说一下,事件是定义在任务当中的,即一个任务可能有多个事件,每个任务对应一个事件处理函数。在这个程序中,一共有6个任务,有兴趣的同学可以自己查看void osalInitTasks( void )函数的代码。 接下来看一下zigbee协调器是怎么建立网络的

首先我们必须选择SimpleCollectorEB版本,在APP文件下看到sapi.c源文件。找到SAPI_Init(byte task_id)函数,此函数是进行sapi层的初始化,代码如下

void SAPI_Init( byte task_id ) {

sapi_TaskID = task_id;//将操作系统初始化任务时定义的任务id号传进来 sapi_bindInProgress = 0xffff;//设置不允许绑定

sapi_epDesc.task_id = &sapi_TaskID;//给端口描述符的任务ID号赋值,感觉也就是端口收到的数据或者消息就交给ID号指定的任务来处理。 sapi_epDesc.endPoint = 0;//端口描述符端口号初始化为0。

#if ( SAPI_CB_FUNC )//编译通过

sapi_epDesc.endPoint = zb_SimpleDesc.EndPoint;//端口号赋值

sapi_epDesc.task_id = &sapi_TaskID;//任务ID赋值,与上面的任务ID的值是相同的。

sapi_epDesc.simpleDesc = (SimpleDescriptionFormat_t

*)&zb_SimpleDesc;//简单描述符赋值,是描述一个端口最基本的信息

sapi_epDesc.latencyReq = noLatencyReqs;//这是一个枚举类型的,不清楚具体含义,不过大家都设成noLatencyReqs,除此之外还有两个值。

afRegister( &sapi_epDesc );//将定义的端点在AF层注册,一定要注册后端点才会生效 #endif

afSetMatch(sapi_epDesc.simpleDesc->EndPoint, FALSE);//设置描述符不能匹配

// Register callback evetns from the ZDApp

ZDO_RegisterForZDOMsg( sapi_TaskID, NWK_addr_rsp );//在sapi层注册网络地址事件,这个函数可以截取空中发来的消息,有兴趣的可以查查资料,第一个函数是截取的消息发到哪个任务中去,第二个参数,cluserID是消息的类型。 ZDO_RegisterForZDOMsg( sapi_TaskID, Match_Desc_rsp );//同理,在sapi层注册匹配描述符事件。

#if ( SAPI_CB_FUNC )

#if (defined HAL_KEY) && (HAL_KEY == TRUE) // Register for HAL events

RegisterForKeys( sapi_TaskID );//注册按键响应事件

if ( HalKeyRead () == HAL_KEY_SW_5)

{ uint8 startOptions = ZCD_STARTOPT_CLEAR_STATE | ZCD_STARTOPT_CLEAR_CONFIG;

zb_WriteConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );

zb_SystemReset(); }

#endif // HAL_KEY

osal_set_event(task_id, ZB_ENTRY_EVENT);//在这里设置了一个进入事件,第一个参数是task_id是任务的ID号,因此我们可以在sapi层的事件处理函数中找到这个进入事件是怎么处理的。 #endif }

在UINT16 SAPI_ProcessEvent( byte task_id, UINT16 events )函数中,找到

if ( events & ZB_ENTRY_EVENT ) {

uint8 startOptions;

// Give indication to application of device startup #if ( SAPI_CB_FUNC )

zb_HandleOsalEvent( ZB_ENTRY_EVENT ); #endif

// LED off cancels HOLD_AUTO_START blink set in the stack HalLedSet (HAL_LED_4, HAL_LED_MODE_OFF);//为了方便观察实验现象,将第四个灯关闭。

zb_ReadConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );

if ( startOptions & ZCD_STARTOPT_AUTO_START ) {

zb_StartRequest(); } else {

// blink leds and wait for external input to config and restart HalLedBlink(HAL_LED_2, 0, 50, 500); }

return (events ^ ZB_ENTRY_EVENT ); }

这个时候,程序就停在这里,只能看到LED_2在闪烁。这个时候我们可以按下按键1,然后去找一下,事件处理函数中如何对此事件进行相应。找到UINT16 SAPI_ProcessEvent( byte task_id, UINT16 events )函数中的关于按键的处理: case KEY_CHANGE: #if ( SAPI_CB_FUNC )

zb_HandleKeys( ((keyChange_t *)pMsg)->state, ((keyChange_t *)pMsg)->keys ); #endif

break;

进入到HandleKeys函数中,找到

if ( keys & HAL_KEY_SW_1 ) {

if ( myAppState == APP_INIT ) {

zb_ReadConfiguration( ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType );//读取flash中的设备类型

if ( logicalType != ZG_DEVICETYPE_ENDDEVICE ) {

logicalType = ZG_DEVICETYPE_COORDINATOR;//将设备类型改变为协调器类型

zb_WriteConfiguration(ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType);//将设备类型写入到flash中 }

zb_ReadConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );//读取启动模式

startOptions = ZCD_STARTOPT_AUTO_START;//将启动模式赋值为自动启动模式

zb_WriteConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );//将启动模式存入到flash中

zb_SystemReset();//系统重启设置。这时候flash中,启动模式就变成了ZCD_STARTOPT_AUTO_START,系统重启以后,系统继续刚才讲过的过程,不同的是在进行到进入事件处理函数时,if ( startOptions &

ZCD_STARTOPT_AUTO_START )的值成立,调用if语句里面的zb_StartRequest()函数;即执行开始请求函数。 }

接下来进入到zb_StartRequest函数中看一看,原代码如下: void zb_StartRequest() {

uint8 logicalType;

zb_ReadConfiguration( ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType );//从flash中读出设备类型。

// Check for bad combinations of compile flag definitions and device type setting.

if ((logicalType > ZG_DEVICETYPE_ENDDEVICE) || //可以判断if里面语句为0,执行else

#if !ZG_BUILD_ENDDEVICE_TYPE // Only RTR or Coord possible. (logicalType == ZG_DEVICETYPE_ENDDEVICE) || #endif

#if !ZG_BUILD_RTR_TYPE // Only End Device possible. (logicalType == ZG_DEVICETYPE_ROUTER) || (logicalType == ZG_DEVICETYPE_COORDINATOR) || #elif ZG_BUILD_RTRONLY_TYPE // Only RTR possible. (logicalType == ZG_DEVICETYPE_COORDINATOR) || #elif !ZG_BUILD_JOINING_TYPE // Only Coord possible. (logicalType == ZG_DEVICETYPE_ROUTER) || #endif

(0)) {

logicalType = ZB_INVALID_PARAMETER;

SAPI_SendCback(SAPICB_START_CNF, logicalType, 0); } else {

logicalType = ZB_SUCCESS; //将设备类型改为ZB_SUCCESS ZDOInitDevice(zgStartDelay); // 执行初始化设备函数。 }

return; }

那么接下来去初始化设备函数中看一下,右键,go to definition

uint8 ZDOInitDevice( uint16 startDelay ) {

uint8 networkStateNV = ZDO_INITDEV_NEW_NETWORK_STATE; //首先更改了网络状态为初始化新网络状态 uint16 extendedDelay = 0; if ( devState == DEV_HOLD ) {

zgInitItems( FALSE ); }

ZDConfig_InitDescriptors();

_NIB.CapabilityInfo = ZDO_Config_Node_Descriptor.CapabilityFlags;

devState = DEV_INIT; // 设备状态改为初始化 ZDApp_LeaveCtrlInit(); //离开控制初始化

ZDApp_LeaveCtrlStartup( &devState, &startDelay );//检查离开控制时的一些设置


Zstack中如何实现自己的任务(3).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:全国计算机等级考试二级VFP重点

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: