一、分析内容:

   这次主要分析:从上层的AMSender.send发送packet到Xmac将packet发送出去的流程。

二、

  找到upma/apps/tests/TestXmac/SendingC$SendTimer$startPeriodic事件,代码如下:  

    event void SendTimer.fired(){if(sends){call Leds.led2On();call AMSender.send(AM_BROADCAST_ADDR, &packet, 2 * sizeof(uint8_t));        }}

  call AMSender.send(AM_BROADCAST_ADDR, &packet, 2 * sizeof(uint8_t));的实现代码如下(/opt/tinyos-2.1.2/tos/system/AMQueueEntryP.nc文件):

  command error_t AMSend.send(am_addr_t dest,message_t* msg,uint8_t len) {// printf("AMSend.send!!!\r\n");call AMPacket.setDestination(msg, dest);        //设置packet的目的地址call AMPacket.setType(msg, amId);              //设置packet的类型return call Send.send(msg, len);             //发送packet}

   call Send.send(msg, len);的实现代码如下:(/opt/tinyos-2.1.2/tos/system/AMQueueImplP.nc)    

/*** Accepts a properly formatted AM packet for later sending.* Assumes that someone has filled in the AM packet fields* (destination, AM type).** @param msg - the message to send* @param len - the length of the payload**/command error_t Send.send[uint8_t clientId](message_t* msg,uint8_t len) {//printf("Send.send !!!  numClients=%d clientId=%d\r\n",numClients,clientId);if (clientId >= numClients) {            //numClients=1,    clientId=0,具体什么意义暂时不了解return FAIL;}if (queue[clientId].msg != NULL) {return EBUSY;}dbg("AMQueue", "AMQueue: request to send from %hhu (%p): passed checks\n", clientId, msg);//printf("msg=%s !!!\r\n",msg);queue[clientId].msg = msg;call Packet.setPayloadLength(msg, len);        //在头部加入CC2420_SIZE的大小的头if (current >= numClients) { // queue empty      //current=1
        error_t err;am_id_t amId = call AMPacket.type(msg);        //amId=240  new AMSenderC(240)am_addr_t dest = call AMPacket.destination(msg);    //dest=-1,广播目的节点为-1?// printf("current=%d amId=%d,dest=%d!!!\r\n",current,amId,dest);dbg("AMQueue", "%s: request to send from %hhu (%p): queue empty\n", __FUNCTION__, clientId, msg);current = clientId;//printf("AMQueueImplP\r\n");err = call AMSend.send[amId](dest, msg, len);if (err != SUCCESS) {//printf("underlying send failed\r\n");dbg("AMQueue", "%s: underlying send failed.\n", __FUNCTION__);current = numClients;queue[clientId].msg = NULL;}//printf("SUCCESS\r\n");return err;}else {dbg("AMQueue", "AMQueue: request to send from %hhu (%p): queue not empty\n", clientId, msg);}return SUCCESS;}

   err = call AMSend.send[amId](dest, msg, len);由/opt/tinyos-2.1.2/wustl/upma/chips/cc2420/CC2420ActiveMessageP.nc实现,代码如下:  

/***************** AMSend Commands ****************/command error_t AMSend.send[am_id_t id](am_addr_t addr,message_t* msg,uint8_t len) {cc2420_header_t* header = call CC2420PacketBody.getHeader( msg );if (len > call Packet.maxPayloadLength()) {return ESIZE;}header->type = id;                //header->type就是new AMSenderC(240)这里的240header->dest = addr;            //header->dest=-1,由于是广播        header->destpan = call CC2420Config.getPanAddr();    //header->destpanheader->src = call AMPacket.address();    //header->src  packet源地址//   printf("header->type=%d,header->dest=%d,header->destpan=%d,header->src=%d,\r\n",
//                                header->type,header->dest,header->destpan,header->src);//printf("CC2420ActiveMessageP\r\n");if (call RadioResource.immediateRequest() == SUCCESS) {    //立即请求radio资源,经调试,一般都会成功
      error_t rc;signal SendNotifier.aboutToSend[id](addr, msg);        //为什么AMQueueImplP没有实现该事件。//printf("CC2420ActiveMessageP\r\n");rc = call SubSend.send( msg, len );if (rc != SUCCESS) {call RadioResource.release();}return rc;} else {pending_length  = len;pending_message = msg;return call RadioResource.request();}}

  rc = call SubSend.send( msg, len );由/opt/tinyos-2.1.2/tos/chips/cc2420/lowpan/ CC2420TinyosNetworkP.nc实现,源码如下: 

command error_t ActiveSend.send(message_t* msg, uint8_t len) {//printf("CC2420TinyosNetworkP\r\n");
    call CC2420Packet.setNetwork(msg, TINYOS_6LOWPAN_NETWORK_ID);m_busy_client = CLIENT_AM;return call SubSend.send(msg, len);}

call SubSend.send(msg, len); 由/opt/tinyos-2.1.2/tos/chips/cc2420/unique/UniqueSendP.nc实现,源码如下:  
  /***************** Send Commands ****************//*** Each call to this send command gives the message a single* DSN that does not change for every copy of the message* sent out.  For messages that are not acknowledged, such as* a broadcast address message, the receiving end does not* signal receive() more than once for that message.*/command error_t Send.send(message_t *msg, uint8_t len) {error_t error;//printf("UniqueSendP Send.send\r\n");if(call State.requestState(S_SENDING) == SUCCESS) {(call CC2420PacketBody.getHeader(msg))->dsn = localSendId++;if((error = call SubSend.send(msg, len)) != SUCCESS) {call State.toIdle();}return error;}return EBUSY;}

   error = call SubSend.send(msg, len)的由/opt/tinyos-2.1.2/wustl/upma/system/AsyncSendAdapterP.nc实现,源码如下:

command error_t Send.send(message_t * msg, uint8_t len){printf("AsyncSendAdapterP Send.send\r\n");return call AsyncSend.send(msg, len);}

  call AsyncSend.send(msg, len)由/opt/tinyos-2.1.2/wustl/upma/lib/macs/xmac/XmacSenderP.nc实现,终于快到目的地了,源码如下:

    

async command error_t Send.send(message_t * msg, uint8_t len){//printf("XmacSenderP Send.send\r\n");if(call SendState.getState() == S_STOPPED)return EOFF;// Make sure that the radio isn't off// Try to move to the preamble state            if(call SendState.requestState(S_PREAMBLE) == SUCCESS){call FixedSleepLplListener.cancelTimeout();atomic{msg_ = msg;len_ = len;}post doStart();return SUCCESS;// Save the parameters and start the radio
        }return FAIL;}

  总结:本想着一步一步深入了解每个步骤的内容,花了不少时间,但是还是想不通每行代码的意义,所以直接跳到XmacSenderP的实现,这里必须一步一步分析。

    

转载于:https://www.cnblogs.com/LaowangNext/p/7868624.html

Upma Xmac 测试 03相关推荐

  1. 课下测试03!03!03!题目截图及解析(不完全正确)第四周--信息安全系统设计基础...

    课下测试03,也就是第三章内容,以下分析和解析仅供参考哦~ 注意!最好是对着题目看一下书,自己思考一下题目(毕竟我页数都给你标出来了),不是说这样你就能提高了,而是我正确率真不高,你全抄我的的话后果很 ...

  2. BACnet/IP之BACnet4j学习VTS创建虚拟设备及点位测试03

    在前两篇文章中,我们使用的虚拟设备软件是Yabe,模拟天气数据,无法自定义自己的点位数据,这章就学习下使用VTS来自己创建虚拟设备,创建定义点位. 1.下载VTS 链接: https://pan.ba ...

  3. python生成器generator和迭代器Iterator测试

    为什么需要使用生成器? ''' generator生成器 通过列表推导式,我们可以创建一个新的列表,但是,受内存限制,列表的容量是有限的. 而且,创建一个包含100万个元素的列表,不仅占用很大存储空间 ...

  4. Python测试习题

    测试01 下面的4个特点,Python不具备的是?(A) A. 运行速度快B. 扩展库丰富C. 跨平台D. 支持函数式编程 下面能够支持Python开发的环境有哪些?(ABCD) A. IDLE B. ...

  5. 绝对牛逼的3套Python项目,就业/毕设/私活/女朋友都不愁了

    来源: 来自网络,如侵权请告知博主删除,感谢????. 仅学习使用,请勿用于其他- 今天给大家推荐3套Python项目,给大家介绍一波. 第一套 : Python零基础就业项目 ,比较适合还没工作,没 ...

  6. C#使用NPOI导出Excel文件

    欢迎您成为我的读者,希望这篇文章能给你一些帮助. 前言 今天咱们一起来看看在C#中如何使用NPOI第三方控件进行数据的导出. 关于NPOI插件网上资料很多,大家感兴趣的可以去看看. 本文使用的版本是N ...

  7. 超全超详细AC-DC电源模块测试教程!

    一. AC-DC电源模块典型应用电路 *备注:我司产品内部EMC相关电路,用户无需在外设额外增加器件,应用简单. 二.AC-DC电源模块基本测试方法 基本性能测试 测试仪器-参考:输入电压范围足够大的 ...

  8. mysql left join中on后加条件判断和where中加条件的区别

    left join中关于where和on条件的几个知识点:1.多表left join是会生成一张临时表,并返回给用户2.where条件是针对最后生成的这张临时表进行过滤,过滤掉不符合where条件的记 ...

  9. 用python把excel中的数据变成字典(复制代码即可用)

    在同一个文件夹里面 创建一个python文件,如dalao.py 一个excel文件,名字如textone.xlsx 在下面代码中: book = load_workbook('textone.xls ...

最新文章

  1. 动手扩充FreeTextBox的功能
  2. [k8s] 第三章 k8s 资源管理
  3. StartActivityForResult(中规中矩版 获得Acivity2的性别选择)
  4. LeetCode Decode String(栈和递归)
  5. 前端学习(2840):nevagator导航标签
  6. Java ObjectInputStream readFloat()方法与示例
  7. java 课后习题 编写判断从键盘输入的字符串是否为回文
  8. 豆瓣上关于一万小时天才理论一书的一个评论
  9. Nessus高级使用研究
  10. 【python文本分析】——基于股评文本的情绪分析
  11. linux快捷键列表,全面总结Linux快捷键的使用
  12. 【HTML/CSS】表单美化
  13. 移远NB-IOT模块BC26资料
  14. Python3 大型网络爬虫实战 003 — scrapy 大型静态图片网站爬虫项目实战 — 实战:爬取 169美女图片网 高清图片
  15. 0517零散问题整理
  16. 50个最受欢迎的大数据面试问题
  17. 使用 Learner Lab - 使用 API Gateway 与 Lambda 上传图片到 S3
  18. 使用MyQR和qrcode来制作二维码
  19. 对类模板特化和函数模板重载的一点理解
  20. #Java教程:集合 #Collection、List、Set #ArrayList、LinkedList、Vector、HashSet、TreeSet #一个斗地主小游戏@FDDLC

热门文章

  1. C#中全局作用域的常量、字段、属性、方法的定义与使用
  2. Vue实现仿音乐播放器13-实现音乐榜单跳转显以及播放效果
  3. 使用netty实现一个http挡板,轻量又实用。收藏起来吧
  4. 只是简单读了读《oracle查询优化改写》,就让我获益匪浅,想写好sql,这一本书就够了!
  5. 数据库系统概念总结:第五章 高级SQL
  6. 在Flutter中设置更好的Logging的指南
  7. Android小结(1)
  8. Mongodb~Linux环境下的部署~服务的部署与自动化
  9. nginx + mysql + php-fpm 环境
  10. XML 解析错误:XML 或文本声明不在实体的开头位置,有效的解决方法