Upma Xmac 测试 03
一、分析內(nèi)容:
這次主要分析:從上層的AMSender.send發(fā)送packet到Xmac將packet發(fā)送出去的流程。
二、
找到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));的實(shí)現(xiàn)代碼如下(/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); //設(shè)置packet的目的地址call AMPacket.setType(msg, amId); //設(shè)置packet的類型return call Send.send(msg, len); //發(fā)送packet}call Send.send(msg, len);的實(shí)現(xiàn)代碼如下:(/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,具體什么意義暫時(shí)不了解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,廣播目的節(jié)點(diǎn)為-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實(shí)現(xiàn),代碼如下:
/***************** 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) { //立即請(qǐng)求radio資源,經(jīng)調(diào)試,一般都會(huì)成功 error_t rc;signal SendNotifier.aboutToSend[id](addr, msg); //為什么AMQueueImplP沒(méi)有實(shí)現(xiàn)該事件。//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實(shí)現(xiàn),源碼如下:
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實(shí)現(xiàn),源碼如下:/***************** 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實(shí)現(xiàn),源碼如下:
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實(shí)現(xiàn),終于快到目的地了,源碼如下:
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;}
總結(jié):本想著一步一步深入了解每個(gè)步驟的內(nèi)容,花了不少時(shí)間,但是還是想不通每行代碼的意義,所以直接跳到XmacSenderP的實(shí)現(xiàn),這里必須一步一步分析。
轉(zhuǎn)載于:https://www.cnblogs.com/LaowangNext/p/7868624.html
總結(jié)
以上是生活随笔為你收集整理的Upma Xmac 测试 03的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: skynet 报错 skynet 服务缺
- 下一篇: 玩转webpack(一)下篇:webpa