




已阅读5页,还剩2页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
z-stack问题之串口结构(转载) (2010-12-09 09:43) 分类: zigbee 技术学习 typedef structuint8 *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_t rxcb; 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 )这几个函数都在其中定义了这个结构的变量在使用,所以我们也需要关注。可以看出,这个结构与串口的应用,也就是数据的接收和发送有关,而与串口的初始化灯没有关系。所以这里排除串口初始化的任何可能。还要来关系两个全局变量的定义:#if hal_uart_0_enablestatic uartcfg_t *cfg0;#endif#if hal_uart_1_enablestatic uartcfg_t *cfg1;#endif可以看出,串口0对应变量cfg0,串口1对应变量cfg1。这两个变量的变化使我们关注的重点,因为只要了解其变化过程和使用方法,基本上就能摸清每个参数的意义了。为了更明确每个参数的意思,所以一个个来分析。这个是逆向解决问题的方法,正向思维就是先把每个函数都看完看明白,自然也就知道了。但是我哪有那能耐和功夫?所以就偷懒从后面出发!1、uint8 *rxbuf;/接收缓存这个参数我觉得没必要太多解释,就是串口接收缓存。直观理解就是串口接收放数据的地方,体现这个含义最明显的地方就是串口接收函数了:cfg-rxbuf = osal_mem_alloc( cfg-rxmax+1 );这里是在打开串口函数中的语句,就是为接收缓存分配存储空间。osal_mem_free( cfg-rxbuf );这个函数是在关闭串口函数中,就是释放存储空间。hal_isr_function( haluart0rxisr, urx0_vector )cfg0-rxbufcfg0-rxhead = u0dbuf;if ( cfg0-rxhead = cfg0-rxmax )cfg0-rxhead = 0;elsecfg0-rxhead+;这个是串口0中断函数:其中cfg0-rxbufcfg0-rxhead = u0dbuf,显然是把u0dbuf中的数据转移到存储区去。从这个函数中还能看出两个问题:rxhead是否用作了串口接收计数,而rxmax代表最大的接收数据长度。2、uint8 rxhead字面理解为接收头,但是上面已经提到了似乎起到了串口接收计数的功能。那下面就来看看它到底有什么意义。cfg-rxhead = cfg-rxtail = 0;在打开串口中有这么赋值,把它初始化为0.其实从上面那个中断函数就已经把这个参数的功能体现的淋漓尽致了:就是串口接收数据,这个参数始终指向像一个参数被存放到rxbuf的位置。因为硬件串口缓存器u0dbuf只能存放一个字节,如果不及时把这个接收到的转移出去,那么就会被下一个到来的字节覆盖掉,所以rxhead变量就指向了这个存放的地址,当然是基于定义的rxbuf存储空间。相当于一个数组赋值,那么必然有个变量会指向该数组的下一个赋值的参数,当然这个变量的最终值也能在一定程度上体现这个被赋值数组的大小。所以rxhead在这里起到了类似的作用,而if ( cfg0-rxhead = cfg0-rxmax )这一句判断也说明的很清楚,一旦这个计数达到了定义的最大接收数量,也就是说已经把rxbuf存储空间占满了,那么就不能在继续存放了,否则存放的位置就未知,而且有可能造成程序中其他变量的损坏,那么这个时候如果串口还有数据怎么办?那就需要把rxbuf清空在接收了,否则就会丢失数据。3、uint8 rxtail;这个变量就与上面提到的清空rxbuf密切相关了。while ( (cfg-rxtail != cfg-rxhead) & (cnt rxbufcfg-rxtail;if ( cfg-rxtail = cfg-rxmax )cfg-rxtail = 0;elsecfg-rxtail+;cnt+;这里是在uint16 haluartread( uint8 port, uint8 *buf, uint16 len )函数中调用的,实际上把rxbuf空间的数据读走,然后rxbuf可以继续串口数据的接收了。可以看到*buf+ = cfg-rxbufcfg-rxtail这个是在转移数据,而转移多少的计数是以rxtail来计数的。一旦计数达到rxmax,那么该计数归0,因为rxmax定义了rxbuf的最大的数据量。这里需要强调一点:rxtail和rxhead的区别。我第一眼看到这个两个变量的反应是:rxhead为串口数据串接收的头,而rxtail为串口数据串接收的尾(结束),因为这样理解符合我们平常编写串口通信协议习惯,有头有尾。但是仔细看了只有,虽然也是头与尾的概念,但是却不应该这么理解。rxtail和rxhead应该是针对rxbuf来说的。rxhead是往rxbuf装数据的计数,而rxtail是从rxbuf取走数据的计数。希望这个一定要注意。所以我们就不难理解:rxhead是在串口接收中断的时候强调使用,而rxtail是在haluartread函数中使用了。这里还需要注意一点点,haluartread并不是读取uxbuf数据,而是读取rxbuf中数据。其实仔细想想,这两个参数还是与串口的头和尾有关的。头又名开始,串口接收数据开始存放数据的指向;尾又名结束,是把串口数据取走用作他用的指向。 rxhead=0,标示串口接收数据新的起点,新的开始;而rxtail=0,标示把串口接收到的数据全部取走用作他用,-结束。体现了串口数据从接收到被使用的整个过程。4、uint8 rxmax;/接收最大长度这个我想没必要多做解释,这里只看看它究竟有多大,因为这个量的赋值非常隐蔽,俺找了好久才功夫不负有心人!首先在打开串口第函数中有:cfg-rxmax = config-rx.maxbufsize;其次在void spimgr_init ()函数中有: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还是藏的很隐蔽就是了,呵呵!关于这个128我是做个实验的,在串口互发的实验也是定义的128.多了就会丢掉!这个下次有机会在说。5、uint8 rxcnt ;static void pollisr( uartcfg_t *cfg )uint8 cnt = uart_rx_avail( cfg );if ( !(cfg-flag & uart_cfg_rxf) )/ if anything received, reset the rx idle timer.if ( cfg-rxcnt != cnt )cfg-rxtick = hal_uart_rx_idle;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.*/if ( cfg-rxcnt = (cfg-rxmax - safe_rx_min) )rx_stop_flow( cfg );就这个函数使用这个参数最典型了。关心的第一句不if ( cfg-rxcnt != cnt )一开始就与cnt变量有关系,而且更加过分的是在里面直接cfg-rxcnt = cnt,所以不得不关系下cnt了。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,由于有上面的讲解,理解这个就很容易了,有的数据数量-已经取走的数据数量,那么就省还有多少各有用的数据量。而cfg-rxmax - cfg-rxtail + cfg-rxhead +1理解就需要转个弯了,因为此时cfg-rxhead cfg-rxtail,那么什么情况下才满足这种条件呢,只有一种情况,rxhead已经是第二轮接收计数了,而rxtail还在上一轮取数。cfg-rxmax - cfg-rxtail,也就是第一轮把rxbuf填满的数据取走cfg-rxtail,那么就是第一轮剩下又有的数据,那么在+ cfg-rxhead这个,就是加上cfg-rxhead第二轮接收的数据,至于后面+1的理解为cfg-rxbuf = osal_mem_alloc( cfg-rxmax+1),分配存储空间本来就比rxmax多分了一个。-这里我仍然有疑惑,谁有深刻的理解欢迎交流!而if ( cfg-rxcnt = (cfg-rxmax - safe_rx_min) )这里理解就更微妙了,表明接收缓存空间已经满了,所以下面就rx_stop_flow( cfg ); #define rx_stop_flow( cfg ) if ( !(cfg-flag & uart_cfg_u1f) ) rx0_flow_off; else rx1_flow_off; if ( cfg-flag & uart_cfg_dma ) cfg-rxtick = dma_rx_dly; cfg-flag |= uart_cfg_rxf; 可以看出通过硬件流控制停止了接收,而置位cfg-flag为uart_cfg_rxf。至于cfg-rxmax - safe_rx_min的理解才是这里的精妙之处。#define safe_rx_min 48定义了每次串口操作处理间隔串口最多能接收多少字节数据。因为必须把这个空间预留充足,否则在非处理间隔期间就有可能覆盖以前的数据,关于这个的理解现在还比较困难,我想经过后面的叙述会豁然开朗。6、uint8 rxtick;/时间cfg-rxtick = hal_uart_rx_idle;#define hal_uart_rx_idle (6 * rx_msecs_to_ticks)#define rx_msecs_to_ticks 33所以cfg-rxtick=198,也就是差不多200ms才处理一次pollisr这个函数。这里我可以论证下上面提到的#define safe_rx_min 48因为cc2430串口波特率为38400bps下,一个字节需要事件约为:4.16ms,那么198/4.16等于47.6(这里我个人注释:(198ms是中断处理数据的间隔,这期间串口是不断接收数据,那在这期间能接收到多少数据呢?为47.6字节,因此要保证至少48字节的存储空间)),约为48.所以这也就是上面定义这个48的原因。因为 cfg-rxtick定义了多久处理一次串口缓存区,而为了保证串口缓冲区不被新的数据覆盖,那么在这个间隔期间就必须保证大于48字节存储空间空闲。至于这个时间具体涉及到休眠定时器的使用,这个我就不大清楚了。7、uint8 rxhigh;cfg-rxhigh = config-rx.maxbufsize - config-flowcontrolthreshold;定义了rxhigh的大小。else if ( cfg-rxhigh & (cfg-rxhead = cfg-rxhigh) )evt = hal_uart_rx_about_full;指出了,rxhigh的用法,就是一旦接收的数据超过rxhigh就触发hal_uart_rx_about_full事件。uartconfig.flowcontrolthreshold = spi_mgr_default_threshold;#define spi_mgr_default_threshold spi_threshold#define spi_threshold 48最终我们可以看到cfg-rxhigh=128-48=80.也就是说只要接收的数据超过80就触发hal_uart_rx_about_full事件。那么来看看这个事件是干啥用的:if (event & (hal_uart_rx_full | hal_uart_rx_about_full | hal_uart_rx_timeout)while (hal_uart_rxbuflen(spi_mgr_default_port)haluartread (spi_mgr_default_port, &ch, 1);.基本上就是
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年中国个人护理用小核菌胶行业市场分析及投资价值评估前景预测报告
- 2025年新能源汽车换电模式与电池回收利用技术创新报告
- 第1课 回收利用闲置衣物说课稿-2025-2026学年小学劳动五年级下册川民版《劳动教育》
- 七年级信息技术上册 第一章 第一节 收集身边的信息说课稿
- 第4章 植物体的结构层次教学设计2023-2024学年北师大版生物七年级上册
- 四年级信息技术上册 第三单元 小小编辑 第12课 图文并茂美文章说课稿4 浙江摄影版
- 农业绿色发展政策支持与农业生物防治技术新应用报告
- 3《我多想去看看》(教案)-统编版(2024)语文一年级下册
- 2025年中国高纯三氟氯乙烯(CTFE)行业市场分析及投资价值评估前景预测报告
- 2025年中国高纯锰硫酸盐行业市场分析及投资价值评估前景预测报告
- 2025年河南省文化旅游投资集团有限公司权属企业社会招聘52人笔试参考题库附答案解析
- 2025云南昆明元朔建设发展有限公司第一批收费员招聘20人考试参考试题及答案解析
- 微生物检验技能-细菌的生化试验
- 导数的应用-函数的零点问题(5题型分类)-2025年高考数学一轮复习(解析版)
- 第十中学八年级上学期语文10月月考试卷(含答案)
- 江苏省南京市联合体2024-2025学年八年级上学期期中考试语文试题含答案
- 有限责任干股持有者分红权利具体合同版
- 山东版离婚协议书模板
- 西南大学研究生开题报告(模板)
- 物业公司安全生产检查表
- 视觉slam介绍教学课件
评论
0/150
提交评论