Zigbee学习日记(八)(上)协议栈安装与入门
goJhou 发布于2018-01 浏览:4091 回复:1
1
收藏

ZStack是TI公司为Zigbee量身定做的协议栈

通过到官方下载ZStack安装协议栈,可在C:/Texas Instruments/ZStack中查看到协议栈

目前协议栈已经更新到了3.0.1版本了。我用的是2.4.0-1.4.0版本,因为3.0.1要求IDE版本太高了,我这没更新IDE。

当需要根据协议栈进行开发时,仅需要将协议栈整个复制出来,放入项目目录

将根目录除了Components和Projects之外的文件/文件夹全部删除 是用不到的,有工具和帮助文档

在zstack/Samples中也仅需保留GenericApp这个目录,其余两个可删除

当我们要对GenericApp重命名时,将文件夹重命名成想要重命名的名字

然后进入该目录中的Source中。将3个文件内的GenericApp都替换成你重命名后的名字,保存。

然后将这3个文件的名字中的GenericApp也改成重命名之后的名字。

再进入到CC2530DB中,将GenericApp. 改成 重命名.(4个IAR工程文件)
并将这4个文件中的GenericApp也都替换一下。
eww文件可先改成txt打开替换后再改回eww

之后双击打开,就是重命名好的工程了

在左上角工程上方有个选项卡,可以下拉选择 协调器、路由器、终端

优先使用PRO就可以,功能没太大区别,但PRO更强大

通过在工程中添加模块化的串形数码管文件

将工程设置 c/c++ compiler中的Require prototype钩子取消

在Zmain.c main函数 osal_start_system()前输入初始化数码管的函数。

在APP/GenericApp.c中,有一个ProcessEvent,表示的是进程事件函数。

在ZDO_STATE_CHANGE这个case中,可以确认模块究竟是 协调器、路由器还是终端

在Tools/Config.cfg中

DDEFAULT_CHANLIST可以定义信道。可以将多个信道或操作,对于模块来说就意味着会在多个信道选择最优信道。

DZDAPP_CONFIG_PAN_ID用于定义局域网网号

非0xFFFF时,路由器和终端必须要加入到PANID为此时参数的网络中,如果没有就不加入网络。对于协调器来说,我必须要创建这样一个PANID的网络,如果说一个信道中已经有了该PANID的网络,会在PANID基础上+1创建网络。

如果为0xFFFF时,路由器和终端没有加入网络限制
协调器也会随机生成PANID

 

 

在ZStack中按照功能来划分,分为不同层,如物理层、网络层、应用层等

几乎每一个层都是一个任务,系统为每一个任务分配一个一个字节的唯一数值
这个数值叫做任务ID。他们能够处理的事物,叫做事件

处理事务
uint8 osal_set_event(uint8 task_id,uint16 event_flag)

在App/GenericApp.c的Init函数中,第一行就有保存GenericApp_TaskID。通过GenericApp_ProcessEvent中有GENERICAPP_SEND_MSG_EVT这样的event_flag,可以触发一个事件。当然也可以自定义flag。

延时处理事务 等待timeout_value毫秒后处理事务 仅处理一次
uint8 osl_start_timerEx(uint8 taskID,uint16 event_id,uint16 timeout_value)

 

如何添加自定义事件

一个任务可以定义16个事件

在GenericApp.h中,搜索Application Events 处可增加事件

需要注意的是 事件值转成2进制,16位里只能有1个是1,意味着有效值是从0x0001~0x000F + 0x0010

也就是16个事件可定义

之后再回到.c的GenericApp_ProcessEvent事件处理函数中,新增一个if

if (events & GENERICAPP_YOUR_EVT)
  {

    // return unprocessed events
    return (events ^ GENERICAPP_YOUR_EVT);
  }

要注意的是,ZMain会对学习板的硬件路径进行初始化,如果要对LED、串行数码管进行操作时,一定要按标准来设置。(普通IO还是偏上外设、输出还是输入、0还是1)。

 

如何添加消息

有些时候,16个事件是完全不够用的。ZStack引入了一种消息的概念

当需要应用层任务来处理某个事务时,首先给应用层任务发一个消息

调用osal_set_event,这样一来,应用层就会进入系统事件处理

在事件处理中判断到底产生事件的是哪一种类型的消息

根据消息的类型做相应的处理。

而消息的类型可以自定义,这样一来就打破了16个事件定义的限制。

keyChange_t *msgPtr;
msgPtr=(keyChange_t *)osal_msg_allocate(sizeof(keyChange_t));//定义按钮改变消息

if(msgPtr)
{
    msgPtr->hdr.event=KEY_CHANGE;//类型是消息改变
    msgPtr->keys=3; //消息内容是3
    
    osal_msg_send(GenericApp_TaskID,(uint8 *)msgPtr);//将消息发送到消息队列(会自动调用osal_set_event( destination_task, SYS_EVENT_MSG ))
}

可以看出,消息只能在SYS_EVENT_MSG这个事件中触发,所以在使用时要注意代码填写的位置。

 

协议栈的消抖处理

在先前,我们为了写一个按钮的中断,会延时10ms,为了稳定按钮状态。在协议栈中,延时是致命的,会破坏协议栈的栈体运行情况。应该使用延时处理事务方法。不需要担心重复调用的问题,25ms之内再调用,会从0ms重新计时。相当于了消抖效果。

在Hal/Target/CC2530DB/Drivers中保存有各部件的默认中断代码,如果要使用外部引入的 文件的中断,需要将Drivers内的中断给备注掉(HAL_ISR_FUNCTION)

 

生成hex

在工程属性中
Linker内Output,Override Defaulth和下方的Allow C-SPY-specific extra output file勾选上,在Extra Output中勾选Generate,Override Default,将文件名改成*.hex,下方format改成intel extended,然后在工程Tools/2530.xcl中搜索Include these two lines when generating a .hex file for banked code model:,将该句后两行的注释取消之后编译就有hex生成在工程目录中了。

 

收藏
点赞
1
个赞
共1条回复 最后由zi76226回复于2022-04
#2荒墨丶迷失回复于2018-01

强势占领沙发~

1
TOP
切换版块