Zigbee是一种低功耗、低成本的无线通信协议,特别适用于物联网设备之间的通信。Zigbee协议栈是一组硬件和软件层级结构,用于支持Zigbee设备之间的通信。
Zigbee协议栈通常由以下几个层级组成:
-
物理层(Physical Layer):负责处理物理无线通信的细节,例如频率、功率控制和数据传输速率等。物理层使用的是2.4GHz频段,并支持多种调制方式。
-
媒介接入控制层(Medium Access Control, MAC):负责管理通信介质的访问,以便多个设备可以按照一定的规则共享通信介质。MAC层处理一些基本的网络控制功能,例如设备的寻址、帧结构定义和冲突避免。
-
网络层(Network Layer):负责设备的路由和组网管理。网络层处理设备之间的寻址、路由选择和数据包转发等任务。它使用分层路由技术,可实现灵活的网络拓扑结构,如星形、网状和多跳网络等。
-
应用层(Application Layer):负责定义应用层协议和数据格式,以便不同设备之间可以进行有效的通信。应用层定义了设备之间的命令、控制和数据交换等。
Zigbee协议栈的设计目标是提供低功耗、低数据速率和较短通信距离的通信解决方案。它广泛应用于家庭自动化、智能电网、工业自动化和物联网等领域,能够支持大规模设备的无缝连接和通信。
物理层
其中物理层可简单理解为,将一个设备的数据转化为电磁波信号之后,通过物理介质发送给另一个设备,再由另一个设备解读电磁波信号获取数据。
MAC层
MAC(媒体接入控制层)的作用是有序地利用网络通讯资源来进行可靠通信。
由于电磁波和物理介质的限制,同一物理资源在同一时刻只能被一个网络设备占用来发送数据,为控制多个网络设备发送数据。MAC层将设备划分成协调器和普通设备(路由器和终端),协调器产生并发送信标帧,普通设备根据所发出的信标帧和协调器同步,即可组建网络。
网络层(核心协议)
基于IEEE 802.15.4协议之上,主要负责多个设备之间的组网,其优点为支持更多设备进行组网、能够进行多通道通信服务、支持自组网;其次负责设备之间的控制指令和设备状态数据的传输,如温度监测、开关控制;还负责网络安全管理。
目前较多采用的是ZigBee 2007 (Pro)版本。
应用层(一套标准规范,即应用协议)
应用层规定了对象的属性和状态。如灯具备开关的属性,这个属性由开(1)和关(0)两种状态。ZigBee技术开发一般就是指基于ZigBee应用协议的技术开发。
为解决同一领域不同公司设备兼容性问题,ZigBee联盟根据不同领域(Profile)推出了不同的协议。
之后,为解决不同领域的兼容性问题,ZigBee联盟推出ZigBee3.0协议,提升了安全性和稳定性,是目前应用最为广泛的ZigBee应用协议。
TI 技术方案(Chipcon)
TI Z-Stack是ZigBee协议的代码实现, 是TI(德州仪器)针对 ZigBee 3.0 协议而开发的技术方案,也称为TI ZigBee 3.0 协议栈,包含应用层(Z-Stack 3.0)和内核层(2.7.1)。
本次项目采用TI Z-Stack3.0.1_2协议栈以及CC2530芯片进行学习开发,Z-Stack 3.0.1 是到目前为止最新版本。
Z-Stack 3.0官方下载地址 https://www.ti.com/tool/Z-STACK 。
ZigBee设备类型
操作系统的任务调度
任务调度涉及任务、任务池、优先级、轮询和系统调度周期。其中任务池为储存多个任务的缓冲区,适用于任务池的数据结构有多种,比如队列(先进先出)、堆栈(先进后出)和树状结构(遍历),这些数据结构的实现方式可以是静态的数组或者是动态的链表等;优先级为在同一时刻执行任务的等级划分;轮询为系统每隔一段时间在任务池中检查需要处理的任务;“每隔一段时间”指的就是操作系统调度周期。
简单的操作系统原理代码如下:
void main()
{
initLed();//初始化LED灯
taskListInit();//初始化任务池
addTask(2000, TASK_LED_ON);//往任务池中添加一个任务,即2s后打开LED
addTask(3000, TASK_LED_OFF);//往任务池中添加一个任务,即3s后关闭LED
//每隔1ms轮询1次
while(1) {
delayMs(1);//暂停1ms
polling();//轮询
}
}
OSAL(Operating System Abstraction Layer,系统抽象层)
可以通俗地理解为一个简化版的操作系统,为Z-Stack的正确运行提供了内存管理、中断管理和任务调度等基本功能。
ZMain.c文件,可以找到main()函数,其代码如下:
int main( void )
{
// Turn off interrupts
osal_int_disable( INTS_ALL ); // 关闭所有中断
// Initialization for board related stuff such as LEDs
HAL_BOARD_INIT(); // 初始化板载资源,比如PA、时钟源等
// Make sure supply voltage is high enough to run
zmain_vdd_check(); // 检测供电电压是否可以支撑芯片正常运行
// Initialize board I/O
InitBoard( OB_COLD ); // 初始化板载I/O,比如按键配置为输入
// Initialze HAL drivers
HalDriverInit(); // 初始化硬件适配层,比如串口、显示器等
// Initialize NV System
osal_nv_init( NULL ); // 初始化NV(芯片内部FLASH的一块空间)
// Initialize the MAC
ZMacInit(); // 初始化MAC层(数据链路层)
// Determine the extended address
zmain_ext_addr(); // 确定芯片的物理地址
#if defined ZCL_KEY_ESTABLISH
// Initialize the Certicom certificate information.
zmain_cert_init(); // 初始化认证信息
#endif
// Initialize basic NV items
zgInit(); // 初始化存储在NV中的协议栈全局信息,如网络启动方式等
#ifndef NONWK
// Since the AF isn't a task, call it's initialization routine
afInit(); // 初始化AF(射频)
#endif
// Initialize the operating system
osal_init_system(); // 初始化OSAL(操作系统抽象层)
// Allow interrupts
osal_int_enable( INTS_ALL ); // 使能所有中断
// Final board initialization
InitBoard( OB_READY ); // 初始化板载IO资源,比如按键
// Display information about this device
zmain_dev_info(); // 在显示器上显示设备物理地址
/* Display the device info on the LCD */
#ifdef LCD_SUPPORTED
zmain_lcd_init(); // 在显示器上显示设备信息,比如制造商等
#endif
#ifdef WDT_IN_PM1
/* If WDT is used, this is a good place to enable it. */
WatchDogEnable( WDTIMX ); // 启动看门狗功能
#endif
/* 进入系统轮询 */
osal_start_system(); // No Return from here
return 0; // Shouldn't get here.
} // main()
上述代码中有两个关键的函数,代码如下:
//初始化OSAL,包括初始化任务池
osal_init_system();
//轮询任务池
osal_start_system();
osal_init_system()函数代码如下:
uint8 osal_init_system( void )
{
#if !defined USE_ICALL && !defined OSAL_PORT2TIRTOS
// 初始化内存分配系统
osal_mem_init();
#endif /* !defined USE_ICALL && !defined OSAL_PORT2TIRTOS */
// 初始化消息队列
osal_qHead = NULL;
// 初始化OSAL定时器
osalTimerInit();
// 初始化电源管理系统
osal_pwrmgr_init();
#ifdef USE_ICALL
osal_prepare_svc_enroll();
#endif /* USE_ICALL */
// 初始化任务池
osalInitTasks();
#if !defined USE_ICALL && !defined OSAL_PORT2TIRTOS
// Setup efficient search for the first free block of heap.
osal_mem_kick();
#endif /* !defined USE_ICALL && !defined OSAL_PORT2TIRTOS */
#ifdef USE_ICALL
// Initialize variables used to track timing and provide OSAL timer service
osal_last_timestamp = (uint_least32_t) ICall_getTicks();
osal_tickperiod = (uint_least32_t) ICall_getTickPeriod();
osal_max_msecs = (uint_least32_t) ICall_getMaxMSecs();
/* Reduce ceiling considering potential latency */
osal_max_msecs -= 2;
#endif /* USE_ICALL */
return ( SUCCESS );
}
osal_start_system()函数代码如下:
void osal_start_system( void )
{
#ifdef USE_ICALL
/* Kick off timer service in order to allocate resources upfront.
* The first timeout is required to schedule next OSAL timer event
* as well. */
ICall_Errno errno = ICall_setTimer(1, osal_msec_timer_cback,
(void *) osal_msec_timer_seq,
&osal_timerid_msec_timer);
if (errno != ICALL_ERRNO_SUCCESS)
{
ICall_abort();
}
#endif /* USE_ICALL */
#if !defined ( ZBIT ) && !defined ( UBIT )
//主循环
for(;;)
#endif
{
//系统轮询调度
osal_run_system();
#ifdef USE_ICALL
ICall_wait(ICALL_TIMEOUT_FOREVER);
#endif /* USE_ICALL */
}
}
在osal_start_system()函数的主循环中,循环调用了 osal_run_system()函数,该函数主要工作轮询任务池。
void osal_run_system( void )
{
uint8 idx = 0;
/* 更新时间,并整理出到期的任务。系统的时钟周期是:320us */
osalTimeUpdate();
Hal_ProcessPoll();// 硬件适配层中断查询
do {
if (tasksEvents[idx])// 查看是否有任务需要处理
{
break;
}
} while (++idx < tasksCnt);// 轮询整个任务池
if (idx < tasksCnt)//循环结束后,如果idx < tasksCnt表示任务池有任务需要处理
{
uint16 events;
halIntState_t intState;
HAL_ENTER_CRITICAL_SECTION(intState);//关闭中断
events = tasksEvents[idx];//evets中保存了该任务中的待处理事件
tasksEvents[idx] = 0;//清空此任务中的所有待处理事件
HAL_EXIT_CRITICAL_SECTION(intState);//恢复中断
activeTaskID = idx;
events = (tasksArr[idx])( idx, events ); // 处理任务中的事件
activeTaskID = TASK_NO_TASK;
HAL_ENTER_CRITICAL_SECTION(intState);//关闭中断
tasksEvents[idx] |= events;//保存还没被处理的事件到任务中
HAL_EXIT_CRITICAL_SECTION(intState);//恢复中断
}
#if defined( POWER_SAVING ) && !defined(USE_ICALL)
else// Complete pass through all task events with no activity? {
osal_pwrmgr_powerconserve(); //如果没有任务需要处理则进入低功耗
}
#endif
/* Yield in case cooperative scheduling is being used. */
#if defined (configUSE_PREEMPTION)&&(configUSE_PREEMPTION == 0) {
osal_task_yield();
## 最后
**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**
**深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。**
**因此收集整理了一份《2024年嵌入式&物联网开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**
![img](https://img-blog.csdnimg.cn/img_convert/b821abfad641c9e16045c1f9b3cf1edf.png)
![img](https://img-blog.csdnimg.cn/img_convert/5710fcf36d510392240e13aa200d7578.jpeg)
![img](https://img-blog.csdnimg.cn/img_convert/6846078b1339804e739bbf7d7af59551.png)
![img](https://img-blog.csdnimg.cn/img_convert/16f95d529472c0f25920a6dcd6234421.png)
![img](https://img-blog.csdnimg.cn/img_convert/e00c187cd7e52e1f0103520276544f92.png)
![img](https://img-blog.csdnimg.cn/img_convert/4e95795c33437b0dacc1acd21cc4619b.png)
![](https://img-blog.csdnimg.cn/img_convert/c58d69168cf1364d48c7d50c1c038fb3.png)
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上嵌入式&物联网开发知识点,真正体系化!**
[**如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!**](https://bbs.csdn.net/topics/618654289)
**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**!!
(img-ZF6E358O-1715603978656)]
[外链图片转存中...(img-MNtBWd9O-1715603978656)]
[外链图片转存中...(img-N7PcNX4f-1715603978657)]
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上嵌入式&物联网开发知识点,真正体系化!**
[**如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!**](https://bbs.csdn.net/topics/618654289)
**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**!!