zstack 串口使用指南
Zstack入门教程
Zstack入门教程第一步:安装Zstack从TI官方网站上下载的Zstack为:swrc072c.zip,我想这个压缩包大家都认识。
解压之后为:ZStack-CC2430-1.4.3.exe文件。
这个安装文件大家都会了。
默认安装路径为:C:\Texas Instruments\ZStack-1.4.3。
安装之后在C:\Texas Instruments\ZStack-1.4.3目录下有各PDF 文档为:Getting Started Guide CC2430.pdf,不用多说,这个肯定是要看的。
既然把它放到这么前面,说明它是入门中的入门文档。
下面就简单介绍下这个文档:1、介绍了安装ZStack-CC2430-1.4.3.exe需要的硬件软件条件:需要电脑、操作系统为Windows 2000或Windows XP。
至于更高或更低版本的本人没有尝试。
2、讲了安装流程。
这个有点多余了,这年月哪个有电脑的没有安装上百上千次的软件啊?但是需要强调的是安装路径----默认就好!3、接下来就是让我们看的第一个文档为:Start->Programs->Texas Instruments->ZStack-1.4.3->Z-Stack User’s Guide,既然让我看我就来看看这个文档!!第二步:Z-Stack 用户指导这个文档的更新时间为:2007年12月21日----应该还是比较新的版本。
由于本人英文的却有限,就不翻译了,浏览一遍,把大概意思说下就可以了:1、介绍1.1、适用范围本文档适用于CC2430ZigBee开发板----CC2430ZDK。
2、产品包描述(TI提供的CC2430ZDK工具包)2.1、安装包内容这个就是上面提到的的ZStack-CC2430-1.4.3.exe安装之后的所有内容了。
说白了就是包含Zstack开发所需要的所有软件和文档资料等。
2.2、开发板介绍两块SmartRF04EB 评估版,每个都可以用于CC2430EM评估模块。
Zstack协议栈对串口进行操作
Zstack协议栈对串口进行操作Zstack协议栈中如何对串口进行操作想要使用串口功能,首先要进行初始化操作:halUARTCfg_t uartConfig;uartConfig.configured = TRUE; // 2x30 don't care - see uart driver.uartConfig.baudRate = SERIAL_APP_BAUD;uartConfig.flowControl = TRUE;uartConfig.flowControlThreshold = SERIAL_APP_THRESH; // 2x30 don't care - see uart driver.uartConfig.rx.maxBufSize = SERIAL_APP_RX_SZ; // 2x30 don't care - see uart driver.uartConfig.tx.maxBufSize = SERIAL_APP_TX_SZ; // 2x30 don't care - see uart driver.uartConfig.idleTimeout = SERIAL_APP_IDLE; // 2x30don't care - see uart driver.uartConfig.intEnable = TRUE; // 2x30 don't care - see uart driver.uartConfig.callBackFunc = SerialApp_CallBack; HalUARTOpen (SERIAL_APP_PORT, &uartConfig);程序首先定义了halUARTCfg类型的变量uartConfig,用来配置跟串口功能相关的波特率、流控制等等,其中最重要的是uartConfig.callBackFunc=SerialApp_CallBack。
ZStack V3.10.0 日志服务器 使用教程说明书
3. 验证日志服务器
文档版本:V3.10.0
5
日志服务器 使用教程 / 3 典型场景实践
配置完成后,在日志服务器中输入以下命令,查看是否已正常获取管理节点日志: cat /var/log/test.log
如图 3: 获取管理节点日志所示: 图 3: 获取管理节点日志
如上所述,日志服务器已成功接收到管理节点日志信息,日志服务器配置生效。
云主机(VM Instance)
运行在物理机上的虚拟机实例,具有独立的IP地址,可以访问公共网络,运行应用服务。
镜像(Image)
云主机或云盘使用的镜像模板文件,镜像模板包括系统云盘镜像和数据云盘镜像。
文档版本:V3.10.0
7
日志服务器 使用教程 / 术语表
云盘(Volume)
云主机的数据盘,给云主机提供额外的存储空间,共享云盘可挂载到一个或多个云主机共同使用。
如图 1: 配置syslog server所示: 图 1: 配置syslog server
2. 在云平台创建日志服务器 在ZStack私有云主菜单,点击平台管理 > 日志服务器按钮,进入日志服务器界面,点击添加 日志服务器按钮,参考以下内容进行配置:
• 名称:设置日志服务器名称 • 简介:可选项,可留空不填 • IP地址:输入日志服务器的IP地址
注意事项 • 需要设置日志级别与日志服务器的配置完全一致,才能正常接收日志信息,日志级别支持设 置LOCAL0-9,仅为了匹配日志服务器,无高低之分。 • 需确保云平台管理节点与日志服务器的连通性。 • 配置成功后,管理节点的全部日志均会发送至日志服务器,不区分DEBUG、INFO、ERROR等 输出级别。 • 仅admin/平台管理员支持设置日志服务器。
基于Zstack的串口控制LED 实验报告-推荐下载
对全部高中资料试卷电气设备,在安装过程中以及安装结束后进行高中资料试卷调整试验;通电检查所有设备高中资料电试力卷保相护互装作置用调与试相技互术通关,1系电过,力管根保线据护敷生高设产中技工资术艺料0不高试仅中卷可资配以料置解试技决卷术吊要是顶求指层,机配对组置电在不气进规设行范备继高进电中行保资空护料载高试与中卷带资问负料题荷试2下卷2,高总而中体且资配可料置保试时障卷,各调需类控要管试在路验最习;大题对限到设度位备内。进来在行确管调保路整机敷使组设其高过在中程正资1常料中工试,况卷要下安加与全强过,看度并22工且22作尽22下可22都能22可地护以缩1关正小于常故管工障路作高高;中中对资资于料料继试试电卷卷保破连护坏接进范管行围口整,处核或理对者高定对中值某资,些料审异试核常卷与高弯校中扁对资度图料固纸试定,卷盒编工位写况置复进.杂行保设自护备动层与处防装理腐置,跨高尤接中其地资要线料避弯试免曲卷错半调误径试高标方中高案资等,料,编试要5写、卷求重电保技要气护术设设装交备备置底4高调、动。中试电作管资高气,线料中课并敷3试资件且、设卷料中拒管技试试调绝路术验卷试动敷中方技作设包案术,技含以来术线及避槽系免、统不管启必架动要等方高多案中项;资方对料式整试,套卷为启突解动然决过停高程机中中。语高因文中此电资,气料电课试力件卷高中电中管气资壁设料薄备试、进卷接行保口调护不试装严工置等作调问并试题且技,进术合行,理过要利关求用运电管行力线高保敷中护设资装技料置术试做。卷到线技准缆术确敷指灵设导活原。。则对对:于于在调差分试动线过保盒程护处中装,高置当中高不资中同料资电试料压卷试回技卷路术调交问试叉题技时,术,作是应为指采调发用试电金人机属员一隔,变板需压进要器行在组隔事在开前发处掌生理握内;图部同纸故一资障线料时槽、,内设需,备要强制进电造行回厂外路家部须出电同具源时高高切中中断资资习料料题试试电卷卷源试切,验除线报从缆告而敷与采设相用完关高毕技中,术资要资料进料试行,卷检并主查且要和了保检解护测现装处场置理设。备高中资料试卷布置情况与有关高中资料试卷电气系统接线等情况,然后根据规范与规程规定,制定设备调试高中资料试卷方案。
z-stack协议栈串口驱动详解与同时使用两个串口的配置方法
Z-Stack串口操作:CC2530共有两个串口,UART0和UART1,两个串口可以通过设置寄存器PERCFG的值映射到不同的引脚上,对应的映射关系如下:在CC2530中提供了两种方式来操作串口,即直接存取访问(DMA)和中断(ISR)方式,两种操作方式的区别在这里不再叙述,想了解的请自行查阅相关资料。
在z-stack中默认的使用DMA方式来操作串口,默认配置的串口为UART0,UART0默认使用位置1,即P02为UART的RX,P03为UART的TX。
接下来将详细介一下Z-STACK串口默认的配置流程,并介绍如何配置同时使用两个串口。
一、串口默认配置的流程从main函数开始,串口的初始化化函数在调用HalDriverInit()函数时被调用,在HalDriverInit函数中调用了函数HalUARTInit()函数,函数原型如下:void HalUARTInit(void){#if HAL_UART_DMAHalUARTInitDMA();#endif#if HAL_UART_ISRHalUARTInitISR();#endif#if HAL_UART_USBHalUARTInitUSB();#endif}可以看出,协议栈通过判断宏定义的方法来判断以何种方式来初始化串口,有关的宏可以在hal_board_cfg.h中找到,先将与串口有关的宏列出以便分析:* Set to TRUE enable UART usage, FALSE disable it */#ifndef HAL_UART //如果未定义HAL_UART/*如果定义了defined ZAPP_P1、defined ZAPP_P2、defined ZTOOL_P1、defined ZTOOL_P2中的一个,就定义HAL_UART为1,协议栈默认地定义了ZTOOL_P1,可以点击project->options->c/c++complier->preprocess->defined symbols来查看预编译的宏*/#if (defined ZAPP_P1) || (defined ZAPP_P2) || (defined ZTOOL_P1) || (defined ZTOOL_P2) #define HAL_UART TRUE#else //否则的话在进行下面的#define HAL_UART FALSE //将HAL_UART定义为0,即不使用串口#endif#endif#if HAL_UART //如果HAL_UART为1// Always prefer to use DMA over ISR.总是优先地使用DMA方式#if HAL_DMA#ifndef HAL_UART_DMA#if (defined ZAPP_P1) || (defined ZTOOL_P1)#define HAL_UART_DMA 1#elif (defined ZAPP_P2) || (defined ZTOOL_P2)#define HAL_UART_DMA 2#else#define HAL_UART_DMA 1#endif#endif/*执行完上面的一部分代码后,HAL_UART_DMA的值就为1了,具体自行分析#define HAL_UART_ISR 0 //默认不实用ISR方式来处理中断/*在这里已经定义了HAL_UART_ISR,所以就不会进入下面的#ifndef HAL_UART_ISR判断了*/#else#ifndef HAL_UART_ISR#if (defined ZAPP_P1) || (defined ZTOOL_P1)#define HAL_UART_ISR 1#elif (defined ZAPP_P2) || (defined ZTOOL_P2)#define HAL_UART_ISR 2#else#define HAL_UART_ISR 1#endif#endif#define HAL_UART_DMA 0#endif/*执行完上面的代码后,HAL_UART_ISR就被定义为0了*/// Used to set P2 priority - USART0 over USART1 if both are defined.#if ((HAL_UART_DMA == 1) || (HAL_UART_ISR == 1))#define HAL_UART_PRIPO 0x00#else#define HAL_UART_PRIPO 0x40#endif/*上述代码设置了两个串口的优先级,串口0大于串口1*//*这里的#else对应的是#if HAL_UART,意思就是如果串口使用,就将两种方式的宏都定义为0*/#else#define HAL_UART_DMA 0#define HAL_UART_ISR 0#endif/* USB is not used for CC2530 configuration */#define HAL_UART_USB 0上述代码的if和else对应的关系可能很难看出,可以用notepad打开源文件来查看对应关系。
Zstack协议栈SerialApp例程使用说明
Zstack协议栈SerialApp例程使用说明一、硬件准备1)将ZBDC51RM板安装到ZBDC51BB上,配套天线拧到ZBDC51RM板上,安装完成模块如下图所示。
2)使用交叉RS232电缆连接模块串口到PC机;电池盒装上两节5号1.5V电池,电池盒电缆连接到模块电池盒接口。
如果需要下载代码,将ccdebugger调试电缆连接到模块仿真器接口。
3)检查电池合是否拨到on位置,S3开关拨到Soc位置;S1开关拨到ON位置,模块上电开始工作。
二、编译SerialApp例程1)运行IAR 7.6.0以上版本,打开ZStack-CC2530-2.4.0-1.4.0\Projects\zstack \Utilities\SerialApp\CC2530DB\SerialApp.eww工程文件。
2)编译和下载协调器代码,如下图所示.1.选中编译项为coordinatorEB或者RouterEB;注:模块1和模块2这个配置项不一样,一个协议器,一个路由器。
2.右键单击serialApp-Coordinator项目,弹出右键菜单。
3.选择Rebuild All,完整编译代码。
3)使用IAR下载代码到模块。
如果代码生成没有出错,点击下图所示按钮将代码下载到模块,等待模块代码下载完成。
另一个模块也采用同样的方式烧写代码。
三、下载SerialApp代码如果不是从源代码编译下载到模块中,使用光盘上附带的hex文件,可以采用SmartRf Flash Programmer进行程序下载。
1)连接好CCDebugger和ZBDC51BB模块;运行SmartRF Flash Programmer程序。
2)选定需要的hex文件,进行程序下载,如果烧写成功会有提示信息。
3)用同样的方法烧写第二个模块代码,注意两上模块烧写的代码不能一样。
四、运行代码验证1)将已经下载了SerialApp程序的zigbee模块组装完成,用电缆串口和PC机。
ZSTACK串口读写的深度分析 DMA操作部分
HAL_ISR_FUNCTION( halUart1RxIsr, URX1_VECTOR ) HAL_ISR_FUNCTION( halUart0TxIsr, UTX0_VECTOR ) HAL_ISR_FUNCTION( halUart1TxIsr,t0 发送 //uart1 发送
U0BAUD = (config->baudRate == HAL_UART_BR_38400) ? 59 : 216; U0GCR = (config->baudRate == HAL_UART_BR_38400) ? 10 : 11; 这两个是真正定义波特率的地方,具体细节的寄存器定义同学们还是要看手册的 uart 部分哦。下图给 出了在 32MHz 频率下手册中的一波特率表:
代码比较多,我不一一列出,请自行比对代码。看代码,首先是 UART0 和 UART0 占用 P0 口的优先 级,UART0 最优先。之后根据是否使用 UART0 或 UART1 来初始化端口配置和 UART 工作模式配置,并 且为了防止片内 ADC 和 UART 抢 P0 口,还要禁止 ADC 用 RX 和 TX 口。实际上,我们做硬件的也不可 能糊涂到这两个口线同时使用。(TI 考虑的还是很全面的,赞一个!)。之后就是如果使用了 DMA 功能为 串口搞数据,就初始化 DMA 的一大套东西,不过值得注意的是这个协议栈只允许每一个时刻只能让 DMA 操作一个 UART。如果你想让两个 UART 都用 DMA 功能,那么恐怕 DMA 的 1,2 两个通道也要被 UART 使用了,如此太不厚道了,一共 5 个通道,被 UART 搞走了 4 个,哈哈。
为什么要这么做一个结构体呢?这个事情还是要从 CC2430 处理器 user guide 中 DMA 控制器操作说明 说起。我们先节选手册上关于 DMA 的几段描述:
zstack完整资料
\ZigBee\南京\cc2530模块资料(天线杆版本)\cc2530模块资料(天线杆版本)\相关的学习文档\Zstack OSAL详解.pdf\ZigBee\南京\cc2530模块资料(天线杆版本)\cc2530模块资料(天线杆版本)\相关的学习文档\zigbee技术实践教程.pdf\ZigBee\z-stack\Z-Stack_API.pdf配置cc2530的第2功能时,不需要配置方向寄存器,否则可能出错hal_key.c下的HalKeyConfig()函数中/* Rising/Falling edge configuratinn */HAL_KEY_JOY_MOVE_ICTL &= ~(HAL_KEY_JOY_MOVE_EDGEBIT); /* Clear the edge bit */ /* For falling edge, the bit must be set. */#if (HAL_KEY_JOY_MOVE_EDGE == HAL_KEY_FALLING_EDGE)HAL_KEY_JOY_MOVE_ICTL |= HAL_KEY_JOY_MOVE_EDGEBIT;#endif有错,应将HAL_KEY_JOY_MOVE_ICTL改为PICTL1ZigBee协议架构1.1ZigBee简介Zigbee是IEEE 802.15.4协议的代名词。
根据这个协议规定的技术是一种短距离、低功耗的无线通信技术。
这一名称来源于蜜蜂的八字舞,由于蜜蜂(bee)是靠飞翔和“嗡嗡”(zig)地抖动翅膀的“舞蹈”来与同伴传递花粉所在方位信息,也就是说蜜蜂依靠这样的方式构成了群体中的通信网络。
其特点是近距离、低复杂度、自组织、低功耗、低数据速率、低成本。
主要适合用于自动控制和远程控制领域,可以嵌入各种设备。
Zigbee是一种新兴的短距离、低速率、低功耗无线网络技术,它是一种介于无线标记技术和蓝牙之间的技术提案。
Z-Stack中串口发送接收的流程
Z-Stackxx串口发送接收的流程串口接收发送数据有两种方式,一种是中断的模式,另一种是DMA方式,这里主要以中断的方式,来看一下使用串口来发送,接收数据的整个流程。
这里以SerialApp例程为例子。
在mian函数中的调用HalDriverInit();函数,在函数中初始化串口,主要是配置管脚和DMA通道void HalDriverInit(void){.................................../* UART */#if (defined HAL_UART) && (HAL_UART == TRUE)HalUARTInit();#endif....................................}从程序中可以看出要想使用协议栈中串口,初始化串口必须定义HAL_UART 和HAL_UART TRUE 在hal_board_cfg.h文件中。
#ifndef HAL_UART#if (defined ZAPP_P1) || (defined ZAPP_P2) || (defined ZTOOL_P1) ||(defined ZTOOL_P2)#define HAL_UART TRUE#else#define HAL_UART FALSE#endif /* ZAPP, ZTOOL */#endif /* HAL_UART */然后在osal_start_system()开始系统后,会调用Hal_ProcessPoll()来读取时间和串口。
在CC2430的数据手册中有这样一段话。
Data reception on the UART is initiatedwhen a 1 is written to the UxCSR.RE bit The UART will then search for a valid start bit on the RXDx input pin and set the hardware.当有数据接收时,UxCSR.RE位将被置1,然后,UART将在RXDx的输入引脚上查找一个有效的开始位,当找到这个开始位时,将设置UxCSR.ACTIVE位为高电平。
Z-STACK按键
Z-STACK按键的使用总结#define HAL_KEY_SW_6_ENABLE// SW_6的IO端口#define HAL_KEY_SW_6_PORT P0//SW6接到IO端口的位数P0.1#define HAL_KEY_SW_6_BIT HAL_KEY_BIT1// SW_6的IO端口选择#define HAL_KEY_SW_6_SEL P0SEL// SW_6的IO端口方向#define HAL_KEY_SW_6_DIR P0DIR// SW_6的IO端口中断使能#define HAL_KEY_SW_6_IEN IEN1// SW_6的IO端口中断使能的掩码#define HAL_KEY_SW_6_IENBIT HAL_KEY_BIT5// SW_6的IO端口中断的边沿选择#define HAL_KEY_SW_6_EDGE HAL_KEY_RISING_EDGE // SW_6的IO端口边沿掩码#define HAL_KEY_SW_6_EDGEBIT HAL_KEY_BIT0// SW_6的IO端口总中断#define HAL_KEY_SW_6_ICTL PICTL// SW_6的IO端口总中断掩码#define HAL_KEY_SW_6_ICTLBIT HAL_KEY_BIT3// SW_6的IO端口中断标志位#define HAL_KEY_SW_6_PXIFG P0IFG按键主要使用的是IO来设置的,这里需要设置的参数主要有按键设置在哪个端口以及掩码、按键中断使能标志以及掩码、引起中断的上升沿还是下降沿以及掩码涉及的主要寄存器有PICTL端口输入中断控制IEN1端口0总中断使能IEN2 端口1和2总中断使能比如需要设置HAL_KEY_SW_6为P0.4为输入下降沿有效中断设置如下:#define HAL_KEY_SW_6_ENABLE#define HAL_KEY_SW_6_PORT P0#define HAL_KEY_SW_6_BIT HAL_KEY_BIT4#define HAL_KEY_SW_6_SEL P0SEL#define HAL_KEY_SW_6_DIR P0DIR#define HAL_KEY_SW_6_IEN IEN1#define HAL_KEY_SW_6_IENBIT HAL_KEY_BIT5#define HAL_KEY_SW_6_EDGE HAL_KEY_FALLING_EDGE#define HAL_KEY_SW_6_EDGEBIT HAL_KEY_BIT0#define HAL_KEY_SW_6_ICTL PICTL#define HAL_KEY_SW_6_ICTLBIT HAL_KEY_BIT4#define HAL_KEY_SW_6_PXIFG P0IFG比如需要设置HAL_KEY_SW_6为P2.1为输入上升沿有效中断设置如下:#define HAL_KEY_SW_6_ENABLE#define HAL_KEY_SW_6_PORT P2#define HAL_KEY_SW_6_BIT HAL_KEY_BIT4#define HAL_KEY_SW_6_SEL P2SEL#define HAL_KEY_SW_6_DIR P2DIR#define HAL_KEY_SW_6_IEN IEN2#define HAL_KEY_SW_6_IENBIT HAL_KEY_BIT1#define HAL_KEY_SW_6_EDGE HAL_KEY_RISING_EDGE#define HAL_KEY_SW_6_EDGEBIT HAL_KEY_BIT2#define HAL_KEY_SW_6_ICTL PICTL#define HAL_KEY_SW_6_ICTLBIT HAL_KEY_BIT5#define HAL_KEY_SW_6_PXIFG P2IFG这样设置后就可以正常使用KEY 中断。
zstack串口应用总结
zstack串口应用总结最近总是碰到很多人问我串口的问题,很多人会纠结于一些细节性的东西,刨根问底当然好,但在实际的开发过程中需要你会用,不可能给你那么的多的时间学那么多无关的东西,总之一句话:开发注重于框架的掌握,具体在开发中遇到的细节问题再拿出刨根问底的功夫出来,这样才会事半功倍。
(支持原创,如需转载,请注明地址:/litianping0709作者:叶雨荫城(阿雨))其实zstack的串口应用起来相当简单,由于时间关系,我对串口的应用只做一个简单的讲解,给大家一个框架,实际应用中大家自己酌情掌握,当然有错的话希望大家指正,只是个人理解。
在zstack中,串口应用主要有三种方式:(1)与zstack交互进行通信:需要考虑到系统通信的数据格式,这种应用一般更加侧重于与zstack交互。
举个例子,在协调器中我们需要利用PC给zstack发出命令需要其执行相应的命令时,这个时候我们只要在协调器的编译项加上ZTOOL_P1 MT_TASK两个选项即可,如果这个时候如果需要MT层和应用层进行交互处理用户数据(具体用户数据的格式在zstack中的串口文档中有定义,大家可以自行查看),就必须在应用层中加入case MT_SYS_APP_MSG: // Z-Architect Messages(具体为什么加这个如果还不清楚把zstack OSAL运行机制搞清楚之后再开发吧。
)这个时候才能串口发送的数据经过MT层处理后送到我们的应用层,这是接收过程,发送过程直接调用HalUARTWrite()函数即可。
(2)自己的串口应用,与zstack命令格式无关,但不想自己配置串口,想偷懒:这种情况下也很简单,与上述编译项不同的是,此时需要加入的编译项为:MT_TASK ZAPP_P1,当中的串口号根据实际情况而定,这个时候只要加入编译项其实就行了,在应用过程中如果想在应用层处理串口的数据,和上述情况类似,这时候需要在应用层中加入的东西有:#include "SPIMgr.h"头文件....#if defined (ZAPP_P1)SPIMgr_RegisterTaskID(SampleApp_TaskID);//在MT层注册SPIMgr_ZAppBufferLengthRegister(7); // BUFFER大小#endif.....case SPI_INCOMING_ZAPP_DATA:Bindnode_SerialMSGCB(MSGpkt);//自己的串口数据处理函数#if defined(ZAPP_P1)SPIMgr_AppFlowControl ( SPI_MGR_ZAPP_RX_READY );//流控制#endifbreak;......这是最主要的三步,完成上述添加,大家就可以使用串口了。
如何使用ZStack
2010-10-08 21:30如何使用ZStack——网络配置1.PAN ID 和Channel(f8wConfig.cfg)ZigBee协议使用一个14位的个域网标志符(PAN ID)来标识一个网络。
ZStack 允许用两种方式配置PAN ID,当ZDAPP_CONFIG_PAN_ID值不设置为0xFFFF时,那么设备建立或加入网络的PAN ID由ZDAPP_CONFIG_PAN_ID指定;如果设置ZDAPP_CONFIG_PAN_ID为0xFFFF,那么设备就将建立或加入一个“最优”的网络。
//-DZDAPP_CONFIG_PAN_ID=0xFFFF-DZDAPP_CONFIG_PAN_ID=0x2FFFIEEE 802.15.4/ZIGBEE规范在2.4G频段上规定了16各频道,用户可以通过选择DEFAULT_CHANLIST不同的值选择不同的频道,协议默认频道为0xB即0x00000800。
//-DDEFAULT_CHANLIST=0x04000000 // 26 - 0x1A//-DDEFAULT_CHANLIST=0x02000000 // 25 - 0x19-DDEFAULT_CHANLIST=0x01000000 // 24 - 0x18//-DDEFAULT_CHANLIST=0x00800000 // 23 - 0x17//-DDEFAULT_CHANLIST=0x00400000 // 22 - 0x16//-DDEFAULT_CHANLIST=0x00200000 // 21 - 0x15//-DDEFAULT_CHANLIST=0x00100000 // 20 - 0x14//-DDEFAULT_CHANLIST=0x00080000 // 19 - 0x13//-DDEFAULT_CHANLIST=0x00040000 // 18 - 0x12//-DDEFAULT_CHANLIST=0x00020000 // 17 - 0x11//-DDEFAULT_CHANLIST=0x00010000 // 16 - 0x10//-DDEFAULT_CHANLIST=0x00008000 // 15 - 0x0F//-DDEFAULT_CHANLIST=0x00004000 // 14 - 0x0E//-DDEFAULT_CHANLIST=0x00002000 // 13 - 0x0D//-DDEFAULT_CHANLIST=0x00001000 // 12 - 0x0C//-DDEFAULT_CHANLIST=0x00000800 // 11 - 0x0B2.网络结构(nwk_globals.h,nwk_globals.c)STACK_PROFILE_ID定义为NETWORK_SPECIFIC、 HOME_CONTROLS、BUILDING_AUTOMATION、GENERIC_STAR、GENERIC_TREE中的一个,默认为HOME_CONTROLS,并据此设置MAX_NODE_DEPTH、NWK_MODE等,具体如下:#define STACK_PROFILE_ID HOME_CONTROLS#if ( STACK_PROFILE_ID == HOME_CONTROLS )#define MAX_NODE_DEPTH 5#define NWK_MODE NWK_MODE_MESH#define SECURITY_MODE SECURITY_RESIDENTIAL#if ( SECURE != 0 )#define USE_NWK_SECURITY 1 // true or false#define SECURITY_LEVEL 5#else#define USE_NWK_SECURITY 0 // true or false#define SECURITY_LEVEL 0#endif网络最大设备数设定:#if !defined( NWK_MAX_DEVICE_LIST )#define NWK_MAX_DEVICE_LIST 20 // Maximum number of devices in the // Assoc/Device list.#endif路由器和终端设备数设定:#if defined ( RTR_NWK )// change this if using a different stack profile...// Cskip arrayuint16 *Cskip;#if ( STACK_PROFILE_ID == HOME_CONTROLS )byte CskipRtrs[MAX_NODE_DEPTH+1] = {6,6,6,6,6,0};byte CskipChldrn[MAX_NODE_DEPTH+1] = {20,20,20,20,20,0};#elif ( STACK_PROFILE_ID == GENERIC_STAR )byte CskipRtrs[MAX_NODE_DEPTH+1] = {5,5,5,5,5,0};byte CskipChldrn[MAX_NODE_DEPTH+1] = {5,5,5,5,5,0};#elif ( STACK_PROFILE_ID == NETWORK_SPECIFIC )byte CskipRtrs[MAX_NODE_DEPTH+1] = {5,5,5,5,5,0};byte CskipChldrn[MAX_NODE_DEPTH+1] = {5,5,5,5,5,0};#endif // STACK_PROFILE_ID#endif // RTR_NWK其中CskipRtrs和CskipChldrn分别为每一级的最大路由器数和最大节点数,前者是后者的子集。
基于Z-Stack的串口通信.ppt
灯的亮灭与闪烁。
战略性信息产业教育服务提供商
联世界 育未来——创新物联教育
目
录
一、实训目的
二、实训内容 三、实训原理 四、实训步骤
战略性信息产业教育服务提供商
联世界 育未来——创新物联教育
实训内容
在用户应用层任务处理函数 SampleApp_ProcessEvent 中实 现每隔5秒向串口发送“Hello NEWLab!”;并增加一个应用层新任 务,实现由PC 端发送字符“1”和“ 2” 控制ZigBee模块的LED2 灯的
实训原理
(1) 第5)行代码HAL_ENTER_CRITICAL_SECTION(intSta te)函数的作用是把原先中断状态EA赋给X,然后关中断;以便后面 可以恢复原先的中断状态。目的是为了在访问共享变量时,保证变 量不被其它任务同时访问。
(2) 第6)行代码HAL_EXIT_CRITICAL_SECTION(intState)
tasksEvents[tasksCnt] SampleApp_ProcessEvent tasksArr[tasksCnt]
. . .
. . .
tasksEvents[2] tasksEvents[1] tasksEv ents tasksEvents[0] 事件表
Hal_ProcessEve nt Nwk_event_loo p macEventLoop tasksArr[ ] 函数表
数组tasksArr[ ]的每个元素都是函数的地址(用函数名表示函数
的地址),即该数组的元素都是事件处理函数的函数名,如第16行, SampleApp_ProcessEvent就是“通用应用任务事件处理函数名”, 该函数在SampleApp.c文件中被定义了。
基于Z-Stack的串口透传
基于Z-Stack的串口透传
目录
一、实训目的 二、实训内容 三、实训原理 四、实训步骤
实训目的
通过实训,对Z-Stack有更进一步的了解,了解Z-Stack网络 节点的类型和功能,能实现模块之间无线串口通信。
目录
一、实训目的 二、实训内容 三、实训原理 四、实训步骤
实训内容
电脑A与电脑B分别连接一块ZigBee模块,再用串口收发信息, 实现串口透传。
目录
一、实训目的 二、实训内容 三、实训原理 四、实训步骤
实训步骤
第三步,编写协调器程序。 结合实训10与实训11中的协调器程序,在此基础上进行修改,由 于代码较多,在此只列出关键部分代码。 第四步,编写终端节点程序。 结合实训10的终端节点程序,在此基础上进行修改,串口初始化、 消息处理等与协调器程序一样,只需要将网络通信方式设为单播方式 ( my_DstAddr.addrMode=(afAddrMode_t)Addr16Bit ) , 短 地 址 设 为 : 0x0000()。
实训原理
参照实训10、实训11等内容。
பைடு நூலகம்
目录
一、实训目的 二、实训内容 三、实训原理 四、实训步骤
实训步骤
第一步,打开Z-Stack的SampleApp.eww工程。 具体参考实训10的操作。 第二步,修改Coordinator.h 在文件中增加以下代码: //应用事件 #define SAMPLEAPP_SEND_PERIODIC_MSG_EVT 0x0001 #define SAMPLEAPP_READ_PERIODIC_MSG_EVT 0x0002 #define SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT 50 00 // 每5秒一次
Z-STACK问题之串口结构(转载)
Z-STACK问题之串口结构(转载)(2010-12-09 09:43)分类:ZigBee 技术学习typedefstruct{uint8 *rxBuf;//接收缓存uint8 rxHead;//头uint8 rxTail;//尾uint8 rxMax;//接收最大长度uint8 rxCnt;//计数uint8 rxTick;//时间uint8 rxHigh;//高位uint8 *txBuf;#if HAL_UART_BIG_TX_BUFuint16 txHead;uint16 txTail;uint16 txMax;uint16 txCnt;#elseuint8 txHead;uint8 txTail;uint8 txMax;uint8 txCnt;#endifuint8 txTick;uint8 flag;//标志位halUARTCBack_trxCB;} uartCfg_t;有个朋友问我上面的问题,说句老实话,我可是第一次见这个东东,拿到手之后比我那朋友还迷糊,那位朋友至少还知道大概是什么功能,仅仅是不清楚每个参数的具体含义和功能。
为了解决这个问题,我可是遍寻名家,最终结果是人家也不是很清楚,因为平常大家只管用,哪管那么多这些具体细节?没办法,我只有自己解决了,希望我的努力能给大家一点点启示!首先说说这个结构的应用范畴,它是直接面向串口的应用层,也就是与客户接触的还是比较紧密的一个结构,一般是在串口接收数据和发送数据的时候使用。
而串口有两种方式,一种是普通的串口,一种是DMA方式。
这里我只针对普通串口来分析这个结构。
首先来看看这个结构在什么地方用到了?static void pollDMA( uartCfg_t *cfg )static void pollISR( uartCfg_t *cfg )这两个函数直接就用到了这个结构作为参数,应该说是联系最紧密的了,是我们重点剖析的对象了,但是这里不看DMA,因为这个俺很外行----------哈哈!!!!uint16 HalUARTRead( uint8 port, uint8 *buf, uint16 len )uint8 HalUARTOpen( uint8 port, halUARTCfg_t *config )void HalUARTClose( uint8 port )void HalUARTPoll( void )uint16 Hal_UART_RxBufLen( uint8 port )uint16 HalUARTWrite( uint8 port, uint8 *buf, uint16 len )这几个函数都在其中定义了这个结构的变量在使用,所以我们也需要关注。
zstack 串口使用指南
zstack 串口使用指南ZStack 串口使用指南1、简介本文档旨在介绍如何在ZStack开发框架中使用串口功能。
通过串口,可以实现与外部设备进行数据交互,如与传感器通信、与PC 机通信等。
本文将从串口的基本概念开始介绍,然后详细说明在ZStack中如何配置和使用串口功能。
2、串口基础知识2.1 串口的概念串口是一种通过对数据进行串行传输的方式来实现数据通信的接口。
它对数据进行分帧、传输、接收和解析,是常用的外部设备与主控进行通信的方式之一。
2.2 串口的工作原理串口通信是通过发送和接收两个方向上的信号来实现的。
发送端将数据进行串行化处理,然后通过串口线依次发送给接收端。
接收端接收到数据后,再进行解析和处理。
3、ZStack中的串口配置3.1 串口引脚配置在ZStack开发框架中,需要根据具体的硬件平台来配置串口引脚。
一般情况下,需要连接UART芯片与主控芯片。
3.2 串口初始化配置在ZStack中,可以通过调用相关API来进行串口的初始化配置。
具体的配置包括波特率、数据位、停止位、校验位等。
可以根据业务需求进行相应的配置。
4、串口数据收发4.1 数据发送在ZStack中,可以使用相关API来实现串口数据的发送。
可以将需要发送的数据通过API传递给串口发送缓冲区,然后通过调用相应的API来发送数据。
4.2 数据接收在ZStack中,可以使用相关API来实现串口数据的接收。
通过配置串口的接收中断,并设置接收缓冲区,当接收到数据时,会触发相应的中断,通过API可以读取到接收到的数据。
5、附件:示例代码本文档附带一个示例代码,展示了在ZStack中使用串口的基本操作。
可以通过参考示例代码来加深理解和实践。
6、法律名词及注释6.1 波特率:串口通信中的数据传输速率,表示每秒传输的数据bit数。
6.2 数据位:表示每个字节中有效数据的位数。
6.3 停止位:表示每个字节结束后的空闲时间,用于区分不同字节。
如何在Zstack中使用串口
//禁止硬件流控,如果你的串口只有 RXD,TXD 和 GND 三条线,必须这么做;
uartConfig.flowControlThreshold = MT_UART_DEFAULT_THRESHOLD;
uartConfig.rx.maxBufSize
= MT_UART_DEFAULT_MAX_RX_BUFF;
case ZDO_CB_MSG: GenericApp_ProcessZDOMsgs( (zdoIncomingMsg_t *)MSGpkt ); break;
case KEY_CHANGE: GenericApp_HandleKeys( ((keyChange_t *)MSGpkt)->state,
} 第二个函数
void MT_UartRegisterTaskID( byte taskID ) {
App_TaskID = taskID; } /*这个函数很简单,做什么用?无非就是注册一个处理串口数据的任务。App_TaskID 是什么? 这个也放一放,一会儿说。*/
第三个函数
void MT_UartProcessZToolData ( uint8 port, uint8 event ) /*这个函数很长,具体说来就是把串口发来的数据包进行打包,校验,生成一个消息,发给 处理数据包的任务。如果你看过 MT 的文档,应该知道如果用 ZTOOL 通过串口来沟通协议 栈,那么发过来的串口数据具有以下格式:
} 再看一下 MT_UartRegisterTaskID(GenericApp_TaskID): void MT_UartRegisterTaskID( byte taskID ) {
App_TaskID = taskID; } /*回头想想,前面的 MT_UartProcessZToolData 中不是有一个 osal_msg_send( App_TaskID, (byte *)pMsg );吗?这样,osal_msg_send 将把消息发给 GenericApp_TaskID*/
从零开始学习Zstack之9
从零开始学习Z-Stack之9接到昨天的继续忽悠,话说:2、SimpleApp“这个例子我基本跑通了,可是鉴于时间的关系,没有来得及打字了,所以就留到下一次了,时间真是如流水啊-------------------快!….”这个例子里面有两个演示:一个是灯与开关的控制实验,一个温度传感器实验。
咱一个个来,不忙。
灯与开关实验在这个例子中灯对应的工程名字为:SimpleControllerDB;开关对应:SimpleSwitchDB。
严重需要注意的地方,这里选用的是DB。
因为从从零开始学习Z-Stack之1上可以看到DB与EB的区别,而这里用DB的硬件就足以应付。
编译下载我就不继续罗嗦了。
咱关心的几个问题不外乎就是表演过程和表演结果,以及初步看看为什么会有这样的结果产生,当然就得从程序上简单了解下。
首先打开Controller(也就是灯设备)的电源,那么LED2就会不停的闪烁,这个时候是设备正在初始化,让您选择设备以哪种类型启动,从程序可以看出:if ( keys & HAL_KEY_SW_1 ){if ( myAppState == APP_INIT ){// In the init state, keys are used to indicate the logical mode.// Key 1 starts device as a coordinatorzb_ReadConfiguration( ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType ); if ( logicalType != ZG_DEVICETYPE_ENDDEVICE ){logicalType = ZG_DEVICETYPE_COORDINATOR;zb_WriteConfiguration(ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType); }// Do more configuration if necessary and then restart device with auto-start bit set// write endpoint to simple desc...dont pass it in start req..then resetzb_ReadConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions ); startOptions = ZCD_STARTOPT_AUTO_START;zb_WriteConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions ); zb_SystemReset();}如果按下S1(UP),那么作为协调器启动。
Z-stack串口的DMA模式简介
协议栈串口的DMA模式以下修改皆基于ZStack-CC2530-2.3.0-1.4.0版本:1.串口的初始化根据底板的引脚分配,我们用的是串口的UART0的Alt2方式。
需要修改的地方:(1)将option里预编译选项,ZTOOL_P1改成ZTOOL_P2,使#define HAL_UART_DMA 2为真。
(2)_hal_uart_dma.c的HalUARTInitDMA函数是对UART引脚以及寄存器的操作,修改如下:在HAL_UART_DMA == 2情况下的//#define HAL_UART_Px_RTS 0x20 // Peripheral I/O Select for RTS.//#define HAL_UART_Px_CTS 0x10 // Peripheral I/O Select for CTS.//屏蔽上两句,是因为该底板没有分配RTS和CTS的引脚#define HAL_UART_PERCFG_BIT 0x01 // USART0 on P1, Alt-2; so set this bit. //这里是将串口设置为UART0的Alt2方式#define HAL_UART_Px_RX_TX 0x30 // Peripheral I/O Select for Rx/Tx.//此处设置RX,TX引脚为P1_4,P1_5(3)在osal_init_system里osalInitTasks下MT_TaskInit的MT_UartInit(),是对串口的配置但要将uartConfig.flowControl = MT_UART_DEFAULT_OVERFLOW;改为uartConfig.flowControl = FALSE;协议栈默认的流控制是TRUE。
2. 串口的事件处理//系统主循环void osal_start_system( void ){……Hal_ProcessPoll(); // 串口与定时器轮询函数……}//定时器与串口轮询函数void Hal_ProcessPoll (){…….#if (defined HAL_UART) && (HAL_UART == TRUE)HalUARTPoll();#endif……}//串口轮询函数void HalUARTPoll( void ){#if HAL_UART_DMAHalUARTPollDMA();//根据DMA的方式选择DMA的轮询方式#endif……}//DMA串口轮询函数static void HalUARTPollDMA(void){……//以上是检查rxbuf里是否有数据写入,并对uartDMACfg_t dmaCfg结构体赋值if (evt && (dmaCfg.uartCB != NULL)){dmaCfg.uartCB(HAL_UART_DMA-1, evt);}//执行回调函数}注:回调函数dmaCfg.uartCB的初始化在HalUARTOpenDMA的第一句代码:dmaCfg.uartCB = config ->callBackFunc;而halUARTCfg_t uartConfig结构体的初始化在MT包里的MT_UART.c的MT_UartInit ()中1)typedef struct{bool configured;uint8 baudRate;bool flowControl;uint16 flowControlThreshold;uint8 idleTimeout;halUARTBufControl_t rx;halUARTBufControl_t tx;bool intEnable;uint32 rxChRvdTime;halUARTCBack_t callBackFunc;}halUARTCfg_t;该结构体是UART的配置结构体,设置UART的波特率,流控制,回调函数等等。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
5、uint8 rxCnt ;
static void pollISR( uartCfg_t *cfg )
{
uint8 cnt = UART_RX_AVAIL( cfg );
static void pollISR( uartCfg_t *cfg )
这两个函数直接就用到了这个结构作为参数,应该说是联系最紧密的了,是我们重点剖析的对象了,但是这里不看DMA,因为这个俺很外行----------哈哈!!!!
uint16 HalUARTRead( uint8 port, uint8 *buf, uint16 len )
首先说说这个结构的应用范畴,它是直接面向串口的应用层,也就是与客户接触的还是比较紧密的一个结构,一般是在串口接收数据和发送数据的时候使用。而串口有两种方式,一种是普通的串口,一种是DMA方式。这里我只针对普通串口来分析这个结构。
首先来看看这个结构在什么地方用到了?
static void pollDMA( uartCfg_t *cfg )
4、uint8 rxMax;//接收最大长度
这个我想没必要多做解释,这里只看看它究竟有多大,因为这个量的赋值非常隐蔽,俺找了好久才功夫不负有心人!!!
首先在打开串口第函数中有:
cfg->rxMax = config->rx.maxBufSize;
其次在void SPIMgr_Init ()函数中有:
其实从上面那个中断函数就已经把这个参数的功能体现的淋漓尽致了:
就是串口接收数据,这个参数始终指向像一个参数被存放到rxBuf的位置。因为硬件串口缓存器U0DBUF只能存放一个字节,如果不及时把这个接收到的转移出去,那么就会被下一个到来的字节覆盖掉,所以rxHead变量就指向了这个存放的地址,当然是基于定义的rxBuf存储空间。相当于一个数组赋值,那么必然有个变量会指向该数组的下一个赋值的参数,当然这个变量的最终值也能在一定程度上体现这个被赋值数组的大小。所以rxHead在这里起到了类似的作用,而if ( cfg0->rxHead == cfg0->rxMax )这一句判断也说明的很清楚,一旦这个计数达到了定义的最大接收数量,也就是说已经把rxBuf存储空间占满了,那么就不能在继续存放了,否则存放的位置就未知,而且有可能造成程序中其他变量的损坏,那么这个时候如果串口还有数据怎么办?那就需要把rxBuf清空在接收了,否则就会丢失数据。
cfg->rxCnt = cnt;
}
/* It is necessary to stop Rx flow in advance of a full Rx buffer because
* bytes can keep coming while sending H/W fifo flushes.
typedef struct
{
uint8 *rxBuf;//接收缓存
uint8 rxHead;//头
uint8 rxTail;//尾
uint8 rxMax;//接收最大长度
uint8 rxCnt;//计数
uint8 rxTick;//时间
uint8 rxHigh;//高位
uint8 *txBuf;
从这个函数中还能看出两个问题:
rxHead是否用作了串口接收计数,而rxMax代表最大的接收数据长度。
2、uint8 rxHead
字面理解为接收头,但是上面已经提到了似乎起到了串口接收计数的功能。那下面就来看看它到底有什么意义。
cfg->rxHead = cfg->rxTail = 0;
在打开串口中有这么赋值,把它初始化为0.
if ( !(cfg->flag & UART_CFG_RXF) )
{
// If anything received, reset the Rx idle timer.
if ( cfg->rxCnt != cnt )
{
cfg->rxTick = HAL_UART_RX_IDLE;
{
cfg0->rxBuf[cfg0->rxHead] = U0DBUF;
if ( cfg0->rxHead == cfgd = 0;
}
else
{
cfg0->rxHead++;
}
}
这个是串口0中断函数:其中cfg0->rxBuf[cfg0->rxHead] = U0DBUF,显然是把U0DBUF中的数据转移到存储区去。
uint16 HalUARTWrite( uint8 port, uint8 *buf, uint16 len )
这几个函数都在其中定义了这个结构的变量在使用,所以我们也需要关注。
可以看出,这个结构与串口的应用,也就是数据的接收和发送有关,而与串口的初始化灯没有关系。所以这里排除串口初始化的任何可能。
{
cfg->rxTail = 0;
}
else
{
cfg->rxTail++;
}
cnt++;
}
这里是在uint16 HalUARTRead( uint8 port, uint8 *buf, uint16 len )函数中调用的,实际上把rxBuf空间的数据读走,然后rxBuf可以继续串口数据的接收了。可以看到*buf++ = cfg->rxBuf[cfg->rxTail]这个是在转移数据,而转移多少的计数是以rxTail来计数的。一旦计数达到rxMax,那么该计数归0,因为rxMax定义了rxBuf的最大的数据量。
uint8 cnt = UART_RX_AVAIL( cfg );这个函数的第一句,而:
#define UART_RX_AVAIL( cfg ) \
( (cfg->rxHead >= cfg->rxTail) ? (cfg->rxHead - cfg->rxTail) : \
(cfg->rxMax - cfg->rxTail + cfg->rxHead +1 ) )
我的理解是UART_RX_AVAIL是指明串口缓存区rxBuf还剩多少有用的数据,也就是没有被取走的数据。首先从字面理解avail为“效用”的意思,那么扩展下为available,那么意思就是“有用的”“有空的”,呵呵!只有理解其实也很有意思哈。
再从后面的判断语句,cfg->rxHead - cfg->rxTail,由于有上面的讲解,理解这个就很容易了,有的数据数量-已经取走的数据数量,那么就省还有多少各有用的数据量。
3、uint8 rxTail;
这个变量就与上面提到的清空rxBuf密切相关了。
while ( (cfg->rxTail != cfg->rxHead) && (cnt < len) )
{
*buf++ = cfg->rxBuf[cfg->rxTail];
if ( cfg->rxTail == cfg->rxMax )
#if HAL_UART_BIG_TX_BUF
uint16 txHead;
uint16 txTail;
uint16 txMax;
uint16 txCnt;
#else
uint8 txHead;
uint8 txTail;
uint8 txMax;
uint8 txCnt;
#endif
uint8 txTick;
为了更明确每个参数的意思,所以一个个来分析。这个是逆向解决问题的方法,正向思维就是先把每个函数都看完看明白,自然也就知道了。但是我哪有那能耐和功夫?所以就偷懒从后面出发!!!
1、uint8 *rxBuf;//接收缓存
这个参数我觉得没必要太多解释,就是串口接收缓存。直观理解就是串口接收放数据的地方,体现这个含义最明显的地方就是串口接收函数了:
uint8 HalUARTOpen( uint8 port, halUARTCfg_t *config )
void HalUARTClose( uint8 port )
void HalUARTPoll( void )
uint16 Hal_UART_RxBufLen( uint8 port )
其实仔细想想,这两个参数还是与串口的头和尾有关的。头又名开始,串口接收数据开始存放数据的指向;尾又名结束,是把串口数据取走用作他用的指向。rxHead=0,标示串口接收数据新的起点,新的开始;而rxTail=0,标示把串口接收到的数据全部取走用作他用,------结束。体现了串口数据从接收到被使用的整个过程。
uartConfig.rx.maxBufSize = SPI_MGR_DEFAULT_MAX_RX_BUFF;
在次有如下定义:
#define SPI_MGR_DEFAULT_MAX_RX_BUFF SPI_RX_BUFF_MAX
最后才找到其最终的东西:
#define SPI_RX_BUFF_MAX 128
cfg->rxBuf = osal_mem_alloc( cfg->rxMax+1 );
这里是在打开串口函数中的语句,就是为接收缓存分配存储空间。
osal_mem_free( cfg->rxBuf );