zigbee笔记:十、ZStack(2.3.0-1.4.0)的OSAL使用分析
zigbee笔记:九中,我们已经学会了利用模板,定制自己的个性开发工程,本文为协议栈(ZStack-CC2530-2.3.0-1.4.0)代码使用分析笔记,来进一步掌握协议栈的使用。
一、协议栈使用知识点
1、协调器、路由器、终端代码下载
通过选项卡选择不同的节点类型工程(分别是协调器、路由节点和终端节点工程),就会导致参与编译的配置文件不同,配置不同就会导致部分宏定义不同,宏定义不同就会导致工程里某些宏的值不同。这些宏值的不同会影响程序执行的流程,就会导致出现不同的功能,,如下图所示。
在选项卡里每一种版本模块都貌似有2个分为不带Pro和带Pro。zigbee协议在发展过程中经历了3个版本,其中zigbee在7出的是最新的规范这个规范有2个版本 zigbee2007和 zigbeePro他们之间的区别是,功能基本相同,Pro版本功能稍微强大咱们一般都选 Pro 。


2、信道选择与网络PANID设置

在工程配置文件f8wConfig.cfg中, 参数-DDEFAULT_CHANLIST和-DZDAPP_CONFIG_PAN_ID。
(1)-DDEFAULT_CHANLIST 参数
信道编码采用64位独热码,当需要多信道通信时,可以采用或运算,如编码为0x00001800表示采用11和12信道,把结果作为 DEFAULT CHANLIST值。
路由器和终端:可以在参与或操作的这些信道上选择一个相对于我来说最佳的网络,加入进去。
协调器: 可以在参与或操作的这些信道上选择一个最佳的信道并在这个信道上创建自己的Zigbee网络()。
(2)-DZDAPP_CONFIG_PAN_ID 参数
-DZDAPP_CONFIG_PAN_ID值非0xFFFF时:
路由器和终端:必须要加入到PANID为参数值这样一个Zigbee无线局域网。
协调器:我要创建一个网络,并且把这个参数值作为这个网络的PANID。
-DZDAPP_CONFIG_PAN_ID值为0xFFFF时:
路由器和终端:在加入网络的时候没有PANID的限制。
协调器:可以随机生成一个值,把这个随机值作为这个网络的PANID。
(3)补充:
问1: 当2个模块下载相同的协调器代码,并且指走的PANID参数值为非0xFFFF,后果会怎样?
答: 先上电的模块可以创建0xFFFB这样-个zigbee网络,后上电的模块创建一个在DXFFF8基础上加1的网络。
问2:网络创建成功后,协调器的网络短地址固定为0x0000。
3、引脚初始化准备
启动osal之前main函数中还初始化调用了TI的一些硬件实验,其中很多引脚的功能已经被初始化为片上外设了,所以我们使用时要自己修改,不能漏步骤。如果添加自己的一些外设初始化要放在osal_start_system函数前面,WatchDogEnable之后,如初始化LED,如果缺少配置为普通IO模式这一步骤,可能会导致LED无法使用。

4、OSAL操作系统
OSAL(Operating System Abstraction Layer),能够实现任务调度的微操作系统,在OSAL操作系统中非常重要的两个概念是任务和事件,还有消息也比较重要
(1)OSAL的启动流程
如下图所示,系统启动后,先完成一系列的初始化,然后进入如无轮询主循环。

在zstack协议栈工程目录ZMAIN下的ZMain.c包含了主程序的入口地址

(2) 两个重要的函数
main函数中完成了一系列的初始,其中对开发者比较重要有两个函数
1)OSAL初始化函数 osal_init_system()
函数osal_init_system() 其中包含的任务初始化函数osalInitTasks(),完成系统任务和用户自定义任务

函数osalInitTasks()包含的任务初始化函数完成系统任务和用户自定义任务

2)系统启动函数 osal_start_system(),其功能是不断查询任务事件数组,如果有事件产生,则根据事件在taskArr数组中查询任务事件处理函数进行处理。从tasksEvents数组中tasksEvent[0](0号任务事件变量)去读一直读到tasksEvent[8],如果发现哪一个任务事件变量值为非0,就会跳出循环,此时的idx值就是它的任务ID。跳出上面的循环后,此时就会将idx中存的任务ID和event中存的任务事件变量值,通过函数指针的方法调用相应的任务事件处理函数。


(3) OSAL(操作系统抽象层)原理
1)应用层是一个任务,它有一个系统分配给它的数值唯一的编号叫做任务ID。

2)任务可以处理事件,处理事件的这些代码都在一个函数里,这个函数叫做应用层任务事件处理函数。应用层任务还有一个2个字节的变量,这个变量叫做任务事件变量,如果事件变量和某个事件的宏值&操作为1,那么表示应用层任务将要处理这个事件。

3)系统在运行的时候,会不断地读取应用层任务事件变量,如果应用层任务事件变量为非0,就会认为应用层任务有事件需要处理,此时就会调用应用层任务事件处理函数StarryApp_ProcessEvent,并将任务事件变量的值传给events,在处理函数中会将events分别与应用层定义的所有任务事件宏值进行与操作,如果值为1,就会去执行这个事件处理的相应代码;当发现任务事件变量为0的时候,就会认为应用层任务没有事件需要处理。
4) 函数 uint8 osal_set_event( uint8 task_id, uint16 event_flag ) 为事件产生函数,调用执行某个任务中的某个事件, para1是任务ID,para2是任务中的某个事件宏。

本质是,把taskID(应用层任务)的任务事件变量中对应于宏event_flag值为1的那个位变为1,这样的话首先这个任务事件变量就变成了非0,系统在检测到任务事件变量为非0,就会去调用任务事件处理函数***App_ProcessEvent。在这个函数里,任务事件变量肯定和任务宏的值与操作为1,所以必定会执行这个事件相关的代码。
5)在ZStack里按照代码功能来划分,分成不同的层,比如,硬件操作相关硬件层,网络相关的代码叫网络层,自己写应用程序部分叫应用层。几乎每一个层都是一个任务,系统为每一个任务分配一个字节的唯一数值编号, 我们把这个数值编号叫做任务ID(task_id)。每一个任务都能处理一些他们能够处理的事物,叫做事件(event_flag)。TI在设计的时候把任务事件处理函数和任务事件变量都封装成了数组:
函数数组={任务事件处理函数A,任务事件处理函数B,任务事件处理函数C...}
变量数组={任务事件变量A,任务事件变量B,任务事件变量C...}


6)任务ID,系统不是随便分配的,我们可以通过这个值立即找到这个任务自己的任务事件处理函数和任务事件变量。任务ID就是数组的下标,通过下标就可以找到相应的任务事件处理函数和任务事件变量。由函数osalInitTasks()包含的任务初始化函数完成系统任务和用户自定义任务,详见 4(2)。

7)事件是系统需要处理的事情,必须有对应的任务进行处理,事件采用16位独热码,即每种任务可以有16种事件(event_flag)。例如,在应用层,系统事件已被定义,占用编码为0x8000,还有15种用户可定义的事件。


8)所有Zstack协议栈在稳定工作时,它的行为是在for(;;){}死循环里不断去读所有任务的任务事件变量。如果发现所有任务的任务事件变量都为0,没问题,说明所有任务都没有事件将要去处理;不断重复这个过程,直到发现,某个任务事件变量不为0,就会通过不为0的这个任务ID找到这个任务事件处理函数,去处理相应的事件。
9) 当事件数量较多,编码无法表示时,可采用消息,系统事件就是采用消息进行事件传递的。 OSAL任务与事件的关系 ,如下图所示。

10) 消息*******************************************
4、事件处理函数的编写
以应用层任务的事件为例, 事件处理函数要在xxApp.c里的xx应用事件处理函数中编写(xxApp_ProcessEvent),如下图所示。

5、函数总结:
(1)uint8 osal_set_event( uint8 task_id, uint16 event_flag );
事件产生函数,调用执行某个任务中的某个事件, para1是任务ID,para2是任务中的事件
(2)uint8 osal_start_timerEx( uint8 task_id, uint16 event_flag,unit16 timeout_value );
事件定时器触发函数,等待一定时间执行某个任务中的某个事件,para1是任务编号,para2是参数是要处理的事务,para3是是时间(毫秒)。
(3)uint8 osal_msg_send( uint8 destination_taskID, uint8 *msg_ptr );
发送消息的函数,para1是要接收此Message的目标任务ID,para2是所要发送的消息Message指针。
(4)MSGpkt =(afIncomingMSGPacket t *)osal_msg_receive( SampleApp TasklD );
接收消息的函数,para1是任务ID的参数,用于指定从哪个任务的消息队列中接收消息。osal_msg_receive函数从任务的消息队列中取出一个消息,该消息是一个指向afIncomingMSGPacket_t 类型的指针,然后将其强制类型转换为 afIncomingMSGPacket_t 类型(osal_msg_receive()函数返回的是一个指向 void 类型的指针),最后将其赋值给 MSGpkt 变量,这个操作通常在一个任务中用于接收其他任务发送的消息,以便进行进一步的处理。
二、常见注意和错误解决
1、编译时Error[Pa045]: **** has no prototype ,prototypes取消勾选
在协议栈中添加使用自己写程序的时候,编译时要把设置中的prototypes取消勾选。


2、编译基于协议栈代码生成hex文件
(1)首先设置选项,如下图所示


(2)取消f8w2530.xcl文件内的部分代码,如下图所示

3、 Warning[w2]: Symbol ?PBANK is redefined in command-line
(1) IAR 编译zigbee工程时 报的警告如下:

(2)可以在配置文件中修改,Tools文件夹下的f8w2530.xcl中屏蔽掉-D?PBANK=93这一行。

(3)重新全部编译

4、Warning[Pe223]: function **** declared implicitly
这个告警是提示我,我调用的这个 **** 函数没有进行函数声明,一般出现这种情况就是没有调用该函数声明的头文件,或者是没有对其进行外部声明。 解决办法
1、将使用的函数的头文件包含进去。
2、对其使用关键字"extern"声明
extern void ****(void);
3、还有一种就是如果只在一个文件中调用函数,就将这个函数定义移到最前面也可以解决。
参考链接
(1)lesson7上协议栈的使用_1_哔哩哔哩_bilibili
(2)ZigBee协议栈 -- Zstack协议栈(Zstack2.5.1a)-CSDN博客
(3)zigbee之Zstack协议栈使用_z-stack协议栈-CSDN博客
(4)lesson7-3 OSAL操作系统抽象层原理_osal运行机制-CSDN博客
(5)lesson7-2 Zigbee协议栈的使用_zigbee协议栈如何创建一个新任务-CSDN博客
相关文章:
zigbee笔记:十、ZStack(2.3.0-1.4.0)的OSAL使用分析
zigbee笔记:九中,我们已经学会了利用模板,定制自己的个性开发工程,本文为协议栈(ZStack-CC2530-2.3.0-1.4.0)代码使用分析笔记,来进一步掌握协议栈的使用。 一、协议栈使用知识点 1、协调器、路…...
SpringBoot响应式编程(1)Reactor核心
一、概述 1.1介绍 Reactor 是一个用于JVM的完全非阻塞的响应式编程框架,Webflux 底层使用的也是该框架,其通过流的方式实现了异步相应,具备高效的需求管理(即对 “背压(backpressure)”的控制)…...
Java后端处理前端字符串与 JSON 数据:安全拼接与转义技巧
在现代 Web 开发中,前后端数据交互是家常便饭。我们经常需要处理前端传递的字符串和 JSON 数据,并在后端进行加工处理后发送到其他服务。本文将以 Spring Boot 为例,探讨如何安全地拼接字符串和 JSON 数据,并介绍如何避免 JSON 特…...
一文搞懂bfs,dfs和高级图算法
你以为BFS(广度优先搜索)和DFS(深度优先搜索)这两种基础算法,简单到小学数学就能搞定?但真的是这样吗?很多人都这么认为,但真的对吗?今天,我们不只是走马观花…...
【Rust光年纪】Rust异步编程利器:异步DNS、高性能Web服务器一网打尽
构建高效网络应用必备:解读Rust异步编程神器 前言 Rust 是一种快速流行的系统编程语言,它以其内存安全和并发性能而闻名。在 Rust 生态系统中,有许多优秀的库和框架可以帮助开发者构建高性能、可靠的应用程序。本文将介绍几个在 Rust 中备受…...
04学生管理系统(栈)
文章目录 预处理菜单结构体主函数函数声明栈操作功能实现 预处理 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<windows.h> #include<conio.h>#define OVERFLOW -2 #define FALSE 0 #define TRUE 1 #define OK 1 …...
我们如何在centos上部署批量管理工具ansible
1)我们先准备环境、设备 #我们准备一台服务机 (192.168.61.140) #然后准备几天客户机(192.168.61.141 192.168.61.142)这里我们准备两台2)然后我们在客服务机里面添加域名 vi /etc/hosts #添加如下内容 192.…...
如何评估前端代码审查培训计划的有效性?
评估前端代码审查培训计划的有效性可以通过以下方法: 培训前后测试: 在培训前后对学员进行测试,比较结果以评估知识增长。 学员反馈: 通过问卷调查、访谈或开放式反馈收集学员对培训内容、方式和效果的看法。 参与度:…...
使用nvm切换Node.js版本
一、安装nvm nvm(Node Version Manager)是一个用于管理Node.js版本的工具,它允许你在同一台机器上安装和切换多个Node.js版本。 1.安装nvm https://github.com/coreybutler/nvm-windows 访问以上链接到github去下载 点击releases 下载下图…...
x264 编码器 PSNR算法源码分析
PSNR PSNR(Peak Signal-to-Noise Ratio,峰值信噪比)是一种常用的图像质量评价指标,用于衡量图像或视频的清晰度和质量。PSNR是基于信号的最大可能功率与影响信号的噪声功率之间的比率。在图像处理领域,PSNR通常用来评估图像压缩或图像增强算法的效果。 PSNR的计算公式是…...
开源web版3D展示工具Online3DViewer
Online3DViewer是一个免费且开源的Web解决方案,它允许用户在浏览器中直接预览和探索3D模型。 以下是关于Online3DViewer的详细介绍: 一、基本概述 定义:Online3DViewer是一个在线3D模型查看器,支持多种3D文件格式,用…...
白骑士的Matlab教学实战项目篇 4.2 信号与图像处理项目
系列目录 上一篇:白骑士的Matlab教学实战项目篇 4.1 数据分析与可视化 信号处理和图像处理是 MATLAB 的重要应用领域,广泛应用于医学、工程、科学研究等领域。以下内容将介绍信号滤波与频域分析、图像增强与分割的基本概念和方法,并通过一个…...
复现、并改进open-mmlab的mmpose详细细节
复现open-mmlab的mmpose详细细节 1.配置环境2.数据处理3.训练4.改进mmpose4.1 快速调试技巧4.2 快速定位4.3 改进backbone4.3.1 使用说明4.3.2 改进案例4.3.2.1 复现mmpose原配置文件4.3.2.2 复现开源项目4.3.2.3 修改配置文件4.3.2.4 修改新模型 4.4 添加auxiliary_head4.4.1 …...
编写兼容Python2.x与3.x代码
编写兼容Python2.x与3.x代码 当我们正处于Python2.x到Python3.x的过渡期时,你可能想过是否可以在不修改任何代码的前提下能同时运行在Python2和3中。这看起来还真是一个合理的诉求,但如何开始呢?哪些Python2代码在3.x解释器执行时容易出状况…...
比特币8.12学习问题
疑问:什么是过滤,什么是offset 没有投钱的情况下,怎么用api 公式:单币分配金额 总资金 / 2/ offset/选币数量,其中2 表示多空 买入滑点(Slippage)是指在执行交易订单时,实际成交…...
解析 Vue 中的app.version、 app.provide 与 app.runWithContext :原理、应用与实例剖析
目录 app.provide app.runWithContext app.version 非 VIP 用户能够通过积分下载博文资源 app.provide 在 Vue 3.0 中,app.provide充当着在应用层级提供全局共享数据或者服务的关键角色。 app.provide(key, value) 这一方法接收两个关键参数,其中 …...
Ubuntu server 命令行跑selenium
背景 自动化测试都是在本机win上使用selenium 跑自动化脚本,但是服务器都是命令行的没有web界面 依赖包部署 apt-get install zlib1g-dev zlib1g## 安装谷歌浏览器 ## 跳到底部,选择其他平台 https://www.google.com/chrome/## ubuntu # dpkg -i google-chrome-stable_…...
刚刚,模糊测试平台SFuzz受到行业认可
近日,中国网络安全产业联盟(CCIA)正式发布了“2024年网络安全优秀创新成果大赛-安全严选专题赛”评选结果,开源网安模糊测试平台SFuzz凭借重大创新能力,得到组委会认可,获本次大赛创新产品优胜奖。 2024年网…...
数据结构与算法——DFS(深度优先搜索)
算法介绍: 深度优先搜索(Depth-First Search,简称DFS)是一种用于遍历或搜索树或图的算法。这种算法会尽可能深地搜索图的分支,直到找到目标节点或达到叶节点(没有子节点的节点),然后…...
基于lambda简化设计模式
写在文章开头 本文将演示基于函数式编程的理念,优化设计模式中繁琐的模板化编码开发,以保证用尽可能少的代码做尽可能多的事,希望对你有帮助。 Hi,我是 sharkChili ,是个不断在硬核技术上作死的 java coder ÿ…...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...
在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案
这个问题我看其他博主也写了,要么要会员、要么写的乱七八糟。这里我整理一下,把问题说清楚并且给出代码,拿去用就行,照着葫芦画瓢。 问题 在继承QWebEngineView后,重写mousePressEvent或event函数无法捕获鼠标按下事…...
Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...
redis和redission的区别
Redis 和 Redisson 是两个密切相关但又本质不同的技术,它们扮演着完全不同的角色: Redis: 内存数据库/数据结构存储 本质: 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能: 提供丰…...
MySQL体系架构解析(三):MySQL目录与启动配置全解析
MySQL中的目录和文件 bin目录 在 MySQL 的安装目录下有一个特别重要的 bin 目录,这个目录下存放着许多可执行文件。与其他系统的可执行文件类似,这些可执行文件都是与服务器和客户端程序相关的。 启动MySQL服务器程序 在 UNIX 系统中,用…...
raid存储技术
1. 存储技术概念 数据存储架构是对数据存储方式、存储设备及相关组件的组织和规划,涵盖存储系统的布局、数据存储策略等,它明确数据如何存储、管理与访问,为数据的安全、高效使用提供支撑。 由计算机中一组存储设备、控制部件和管理信息调度的…...
