diff --git a/core/net/mac/nullrdc.c b/core/net/mac/nullrdc.c index 5cec23a3d..7ba62a428 100644 --- a/core/net/mac/nullrdc.c +++ b/core/net/mac/nullrdc.c @@ -46,10 +46,10 @@ #include "net/rime/rimestats.h" #include -#if CONTIKI_TARGET_COOJA +#if CONTIKI_TARGET_COOJA || CONTIKI_TARGET_COOJA_IP64 #include "lib/simEnvChange.h" #include "sys/cooja_mt.h" -#endif /* CONTIKI_TARGET_COOJA */ +#endif /* CONTIKI_TARGET_COOJA || CONTIKI_TARGET_COOJA_IP64 */ #define DEBUG 0 #if DEBUG @@ -158,10 +158,10 @@ send_one_packet(mac_callback_t sent, void *ptr) wt = RTIMER_NOW(); watchdog_periodic(); while(RTIMER_CLOCK_LT(RTIMER_NOW(), wt + ACK_WAIT_TIME)) { -#if CONTIKI_TARGET_COOJA +#if CONTIKI_TARGET_COOJA || CONTIKI_TARGET_COOJA_IP64 simProcessRunValue = 1; cooja_mt_yield(); -#endif /* CONTIKI_TARGET_COOJA */ +#endif /* CONTIKI_TARGET_COOJA || CONTIKI_TARGET_COOJA_IP64 */ } ret = MAC_TX_NOACK; @@ -176,10 +176,10 @@ send_one_packet(mac_callback_t sent, void *ptr) watchdog_periodic(); while(RTIMER_CLOCK_LT(RTIMER_NOW(), wt + AFTER_ACK_DETECTED_WAIT_TIME)) { - #if CONTIKI_TARGET_COOJA - simProcessRunValue = 1; - cooja_mt_yield(); - #endif /* CONTIKI_TARGET_COOJA */ +#if CONTIKI_TARGET_COOJA || CONTIKI_TARGET_COOJA_IP64 + simProcessRunValue = 1; + cooja_mt_yield(); +#endif /* CONTIKI_TARGET_COOJA || CONTIKI_TARGET_COOJA_IP64 */ } } @@ -195,8 +195,8 @@ send_one_packet(mac_callback_t sent, void *ptr) } } } else { - PRINTF("nullrdc tx noack\n"); - } + PRINTF("nullrdc tx noack\n"); + } } break; case RADIO_TX_COLLISION: @@ -303,7 +303,7 @@ packet_input(void) } #endif /* RDC_WITH_DUPLICATE_DETECTION */ #endif /* NULLRDC_802154_AUTOACK */ - + #if NULLRDC_SEND_802154_ACK { frame802154_t info154; diff --git a/core/net/mac/tsch/tsch-private.h b/core/net/mac/tsch/tsch-private.h index 4a26abff3..44c928ae7 100644 --- a/core/net/mac/tsch/tsch-private.h +++ b/core/net/mac/tsch/tsch-private.h @@ -48,6 +48,10 @@ #include "net/linkaddr.h" #include "net/mac/tsch/tsch-asn.h" #include "net/mac/tsch/tsch-conf.h" +#if CONTIKI_TARGET_COOJA || CONTIKI_TARGET_COOJA_IP64 +#include "lib/simEnvChange.h" +#include "sys/cooja_mt.h" +#endif /* CONTIKI_TARGET_COOJA || CONTIKI_TARGET_COOJA_IP64 */ /************ Types ***********/ @@ -109,7 +113,14 @@ void tsch_disassociate(void); #define TSCH_CLOCK_TO_SLOTS(c, timeslot_length) (TSCH_CLOCK_TO_TICKS(c) / timeslot_length) /* Wait for a condition with timeout t0+offset. */ +#if CONTIKI_TARGET_COOJA || CONTIKI_TARGET_COOJA_IP64 +#define BUSYWAIT_UNTIL_ABS(cond, t0, offset) \ + while(!(cond) && RTIMER_CLOCK_LT(RTIMER_NOW(), (t0) + (offset))) { \ + simProcessRunValue = 1; \ + cooja_mt_yield(); \ + }; +#else #define BUSYWAIT_UNTIL_ABS(cond, t0, offset) \ while(!(cond) && RTIMER_CLOCK_LT(RTIMER_NOW(), (t0) + (offset))) ; - +#endif /* CONTIKI_TARGET_COOJA || CONTIKI_TARGET_COOJA_IP64 */ #endif /* __TSCH_PRIVATE_H__ */ diff --git a/core/net/mac/tsch/tsch-slot-operation.c b/core/net/mac/tsch/tsch-slot-operation.c index 62a7942f4..90e0fcad0 100644 --- a/core/net/mac/tsch/tsch-slot-operation.c +++ b/core/net/mac/tsch/tsch-slot-operation.c @@ -54,6 +54,10 @@ #include "net/mac/tsch/tsch-packet.h" #include "net/mac/tsch/tsch-security.h" #include "net/mac/tsch/tsch-adaptive-timesync.h" +#if CONTIKI_TARGET_COOJA || CONTIKI_TARGET_COOJA_IP64 +#include "lib/simEnvChange.h" +#include "sys/cooja_mt.h" +#endif /* CONTIKI_TARGET_COOJA || CONTIKI_TARGET_COOJA_IP64 */ #if TSCH_LOG_LEVEL >= 1 #define DEBUG DEBUG_PRINT @@ -104,7 +108,10 @@ #if RTIMER_SECOND < (32 * 1024) #error "TSCH: RTIMER_SECOND < (32 * 1024)" #endif -#if RTIMER_SECOND >= 200000 +#if CONTIKI_TARGET_COOJA || CONTIKI_TARGET_COOJA_IP64 +/* Use 0 usec guard time for Cooja Mote with a 1 MHz Rtimer*/ +#define RTIMER_GUARD 0u +#elif RTIMER_SECOND >= 200000 #define RTIMER_GUARD (RTIMER_SECOND / 100000) #else #define RTIMER_GUARD 2u @@ -200,7 +207,12 @@ tsch_get_lock(void) if(tsch_in_slot_operation) { busy_wait = 1; busy_wait_time = RTIMER_NOW(); - while(tsch_in_slot_operation); + while(tsch_in_slot_operation) { +#if CONTIKI_TARGET_COOJA || CONTIKI_TARGET_COOJA_IP64 + simProcessRunValue = 1; + cooja_mt_yield(); +#endif /* CONTIKI_TARGET_COOJA || CONTIKI_TARGET_COOJA_IP64 */ + } busy_wait_time = RTIMER_NOW() - busy_wait_time; } if(!tsch_locked) { diff --git a/examples/ipv6/rpl-tsch/project-conf.h b/examples/ipv6/rpl-tsch/project-conf.h index d1af39604..972e86c3d 100644 --- a/examples/ipv6/rpl-tsch/project-conf.h +++ b/examples/ipv6/rpl-tsch/project-conf.h @@ -181,4 +181,8 @@ #endif /* CONTIKI_TARGET_CC2538DK || CONTIKI_TARGET_ZOUL \ || CONTIKI_TARGET_OPENMOTE_CC2538 */ +#if CONTIKI_TARGET_COOJA +#define COOJA_CONF_SIMULATE_TURNAROUND 0 +#endif /* CONTIKI_TARGET_COOJA */ + #endif /* __PROJECT_CONF_H__ */ diff --git a/examples/ipv6/rpl-tsch/rpl-tsch-cooja.csc b/examples/ipv6/rpl-tsch/rpl-tsch-cooja.csc new file mode 100644 index 000000000..a07dd15bd --- /dev/null +++ b/examples/ipv6/rpl-tsch/rpl-tsch-cooja.csc @@ -0,0 +1,279 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + [APPS_DIR]/radiologger-headless + + RPL+TSCH + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype660 + Cooja Mote Type #z11 + [CONTIKI_DIR]/examples/ipv6/rpl-tsch/node.c + make TARGET=cooja clean + make TARGET=cooja node.cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -1.285769821276336 + 38.58045647334346 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype660 + + + + org.contikios.cooja.interfaces.Position + -19.324109516886306 + 76.23135780254927 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype660 + + + + org.contikios.cooja.interfaces.Position + 5.815501305791592 + 76.77463755494317 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype660 + + + + org.contikios.cooja.interfaces.Position + 31.920697784030082 + 50.5212265977149 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype660 + + + + org.contikios.cooja.interfaces.Position + 47.21747673247198 + 30.217765340599726 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype660 + + + + org.contikios.cooja.interfaces.Position + 10.622284947035123 + 109.81862399725188 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype660 + + + + org.contikios.cooja.interfaces.Position + 52.41150716335335 + 109.93228340481916 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype660 + + + + org.contikios.cooja.interfaces.Position + 70.18727461718498 + 70.06861701541145 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype660 + + + + org.contikios.cooja.interfaces.Position + 80.29870484201041 + 99.37351603835938 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 9 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype660 + + + + org.contikios.cooja.plugins.SimControl + 242 + 4 + 160 + 11 + 241 + + + org.contikios.cooja.plugins.Visualizer + + true + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.TrafficVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 1.7405603810040515 0.0 0.0 1.7405603810040515 47.95980153208088 -42.576134155447555 + + 236 + 3 + 230 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1031 + 0 + 394 + 273 + 6 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + + + + 16529.88882215865 + + 1304 + 2 + 311 + 0 + 412 + + + org.contikios.cooja.plugins.RadioLogger + + 150 + + false + false + + + 500 + 1 + 300 + 30 + 442 + + + diff --git a/platform/cooja-ip64/contiki-cooja-ip64-main.c b/platform/cooja-ip64/contiki-cooja-ip64-main.c index 02576a3be..d2d42ae9f 100644 --- a/platform/cooja-ip64/contiki-cooja-ip64-main.c +++ b/platform/cooja-ip64/contiki-cooja-ip64-main.c @@ -376,9 +376,6 @@ Java_org_contikios_cooja_corecomm_CLASSNAME_setMemory(JNIEnv *env, jobject obj, JNIEXPORT void JNICALL Java_org_contikios_cooja_corecomm_CLASSNAME_tick(JNIEnv *env, jobject obj) { - clock_time_t nextEtimer; - rtimer_clock_t nextRtimer; - simProcessRunValue = 0; /* Let all simulation interfaces act first */ @@ -403,21 +400,11 @@ Java_org_contikios_cooja_corecomm_CLASSNAME_tick(JNIEnv *env, jobject obj) doActionsAfterTick(); /* Do we have any pending timers */ - simEtimerPending = etimer_pending() || rtimer_arch_pending(); - if(!simEtimerPending) { - return; - } + simEtimerPending = etimer_pending(); /* Save nearest expiration time */ - nextEtimer = etimer_next_expiration_time() - (clock_time_t) simCurrentTime; - nextRtimer = rtimer_arch_next() - (rtimer_clock_t) simCurrentTime; - if(etimer_pending() && rtimer_arch_pending()) { - simNextExpirationTime = MIN(nextEtimer, nextRtimer); - } else if(etimer_pending()) { - simNextExpirationTime = nextEtimer; - } else if(rtimer_arch_pending()) { - simNextExpirationTime = nextRtimer; - } + simEtimerNextExpirationTime = etimer_next_expiration_time(); + } /*---------------------------------------------------------------------------*/ /** diff --git a/platform/cooja/contiki-conf.h b/platform/cooja/contiki-conf.h index 91c93a3b4..430f27a69 100644 --- a/platform/cooja/contiki-conf.h +++ b/platform/cooja/contiki-conf.h @@ -200,8 +200,12 @@ typedef unsigned short uip_stats_t; #define CLOCK_CONF_SECOND 1000L typedef unsigned long clock_time_t; -typedef unsigned long rtimer_clock_t; -#define RTIMER_CLOCK_DIFF(a,b) ((signed long)((a)-(b))) +typedef uint64_t rtimer_clock_t; +#define RTIMER_CLOCK_DIFF(a,b) ((int64_t)((a)-(b))) + +#define RADIO_DELAY_BEFORE_TX 0 +#define RADIO_DELAY_BEFORE_RX 0 +#define RADIO_DELAY_BEFORE_DETECT 0 #define AODV_COMPLIANCE #define AODV_NUM_RT_ENTRIES 32 diff --git a/platform/cooja/contiki-cooja-main.c b/platform/cooja/contiki-cooja-main.c index 40dd49d1c..9a1e60e4c 100644 --- a/platform/cooja/contiki-cooja-main.c +++ b/platform/cooja/contiki-cooja-main.c @@ -452,9 +452,6 @@ Java_org_contikios_cooja_corecomm_CLASSNAME_setMemory(JNIEnv *env, jobject obj, JNIEXPORT void JNICALL Java_org_contikios_cooja_corecomm_CLASSNAME_tick(JNIEnv *env, jobject obj) { - clock_time_t nextEtimer; - rtimer_clock_t nextRtimer; - simProcessRunValue = 0; /* Let all simulation interfaces act first */ @@ -479,21 +476,11 @@ Java_org_contikios_cooja_corecomm_CLASSNAME_tick(JNIEnv *env, jobject obj) doActionsAfterTick(); /* Do we have any pending timers */ - simEtimerPending = etimer_pending() || rtimer_arch_pending(); - if(!simEtimerPending) { - return; - } + simEtimerPending = etimer_pending(); /* Save nearest expiration time */ - nextEtimer = etimer_next_expiration_time() - (clock_time_t) simCurrentTime; - nextRtimer = rtimer_arch_next() - (rtimer_clock_t) simCurrentTime; - if(etimer_pending() && rtimer_arch_pending()) { - simNextExpirationTime = MIN(nextEtimer, nextRtimer); - } else if(etimer_pending()) { - simNextExpirationTime = nextEtimer; - } else if(rtimer_arch_pending()) { - simNextExpirationTime = nextRtimer; - } + simEtimerNextExpirationTime = etimer_next_expiration_time(); + } /*---------------------------------------------------------------------------*/ /** diff --git a/platform/cooja/dev/cooja-radio.c b/platform/cooja/dev/cooja-radio.c index 9a969016d..51c4160a6 100644 --- a/platform/cooja/dev/cooja-radio.c +++ b/platform/cooja/dev/cooja-radio.c @@ -46,15 +46,13 @@ #define COOJA_RADIO_BUFSIZE PACKETBUF_SIZE #define CCA_SS_THRESHOLD -95 -#define WITH_TURNAROUND 1 -#define WITH_SEND_CCA 1 - const struct simInterface radio_interface; /* COOJA */ char simReceiving = 0; char simInDataBuffer[COOJA_RADIO_BUFSIZE]; int simInSize = 0; +rtimer_clock_t simLastPacketTimestamp = 0; char simOutDataBuffer[COOJA_RADIO_BUFSIZE]; int simOutSize = 0; char simRadioHWOn = 1; @@ -66,8 +64,37 @@ int simLQI = 105; static const void *pending_data; -PROCESS(cooja_radio_process, "cooja radio process"); +/* If we are in the polling mode, poll_mode is 1; otherwise 0 */ +static int poll_mode = 0; /* default 0, disabled */ +static int auto_ack = 0; /* AUTO_ACK is not supported; always 0 */ +static int addr_filter = 0; /* ADDRESS_FILTER is not supported; always 0 */ +static int send_on_cca = (COOJA_TRANSMIT_ON_CCA != 0); +PROCESS(cooja_radio_process, "cooja radio process"); +/*---------------------------------------------------------------------------*/ +static void +set_send_on_cca(uint8_t enable) +{ + send_on_cca = enable; +} +/*---------------------------------------------------------------------------*/ +static void +set_frame_filtering(int enable) +{ + addr_filter = enable; +} +/*---------------------------------------------------------------------------*/ +static void +set_auto_ack(int enable) +{ + auto_ack = enable; +} +/*---------------------------------------------------------------------------*/ +static void +set_poll_mode(int enable) +{ + poll_mode = enable; +} /*---------------------------------------------------------------------------*/ void radio_set_channel(int channel) @@ -97,7 +124,7 @@ radio_signal_strength_current(void) int radio_LQI(void) { - return simLQI; + return simLQI; } /*---------------------------------------------------------------------------*/ static int @@ -152,8 +179,10 @@ radio_read(void *buf, unsigned short bufsize) memcpy(buf, simInDataBuffer, simInSize); simInSize = 0; - packetbuf_set_attr(PACKETBUF_ATTR_RSSI, simSignalStrength); - packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, simLQI); + if(!poll_mode) { + packetbuf_set_attr(PACKETBUF_ATTR_RSSI, simSignalStrength); + packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, simLQI); + } return tmp; } @@ -173,14 +202,14 @@ radio_send(const void *payload, unsigned short payload_len) int radiostate = simRadioHWOn; /* Simulate turnaround time of 2ms for packets, 1ms for acks*/ -#if WITH_TURNAROUND +#if COOJA_SIMULATE_TURNAROUND simProcessRunValue = 1; cooja_mt_yield(); if(payload_len > 3) { simProcessRunValue = 1; cooja_mt_yield(); } -#endif /* WITH_TURNAROUND */ +#endif /* COOJA_SIMULATE_TURNAROUND */ if(!simRadioHWOn) { /* Turn on radio temporarily */ @@ -197,11 +226,11 @@ radio_send(const void *payload, unsigned short payload_len) } /* Transmit on CCA */ -#if WITH_SEND_CCA - if(!channel_clear()) { +#if COOJA_TRANSMIT_ON_CCA + if(send_on_cca && !channel_clear()) { return RADIO_TX_COLLISION; } -#endif /* WITH_SEND_CCA */ +#endif /* COOJA_TRANSMIT_ON_CCA */ /* Copy packet data to temporary storage */ memcpy(simOutDataBuffer, payload, payload_len); @@ -253,6 +282,9 @@ PROCESS_THREAD(cooja_radio_process, ev, data) while(1) { PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); + if(poll_mode) { + continue; + } packetbuf_clear(); len = radio_read(packetbuf_dataptr(), PACKETBUF_SIZE); @@ -275,18 +307,87 @@ init(void) static radio_result_t get_value(radio_param_t param, radio_value_t *value) { - return RADIO_RESULT_NOT_SUPPORTED; + switch(param) { + case RADIO_PARAM_RX_MODE: + *value = 0; + if(addr_filter) { + *value |= RADIO_RX_MODE_ADDRESS_FILTER; + } + if(auto_ack) { + *value |= RADIO_RX_MODE_AUTOACK; + } + if(poll_mode) { + *value |= RADIO_RX_MODE_POLL_MODE; + } + return RADIO_RESULT_OK; + case RADIO_PARAM_TX_MODE: + *value = 0; + if(send_on_cca) { + *value |= RADIO_TX_MODE_SEND_ON_CCA; + } + return RADIO_RESULT_OK; + case RADIO_PARAM_LAST_RSSI: + *value = simSignalStrength; + return RADIO_RESULT_OK; + case RADIO_PARAM_LAST_LINK_QUALITY: + *value = simLQI; + return RADIO_RESULT_OK; + default: + return RADIO_RESULT_NOT_SUPPORTED; + } } /*---------------------------------------------------------------------------*/ static radio_result_t set_value(radio_param_t param, radio_value_t value) { - return RADIO_RESULT_NOT_SUPPORTED; + switch(param) { + case RADIO_PARAM_RX_MODE: + if(value & ~(RADIO_RX_MODE_ADDRESS_FILTER | + RADIO_RX_MODE_AUTOACK | RADIO_RX_MODE_POLL_MODE)) { + return RADIO_RESULT_INVALID_VALUE; + } + + /* Only disabling is acceptable for RADIO_RX_MODE_ADDRESS_FILTER */ + if ((value & RADIO_RX_MODE_ADDRESS_FILTER) != 0) { + return RADIO_RESULT_NOT_SUPPORTED; + } + set_frame_filtering((value & RADIO_RX_MODE_ADDRESS_FILTER) != 0); + + /* Only disabling is acceptable for RADIO_RX_MODE_AUTOACK */ + if ((value & RADIO_RX_MODE_ADDRESS_FILTER) != 0) { + return RADIO_RESULT_NOT_SUPPORTED; + } + set_auto_ack((value & RADIO_RX_MODE_AUTOACK) != 0); + + set_poll_mode((value & RADIO_RX_MODE_POLL_MODE) != 0); + return RADIO_RESULT_OK; + case RADIO_PARAM_TX_MODE: + if(value & ~(RADIO_TX_MODE_SEND_ON_CCA)) { + return RADIO_RESULT_INVALID_VALUE; + } + set_send_on_cca((value & RADIO_TX_MODE_SEND_ON_CCA) != 0); + return RADIO_RESULT_OK; + case RADIO_PARAM_CHANNEL: + if(value < 11 || value > 26) { + return RADIO_RESULT_INVALID_VALUE; + } + radio_set_channel(value); + return RADIO_RESULT_OK; + default: + return RADIO_RESULT_NOT_SUPPORTED; + } } /*---------------------------------------------------------------------------*/ static radio_result_t get_object(radio_param_t param, void *dest, size_t size) { + if(param == RADIO_PARAM_LAST_PACKET_TIMESTAMP) { + if(size != sizeof(rtimer_clock_t) || !dest) { + return RADIO_RESULT_INVALID_VALUE; + } + *(rtimer_clock_t *)dest = (rtimer_clock_t)simLastPacketTimestamp; + return RADIO_RESULT_OK; + } return RADIO_RESULT_NOT_SUPPORTED; } /*---------------------------------------------------------------------------*/ @@ -315,5 +416,5 @@ const struct radio_driver cooja_radio_driver = }; /*---------------------------------------------------------------------------*/ SIM_INTERFACE(radio_interface, - doInterfaceActionsBeforeTick, - doInterfaceActionsAfterTick); + doInterfaceActionsBeforeTick, + doInterfaceActionsAfterTick); diff --git a/platform/cooja/dev/cooja-radio.h b/platform/cooja/dev/cooja-radio.h index b6bfb3aaf..a65a61bb1 100644 --- a/platform/cooja/dev/cooja-radio.h +++ b/platform/cooja/dev/cooja-radio.h @@ -36,6 +36,18 @@ #include "contiki.h" #include "dev/radio.h" +#ifdef COOJA_CONF_SIMULATE_TURNAROUND +#define COOJA_SIMULATE_TURNAROUND COOJA_CONF_SIMULATE_TURNAROUND +#else +#define COOJA_SIMULATE_TURNAROUND 1 +#endif + +#ifdef COOJA_CONF_TRANSMIT_ON_CCA +#define COOJA_TRANSMIT_ON_CCA COOJA_CONF_TRANSMIT_ON_CCA +#else +#define COOJA_TRANSMIT_ON_CCA 1 +#endif + extern const struct radio_driver cooja_radio_driver; /** diff --git a/platform/cooja/lib/simEnvChange.c b/platform/cooja/lib/simEnvChange.c index c9fbd438f..f6060b449 100644 --- a/platform/cooja/lib/simEnvChange.c +++ b/platform/cooja/lib/simEnvChange.c @@ -40,7 +40,7 @@ char simDontFallAsleep = 0; int simProcessRunValue; int simEtimerPending; -clock_time_t simNextExpirationTime; +clock_time_t simEtimerNextExpirationTime; void doActionsBeforeTick() { // Poll all interfaces to do their thing before the tick diff --git a/platform/cooja/lib/simEnvChange.h b/platform/cooja/lib/simEnvChange.h index 35189a42d..7723eb16f 100644 --- a/platform/cooja/lib/simEnvChange.h +++ b/platform/cooja/lib/simEnvChange.h @@ -42,7 +42,7 @@ struct simInterface { // Variable for keeping the last process_run() return value extern int simProcessRunValue; extern int simEtimerPending; -extern clock_time_t simNextExpirationTime; +extern clock_time_t simEtimerNextExpirationTime; extern clock_time_t simCurrentTime; // Variable that when set to != 0, stops the mote from falling asleep next tick diff --git a/platform/cooja/rtimer-arch.c b/platform/cooja/rtimer-arch.c index dff66fdc7..9d4f77646 100644 --- a/platform/cooja/rtimer-arch.c +++ b/platform/cooja/rtimer-arch.c @@ -48,46 +48,44 @@ #define PRINTF(...) #endif -extern clock_time_t simCurrentTime; - -static int pending_rtimer = 0; -static rtimer_clock_t next_rtimer = 0; -static clock_time_t last_rtimer_now = 0; +/* COOJA */ +int simRtimerPending; +rtimer_clock_t simRtimerNextExpirationTime; +rtimer_clock_t simRtimerCurrentTicks; /*---------------------------------------------------------------------------*/ void rtimer_arch_init(void) { - next_rtimer = 0; - last_rtimer_now = 0; - pending_rtimer = 0; + simRtimerNextExpirationTime = 0; + simRtimerPending = 0; } /*---------------------------------------------------------------------------*/ void rtimer_arch_schedule(rtimer_clock_t t) { - next_rtimer = t; - pending_rtimer = 1; + simRtimerNextExpirationTime = t; + simRtimerPending = 1; } /*---------------------------------------------------------------------------*/ rtimer_clock_t rtimer_arch_next(void) { - return next_rtimer; + return simRtimerNextExpirationTime; } /*---------------------------------------------------------------------------*/ int rtimer_arch_pending(void) { - return pending_rtimer; + return simRtimerPending; } /*---------------------------------------------------------------------------*/ int rtimer_arch_check(void) { - if (simCurrentTime == next_rtimer) { + if (simRtimerCurrentTicks == simRtimerNextExpirationTime) { /* Execute rtimer */ - pending_rtimer = 0; + simRtimerPending = 0; rtimer_run_next(); return 1; } @@ -97,14 +95,7 @@ rtimer_arch_check(void) rtimer_clock_t rtimer_arch_now(void) { - if(last_rtimer_now == simCurrentTime) { - /* Yield to COOJA, to allow time to change */ - simProcessRunValue = 1; - simNextExpirationTime = simCurrentTime + 1; - cooja_mt_yield(); - } - last_rtimer_now = simCurrentTime; - return simCurrentTime; + return simRtimerCurrentTicks; } /*---------------------------------------------------------------------------*/ diff --git a/platform/cooja/rtimer-arch.h b/platform/cooja/rtimer-arch.h index 616ad4185..390e1ac56 100644 --- a/platform/cooja/rtimer-arch.h +++ b/platform/cooja/rtimer-arch.h @@ -36,7 +36,10 @@ #include "contiki-conf.h" #include "sys/clock.h" -#define RTIMER_ARCH_SECOND CLOCK_CONF_SECOND +#define RTIMER_ARCH_SECOND UINT64_C(1000000) + +#define US_TO_RTIMERTICKS(US) (US) +#define RTIMERTICKS_TO_US(T) (T) rtimer_clock_t rtimer_arch_now(void); int rtimer_arch_check(void); diff --git a/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiClock.java b/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiClock.java index b033ef06d..97cbc61c3 100644 --- a/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiClock.java +++ b/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiClock.java @@ -52,8 +52,11 @@ import org.contikios.cooja.mote.memory.VarMemory; * Contiki variables: * * @@ -125,16 +128,24 @@ public class ContikiClock extends Clock implements ContikiMoteInterface, PolledB public void doActionsBeforeTick() { /* Update time */ - setTime(mote.getSimulation().getSimulationTime() + timeDrift); + long currentSimulationTime = simulation.getSimulationTime(); + setTime(currentSimulationTime + timeDrift); + moteMem.setInt64ValueOf("simRtimerCurrentTicks", currentSimulationTime); } public void doActionsAfterTick() { + long currentSimulationTime = mote.getSimulation().getSimulationTime(); + + /* Always schedule for Rtimer if anything pending */ + if (moteMem.getIntValueOf("simRtimerPending") != 0) { + mote.scheduleNextWakeup(moteMem.getInt64ValueOf("simRtimerNextExpirationTime")); + } /* Request next tick for remaining events / timers */ int processRunValue = moteMem.getIntValueOf("simProcessRunValue"); if (processRunValue != 0) { /* Handle next Contiki event in one millisecond */ - mote.scheduleNextWakeup(simulation.getSimulationTime() + Simulation.MILLISECOND); + mote.scheduleNextWakeup(currentSimulationTime + Simulation.MILLISECOND); return; } @@ -144,15 +155,20 @@ public class ContikiClock extends Clock implements ContikiMoteInterface, PolledB return; } - /* Request tick next wakeup time */ - int nextExpirationTime = moteMem.getIntValueOf("simNextExpirationTime"); - if (nextExpirationTime <= 0) { - /*logger.warn("Event timer already expired, but has been delayed: " + nextExpirationTime);*/ - mote.scheduleNextWakeup(simulation.getSimulationTime() + Simulation.MILLISECOND); - return; + /* Request tick next wakeup time for Etimer */ + long etimerNextExpirationTime = (long)moteMem.getInt32ValueOf("simEtimerNextExpirationTime") * Simulation.MILLISECOND; + long etimerTimeToNextExpiration = etimerNextExpirationTime - moteTime; + if (etimerTimeToNextExpiration <= 0) { + /* logger.warn(mote.getID() + ": Event timer already expired, but has been delayed: " + etimerTimeToNextExpiration); */ + /* Wake up in one millisecond to handle a missed Etimer task + * which may be blocked by busy waiting such as one in + * radio_send(). Scheduling it in a shorter time than one + * millisecond, e.g., one microsecond, seems to be worthless and + * it would cause unnecessary CPU usage. */ + mote.scheduleNextWakeup(currentSimulationTime + Simulation.MILLISECOND); + } else { + mote.scheduleNextWakeup(currentSimulationTime + etimerTimeToNextExpiration); } - - mote.scheduleNextWakeup(simulation.getSimulationTime() + Simulation.MILLISECOND*nextExpirationTime); } diff --git a/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiRadio.java b/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiRadio.java index bbc4a2abd..dd0775225 100644 --- a/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiRadio.java +++ b/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiRadio.java @@ -62,6 +62,7 @@ import org.contikios.cooja.util.CCITT_CRC; *

*

  • int simInSize (size of received data packet) *
  • byte[] simInDataBuffer (data of received data packet) + *
  • int64_t simLastPacketTimestamp (timestamp of the last received data packet) *

    *

  • int simOutSize (size of transmitted data packet) *
  • byte[] simOutDataBuffer (data of transmitted data packet) @@ -190,6 +191,8 @@ public class ContikiRadio extends Radio implements ContikiMoteInterface, PolledA lastEventTime = mote.getSimulation().getSimulationTime(); lastEvent = RadioEvent.RECEPTION_STARTED; + myMoteMemory.setInt64ValueOf("simLastPacketTimestamp", lastEventTime); + this.setChanged(); this.notifyObservers(); } diff --git a/tools/cooja/java/org/contikios/cooja/mote/memory/VarMemory.java b/tools/cooja/java/org/contikios/cooja/mote/memory/VarMemory.java index 65cff9af7..4e774c8f4 100644 --- a/tools/cooja/java/org/contikios/cooja/mote/memory/VarMemory.java +++ b/tools/cooja/java/org/contikios/cooja/mote/memory/VarMemory.java @@ -263,7 +263,7 @@ public class VarMemory extends Memory { * @param varName Variable name * @param value 16 bit integer value to write */ - public void setInt16ValueOf(String varName, byte value) + public void setInt16ValueOf(String varName, short value) throws UnknownVariableException { setInt16ValueOf(getVariable(varName).addr, value); } @@ -274,7 +274,7 @@ public class VarMemory extends Memory { * @param varName Variable name * @param value 32 bit integer value to write */ - public void setInt32ValueOf(String varName, byte value) + public void setInt32ValueOf(String varName, int value) throws UnknownVariableException { setInt32ValueOf(getVariable(varName).addr, value); } @@ -285,7 +285,7 @@ public class VarMemory extends Memory { * @param varName Variable name * @param value 64 bit integer value to write */ - public void setInt64ValueOf(String varName, byte value) + public void setInt64ValueOf(String varName, long value) throws UnknownVariableException { setInt64ValueOf(getVariable(varName).addr, value); }