diff --git a/apps/slip-cmd/packetutils.c b/apps/slip-cmd/packetutils.c index e8c7fd9aa..46ca3ad5f 100644 --- a/apps/slip-cmd/packetutils.c +++ b/apps/slip-cmd/packetutils.c @@ -70,7 +70,16 @@ packetutils_deserialize_atts(const uint8_t *data, int size) pos = 0; cnt = data[pos++]; PRINTF("packetutils: deserializing %d packet atts:", cnt); + if(cnt > PACKETBUF_NUM_ATTRS) { + PRINTF(" *** too many: %u!\n", PACKETBUF_NUM_ATTRS); + return -1; + } for(i = 0; i < cnt; i++) { + if(data[pos] >= PACKETBUF_NUM_ATTRS) { + /* illegal attribute identifier */ + PRINTF(" *** unknown attribute %u\n", data[pos]); + return -1; + } PRINTF(" %d=%d", data[pos], (data[pos + 1] << 8) | data[pos + 2]); packetbuf_set_attr(data[pos], (data[pos + 1] << 8) | data[pos + 2]); pos += 3; diff --git a/cpu/cc2430/dev/cc2430_rf.c b/cpu/cc2430/dev/cc2430_rf.c index 835365afe..3e53a0f31 100644 --- a/cpu/cc2430/dev/cc2430_rf.c +++ b/cpu/cc2430/dev/cc2430_rf.c @@ -234,7 +234,7 @@ cc2430_rf_tx_enable(void) * Set MAC addresses * * \param pan The PAN address to set - * \param adde The short address to set + * \param addr The short address to set * \param ieee_addr The 64-bit IEEE address to set */ void diff --git a/cpu/cc253x/Makefile.cc253x b/cpu/cc253x/Makefile.cc253x index 568d8f2d9..800574f7a 100644 --- a/cpu/cc253x/Makefile.cc253x +++ b/cpu/cc253x/Makefile.cc253x @@ -15,6 +15,7 @@ BANK_ALLOC = $(CONTIKI_CPU)/bank-alloc.py SEGMENT_RULES = $(OBJECTDIR)/segment.rules CFLAGS += --model-$(MEMORY_MODEL) --stack-auto --std-c99 +CFLAGS += -DCC2530_LAST_FLASH_BANK=$(HIGH_FLASH_BANK) LDFLAGS += --model-$(MEMORY_MODEL) --stack-auto --out-fmt-ihx LDFLAGS += --xram-loc 0x0000 --xram-size 0x1F00 @@ -33,6 +34,16 @@ sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ rm -f $(@:.rel=.$$$$) endef +### SoC flavor (F256, F128, F64, F32) as the ID of the last flash bank (0...7) +### We assume F256, project Makefile can override +### +### ToDo: +### Fix --code-size accordingly +### Fix the bank allocator to play for all flavors +ifndef HIGH_FLASH_BANK + HIGH_FLASH_BANK=7 +endif + ### Banking Guesswork: ### Generic examples do not specify banking. ### We automatically turn it on if its unspecified and if we are building with diff --git a/cpu/cc253x/dev/cc2530-rf.c b/cpu/cc253x/dev/cc2530-rf.c index fc01d8a37..6adacc22c 100644 --- a/cpu/cc253x/dev/cc2530-rf.c +++ b/cpu/cc253x/dev/cc2530-rf.c @@ -46,6 +46,7 @@ #include "net/packetbuf.h" #include "net/rime/rimestats.h" +#include "net/rime/rimeaddr.h" #include "net/netstack.h" #include @@ -142,13 +143,18 @@ cc2530_rf_power_set(uint8_t new_power) void cc2530_rf_set_addr(uint16_t pan) { +#if RIMEADDR_SIZE==8 /* EXT_ADDR[7:0] is ignored when using short addresses */ + int i; + for(i = (RIMEADDR_SIZE - 1); i >= 0; --i) { + ((uint8_t *)&EXT_ADDR0)[i] = rimeaddr_node_addr.u8[RIMEADDR_SIZE - 1 - i]; + } +#endif + PAN_ID0 = pan & 0xFF; PAN_ID1 = pan >> 8; - SHORT_ADDR0 = ((uint8_t *)&X_IEEE_ADDR)[0]; - SHORT_ADDR1 = ((uint8_t *)&X_IEEE_ADDR)[1]; - - memcpy(&EXT_ADDR0, &X_IEEE_ADDR, 8); + SHORT_ADDR0 = rimeaddr_node_addr.u8[RIMEADDR_SIZE - 1]; + SHORT_ADDR1 = rimeaddr_node_addr.u8[RIMEADDR_SIZE - 2]; } /*---------------------------------------------------------------------------*/ /* Netstack API radio driver functions */ diff --git a/cpu/cc253x/soc.h b/cpu/cc253x/soc.h index 81888e2ab..bcf858ba0 100644 --- a/cpu/cc253x/soc.h +++ b/cpu/cc253x/soc.h @@ -31,7 +31,7 @@ /** * \file - * Header file for cc253x SoC hardware init routines + * Header file with cc253x SoC-specific defines and prototypes * * \author * George Oikonomou - @@ -41,6 +41,24 @@ #ifndef __SOC_H__ #define __SOC_H__ + +#ifndef CC2530_LAST_FLASH_BANK +#define CC2530_LAST_FLASH_BANK 7 /* Default to F256 */ +#endif + +#if CC2530_LAST_FLASH_BANK==7 /* F256 */ +#define CC2530_FLAVOR_STRING "F256" +#elif CC2530_LAST_FLASH_BANK==3 /* F128 */ +#define CC2530_FLAVOR_STRING "F128" +#elif CC2530_LAST_FLASH_BANK==1 /* F64 */ +#define CC2530_FLAVOR_STRING "F64" +#elif CC2530_LAST_FLASH_BANK==0 /* F32 */ +#define CC2530_FLAVOR_STRING "F32" +#else +#error "Unknown SoC Type specified. Check the value of HIGH_FLASH_BANK in your" +#error "Makefile. Valid values are 0, 1, 3, 7" +#endif + void soc_init(); #endif /* __SOC_H__ */ diff --git a/examples/ipv6/native-border-router/border-router-cmds.c b/examples/ipv6/native-border-router/border-router-cmds.c index 0e7482726..eec4646ab 100644 --- a/examples/ipv6/native-border-router/border-router-cmds.c +++ b/examples/ipv6/native-border-router/border-router-cmds.c @@ -38,6 +38,7 @@ #include "contiki.h" #include "cmd.h" #include "border-router.h" +#include "border-router-cmds.h" #include "dev/serial-line.h" #include "net/rpl/rpl.h" #include "net/uiplib.h" @@ -46,6 +47,9 @@ #define DEBUG DEBUG_NONE #include "net/uip-debug.h" + +uint8_t command_context; + void packet_sent(uint8_t sessionid, uint8_t status, uint8_t tx); void nbr_print_stat(void); @@ -61,27 +65,27 @@ border_router_cmd_handler(const uint8_t *data, int len) /* handle global repair, etc here */ if(data[0] == '!') { PRINTF("Got configuration message of type %c\n", data[1]); - if(data[1] == 'G') { + if(data[1] == 'G' && command_context == CMD_CONTEXT_STDIO) { /* This is supposed to be from stdin */ printf("Performing Global Repair...\n"); rpl_repair_root(RPL_DEFAULT_INSTANCE); return 1; - } else if(data[1] == 'M') { + } else if(data[1] == 'M' && command_context == CMD_CONTEXT_RADIO) { /* We need to know that this is from the slip-radio here. */ PRINTF("Setting MAC address\n"); border_router_set_mac(&data[2]); return 1; - } else if(data[1] == 'C') { + } else if(data[1] == 'C' && command_context == CMD_CONTEXT_RADIO) { /* We need to know that this is from the slip-radio here. */ printf("Channel is:%d\n", data[2]); return 1; - } else if(data[1] == 'R') { + } else if(data[1] == 'R' && command_context == CMD_CONTEXT_RADIO) { /* We need to know that this is from the slip-radio here. */ PRINTF("Packet data report for sid:%d st:%d tx:%d\n", data[2], data[3], data[4]); packet_sent(data[2], data[3], data[4]); return 1; - } else if(data[1] == 'D') { + } else if(data[1] == 'D' && command_context == CMD_CONTEXT_RADIO) { /* We need to know that this is from the slip-radio here... */ PRINTF("Sensor data received\n"); border_router_set_sensors((const char *)&data[2], len - 2); @@ -89,7 +93,7 @@ border_router_cmd_handler(const uint8_t *data, int len) } } else if(data[0] == '?') { PRINTF("Got request message of type %c\n", data[1]); - if(data[1] == 'M') { + if(data[1] == 'M' && command_context == CMD_CONTEXT_STDIO) { uint8_t buf[20]; char* hexchar = "0123456789abcdef"; int j; @@ -102,7 +106,7 @@ border_router_cmd_handler(const uint8_t *data, int len) } cmd_send(buf, 18); return 1; - } else if(data[1] == 'C') { + } else if(data[1] == 'C' && command_context == CMD_CONTEXT_STDIO) { /* send on! */ write_to_slip(data, len); return 1; @@ -134,6 +138,7 @@ PROCESS_THREAD(border_router_cmd_process, ev, data) if(ev == serial_line_event_message && data != NULL) { PRINTF("Got serial data!!! %s of len: %d\n", (char *)data, strlen((char *)data)); + command_context = CMD_CONTEXT_STDIO; cmd_input(data, strlen((char *)data)); } } diff --git a/examples/ipv6/native-border-router/border-router-cmds.h b/examples/ipv6/native-border-router/border-router-cmds.h index 8da68562b..38fc92111 100644 --- a/examples/ipv6/native-border-router/border-router-cmds.h +++ b/examples/ipv6/native-border-router/border-router-cmds.h @@ -38,6 +38,11 @@ #ifndef __BORDER_ROUTER_CMDS_H__ #define __BORDER_ROUTER_CMDS_H__ +#define CMD_CONTEXT_RADIO 0 +#define CMD_CONTEXT_STDIO 1 + +extern uint8_t command_context; + PROCESS_NAME(border_router_cmd_process); #endif /* __BORDER_ROUTER_CMDS_H__ */ diff --git a/examples/ipv6/native-border-router/project-conf.h b/examples/ipv6/native-border-router/project-conf.h index 2ab3cda7b..494264b58 100644 --- a/examples/ipv6/native-border-router/project-conf.h +++ b/examples/ipv6/native-border-router/project-conf.h @@ -42,6 +42,8 @@ #undef UIP_CONF_RECEIVE_WINDOW #define UIP_CONF_RECEIVE_WINDOW 60 +#define SLIP_DEV_CONF_SEND_DELAY (CLOCK_SECOND / 32) + #undef WEBSERVER_CONF_CFS_CONNS #define WEBSERVER_CONF_CFS_CONNS 2 diff --git a/examples/ipv6/native-border-router/slip-dev.c b/examples/ipv6/native-border-router/slip-dev.c index 6075b4121..a38c6a0c3 100644 --- a/examples/ipv6/native-border-router/slip-dev.c +++ b/examples/ipv6/native-border-router/slip-dev.c @@ -32,7 +32,6 @@ /* Below define allows importing saved output into Wireshark as "Raw IP" packet type */ #define WIRESHARK_IMPORT_FORMAT 1 #include "contiki.h" -#include "net/uip.h" #include #include @@ -55,6 +54,7 @@ #include "net/netstack.h" #include "net/packetbuf.h" #include "cmd.h" +#include "border-router-cmds.h" extern int slip_config_verbose; extern int slip_config_flowcontrol; @@ -64,6 +64,11 @@ extern const char *slip_config_port; extern uint16_t slip_config_basedelay; extern speed_t slip_config_b_rate; +#ifdef SLIP_DEV_CONF_SEND_DELAY +#define SEND_DELAY SLIP_DEV_CONF_SEND_DELAY +#else +#define SEND_DELAY 0 +#endif int devopen(const char *dev, int flags); @@ -75,7 +80,6 @@ long slip_received = 0; int slipfd = 0; -void slip_send(int fd, unsigned char c); //#define PROGRESS(s) fprintf(stderr, s) #define PROGRESS(s) do { } while(0) @@ -172,9 +176,7 @@ slip_packet_input(unsigned char *data, int len) void serial_input(FILE *inslip) { - static union { - unsigned char inbuf[2000]; - } uip; + unsigned char inbuf[2048]; static int inbufptr = 0; int ret,i; unsigned char c; @@ -186,7 +188,7 @@ serial_input(FILE *inslip) #endif read_more: - if(inbufptr >= sizeof(uip.inbuf)) { + if(inbufptr >= sizeof(inbuf)) { fprintf(stderr, "*** dropping large %d byte packet\n", inbufptr); inbufptr = 0; } @@ -205,15 +207,16 @@ serial_input(FILE *inslip) switch(c) { case SLIP_END: if(inbufptr > 0) { - if(uip.inbuf[0] == '!') { - cmd_input(uip.inbuf, inbufptr); - } else if(uip.inbuf[0] == '?') { + if(inbuf[0] == '!') { + command_context = CMD_CONTEXT_RADIO; + cmd_input(inbuf, inbufptr); + } else if(inbuf[0] == '?') { #define DEBUG_LINE_MARKER '\r' - } else if(uip.inbuf[0] == DEBUG_LINE_MARKER) { - fwrite(uip.inbuf + 1, inbufptr - 1, 1, stdout); - } else if(is_sensible_string(uip.inbuf, inbufptr)) { + } else if(inbuf[0] == DEBUG_LINE_MARKER) { + fwrite(inbuf + 1, inbufptr - 1, 1, stdout); + } else if(is_sensible_string(inbuf, inbufptr)) { if(slip_config_verbose == 1) { /* strings already echoed below for verbose>1 */ - fwrite(uip.inbuf, inbufptr, 1, stdout); + fwrite(inbuf, inbufptr, 1, stdout); } } else { if(slip_config_verbose > 2) { @@ -221,11 +224,11 @@ serial_input(FILE *inslip) if(slip_config_verbose > 4) { #if WIRESHARK_IMPORT_FORMAT printf("0000"); - for(i = 0; i < inbufptr; i++) printf(" %02x", uip.inbuf[i]); + for(i = 0; i < inbufptr; i++) printf(" %02x", inbuf[i]); #else printf(" "); for(i = 0; i < inbufptr; i++) { - printf("%02x", uip.inbuf[i]); + printf("%02x", inbuf[i]); if((i & 3) == 3) printf(" "); if((i & 15) == 15) printf("\n "); } @@ -233,7 +236,7 @@ serial_input(FILE *inslip) printf("\n"); } } - slip_packet_input(uip.inbuf, inbufptr); + slip_packet_input(inbuf, inbufptr); } inbufptr = 0; } @@ -257,7 +260,7 @@ serial_input(FILE *inslip) } /* FALLTHROUGH */ default: - uip.inbuf[inbufptr++] = c; + inbuf[inbufptr++] = c; /* Echo lines as they are received for verbose=2,3,5+ */ /* Echo all printable characters for verbose==4 */ @@ -266,8 +269,8 @@ serial_input(FILE *inslip) fwrite(&c, 1, 1, stdout); } } else if(slip_config_verbose >= 2) { - if(c == '\n' && is_sensible_string(uip.inbuf, inbufptr)) { - fwrite(uip.inbuf, inbufptr, 1, stdout); + if(c == '\n' && is_sensible_string(inbuf, inbufptr)) { + fwrite(inbuf, inbufptr, 1, stdout); inbufptr = 0; } } @@ -277,10 +280,13 @@ serial_input(FILE *inslip) goto read_more; } -unsigned char slip_buf[2000]; -int slip_end, slip_begin; +unsigned char slip_buf[2048]; +int slip_end, slip_begin, slip_packet_end, slip_packet_count; +static struct timer send_delay_timer; +/* delay between slip packets */ +static clock_time_t send_delay = SEND_DELAY; /*---------------------------------------------------------------------------*/ -void +static void slip_send(int fd, unsigned char c) { if(slip_end >= sizeof(slip_buf)) { @@ -289,12 +295,19 @@ slip_send(int fd, unsigned char c) slip_buf[slip_end] = c; slip_end++; slip_sent++; + if(c == SLIP_END) { + /* Full packet received. */ + slip_packet_count++; + if(slip_packet_end == 0) { + slip_packet_end = slip_end; + } + } } /*---------------------------------------------------------------------------*/ int slip_empty() { - return slip_end == 0; + return slip_packet_end == 0; } /*---------------------------------------------------------------------------*/ void @@ -306,16 +319,35 @@ slip_flushbuf(int fd) return; } - n = write(fd, slip_buf + slip_begin, slip_end - slip_begin); + n = write(fd, slip_buf + slip_begin, slip_packet_end - slip_begin); if(n == -1 && errno != EAGAIN) { err(1, "slip_flushbuf write failed"); } else if(n == -1) { - PROGRESS("Q"); /* Outqueueis full! */ + PROGRESS("Q"); /* Outqueue is full! */ } else { slip_begin += n; - if(slip_begin == slip_end) { - slip_begin = slip_end = 0; + if(slip_begin == slip_packet_end) { + slip_packet_count--; + if(slip_end > slip_packet_end) { + memcpy(slip_buf, slip_buf + slip_packet_end, + slip_end - slip_packet_end); + } + slip_end -= slip_packet_end; + slip_begin = slip_packet_end = 0; + if(slip_end > 0) { + /* Find end of next slip packet */ + for(n = 1; n < slip_end; n++) { + if(slip_buf[n] == SLIP_END) { + slip_packet_end = n + 1; + break; + } + } + /* a delay between slip packets to avoid losing data */ + if(send_delay > 0) { + timer_set(&send_delay_timer, send_delay); + } + } } } } @@ -430,7 +462,8 @@ stty_telos(int fd) static int set_fd(fd_set *rset, fd_set *wset) { - if(!slip_empty()) { /* Anything to flush? */ + /* Anything to flush? */ + if(!slip_empty() && (send_delay == 0 || timer_expired(&send_delay_timer))) { FD_SET(slipfd, wset); } @@ -503,6 +536,7 @@ slip_init(void) stty_telos(slipfd); } + timer_set(&send_delay_timer, 0); slip_send(slipfd, SLIP_END); inslip = fdopen(slipfd, "r"); if(inslip == NULL) { diff --git a/examples/ipv6/slip-radio/slip-radio.c b/examples/ipv6/slip-radio/slip-radio.c index c034d8964..d04b4b1e6 100644 --- a/examples/ipv6/slip-radio/slip-radio.c +++ b/examples/ipv6/slip-radio/slip-radio.c @@ -99,9 +99,12 @@ slip_radio_cmd_handler(const uint8_t *data, int len) packet_ids[packet_pos] = data[2]; packetbuf_clear(); - pos = 3; - pos += packetutils_deserialize_atts(&data[pos], len - pos); - + pos = packetutils_deserialize_atts(&data[3], len - 3); + if(pos < 0) { + PRINTF("slip-radio: illegal packet attributes\n"); + return 1; + } + pos += 3; len -= pos; if(len > PACKETBUF_SIZE) { len = PACKETBUF_SIZE; @@ -109,11 +112,12 @@ slip_radio_cmd_handler(const uint8_t *data, int len) memcpy(packetbuf_dataptr(), &data[pos], len); packetbuf_set_datalen(len); - PRINTF("slip-radio: sending: %d\n", packetbuf_datalen()); + PRINTF("slip-radio: sending %u (%d bytes)\n", + data[2], packetbuf_datalen()); /* parse frame before sending to get addresses, etc. */ no_framer.parse(); - NETSTACK_MAC.send(&packet_sent, &packet_ids[packet_pos]); + NETSTACK_MAC.send(packet_sent, &packet_ids[packet_pos]); packet_pos++; if(packet_pos >= sizeof(packet_ids)) { diff --git a/platform/cc2530dk/contiki-conf.h b/platform/cc2530dk/contiki-conf.h index 27d7317d5..217579be5 100644 --- a/platform/cc2530dk/contiki-conf.h +++ b/platform/cc2530dk/contiki-conf.h @@ -24,7 +24,9 @@ #endif /* Verbose Startup? Turning this off saves plenty of bytes of CODE in HOME */ +#ifndef STARTUP_CONF_VERBOSE #define STARTUP_CONF_VERBOSE 0 +#endif /* More CODE space savings by turning off process names */ #define PROCESS_CONF_NO_PROCESS_NAMES 1 @@ -81,6 +83,15 @@ */ #define NETSTACK_CONF_SHORTCUTS 1 +/* + * By default we read our MAC from the (read-only) Information Page (primary + * location). In order to have a user-programmable mac, define this as 0 to + * use the secondary location (addresses 0xFFE8 - 0xFFEF on the last flash page) + */ +#ifndef CC2530_CONF_MAC_FROM_PRIMARY +#define CC2530_CONF_MAC_FROM_PRIMARY 1 +#endif + /* * Sensors * It is harmless to #define XYZ 1 diff --git a/platform/cc2530dk/contiki-main.c b/platform/cc2530dk/contiki-main.c index 63d42eaab..23cb272c1 100644 --- a/platform/cc2530dk/contiki-main.c +++ b/platform/cc2530dk/contiki-main.c @@ -27,22 +27,16 @@ PROCESS_NAME(viztool_process); #endif /*---------------------------------------------------------------------------*/ -#ifdef STARTUP_CONF_VERBOSE -#define STARTUP_VERBOSE STARTUP_CONF_VERBOSE -#else -#define STARTUP_VERBOSE 0 -#endif - -#if STARTUP_VERBOSE +#if STARTUP_CONF_VERBOSE #define PUTSTRING(...) putstring(__VA_ARGS__) #define PUTHEX(...) puthex(__VA_ARGS__) #define PUTBIN(...) putbin(__VA_ARGS__) #define PUTCHAR(...) putchar(__VA_ARGS__) #else -#define PUTSTRING(...) do {} while(0) -#define PUTHEX(...) do {} while(0) -#define PUTBIN(...) do {} while(0) -#define PUTCHAR(...) do {} while(0) +#define PUTSTRING(...) +#define PUTHEX(...) +#define PUTBIN(...) +#define PUTCHAR(...) #endif /*---------------------------------------------------------------------------*/ #if CLOCK_CONF_STACK_FRIENDLY @@ -86,25 +80,52 @@ fade(int l) static void set_rime_addr(void) { - uint8_t *addr_long = NULL; - uint16_t addr_short = 0; char i; +#if CC2530_CONF_MAC_FROM_PRIMARY __xdata unsigned char * macp = &X_IEEE_ADDR; +#else + __code unsigned char * macp = (__code unsigned char *) 0xFFE8; +#endif PUTSTRING("Rime is 0x"); PUTHEX(sizeof(rimeaddr_t)); PUTSTRING(" bytes long\n"); +#if CC2530_CONF_MAC_FROM_PRIMARY PUTSTRING("Reading MAC from Info Page\n"); +#else + PUTSTRING("Reading MAC from flash\n"); + + /* + * The MAC is always stored in 0xFFE8 of the highest BANK of our flash. This + * maps to address 0xFFF8 of our CODE segment, when this BANK is selected. + * Load the bank, read 8 bytes starting at 0xFFE8 and restore last BANK. + * Since we are called from main(), this MUST be BANK1 or something is very + * wrong. This code can be used even without a bankable firmware. + */ + + /* Don't interrupt us to make sure no BANK switching happens while working */ + DISABLE_INTERRUPTS(); + + /* Switch to the BANKn, + * map CODE: 0x8000 - 0xFFFF to FLASH: 0xn8000 - 0xnFFFF */ + FMAP = CC2530_LAST_FLASH_BANK; +#endif for(i = (RIMEADDR_SIZE - 1); i >= 0; --i) { rimeaddr_node_addr.u8[i] = *macp; macp++; } +#if !CC2530_CONF_MAC_FROM_PRIMARY + /* Remap 0x8000 - 0xFFFF to BANK1 */ + FMAP = 1; + ENABLE_INTERRUPTS(); +#endif + /* Now the address is stored MSB first */ -#if STARTUP_VERBOSE +#if STARTUP_CONF_VERBOSE PUTSTRING("Rime configured with address "); for(i = 0; i < RIMEADDR_SIZE - 1; i++) { PUTHEX(rimeaddr_node_addr.u8[i]); @@ -166,26 +187,12 @@ main(void) break; } - putstring("-F"); - switch(CHIPINFO0 & 0x70) { - case 0x40: - putstring("256, "); - break; - case 0x30: - putstring("128, "); - break; - case 0x20: - putstring("64, "); - break; - case 0x10: - putstring("32, "); - break; - } + putstring("-" CC2530_FLAVOR_STRING ", "); puthex(CHIPINFO1 + 1); putstring("KB SRAM\n"); PUTSTRING("\nSDCC Build:\n"); -#if STARTUP_VERBOSE +#if STARTUP_CONF_VERBOSE #ifdef HAVE_SDCC_BANKING PUTSTRING(" With Banking.\n"); #endif /* HAVE_SDCC_BANKING */ diff --git a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/MspMote.java b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/MspMote.java index 1e0662046..2b8789e00 100644 --- a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/MspMote.java +++ b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/MspMote.java @@ -64,7 +64,6 @@ import se.sics.mspsim.cli.LineListener; import se.sics.mspsim.cli.LineOutputStream; import se.sics.mspsim.core.EmulationException; import se.sics.mspsim.core.MSP430; -import se.sics.mspsim.core.MSP430Constants; import se.sics.mspsim.platform.GenericNode; import se.sics.mspsim.ui.JFrameWindowManager; import se.sics.mspsim.util.ComponentRegistry; @@ -138,6 +137,7 @@ public abstract class MspMote extends AbstractEmulatedMote implements Mote, Watc */ public void stopNextInstruction() { stopNextInstruction = true; + getCPU().stop(); } protected MoteInterfaceHandler createMoteInterfaceHandler() { @@ -220,7 +220,7 @@ public abstract class MspMote extends AbstractEmulatedMote implements Mote, Watc this.myCpu.setMonitorExec(true); this.myCpu.setTrace(0); /* TODO Enable */ - int[] memory = myCpu.getMemory(); + int[] memory = myCpu.memory; logger.info("Loading firmware from: " + fileELF.getAbsolutePath()); GUI.setProgressMessage("Loading " + fileELF.getName()); node.loadFirmware(((MspMoteType)getType()).getELF(), memory); @@ -481,7 +481,7 @@ public abstract class MspMote extends AbstractEmulatedMote implements Mote, Watc String name = mapEntry.getName(); return file + ":?:" + name; } - return String.format("*%02x", myCpu.reg[MSP430Constants.PC]); + return String.format("*%02x", pc); } catch (Exception e) { return null; } diff --git a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/MspMoteMemory.java b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/MspMoteMemory.java index 619851780..5c76b4696 100644 --- a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/MspMoteMemory.java +++ b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/MspMoteMemory.java @@ -36,21 +36,18 @@ import org.apache.log4j.Logger; import se.sics.cooja.AddressMemory; import se.sics.cooja.Mote; import se.sics.cooja.MoteMemory; -import se.sics.cooja.MoteTimeEvent; -import se.sics.cooja.TimeEvent; -import se.sics.mspsim.core.CPUMonitor; import se.sics.mspsim.core.MSP430; +import se.sics.mspsim.core.Memory.AccessMode; +import se.sics.mspsim.core.Memory.AccessType; import se.sics.mspsim.util.MapEntry; public class MspMoteMemory implements MoteMemory, AddressMemory { private static Logger logger = Logger.getLogger(MspMoteMemory.class); private final ArrayList mapEntries; - private MSP430 cpu; - private Mote mote; + private final MSP430 cpu; public MspMoteMemory(Mote mote, MapEntry[] allEntries, MSP430 cpu) { - this.mote = mote; this.mapEntries = new ArrayList(); for (MapEntry entry: allEntries) { @@ -191,7 +188,7 @@ public class MspMoteMemory implements MoteMemory, AddressMemory { } private ArrayList cpuMonitorArray = new ArrayList(); - class MemoryCPUMonitor implements CPUMonitor { + class MemoryCPUMonitor extends se.sics.mspsim.core.MemoryMonitor.Adapter { public final MemoryMonitor mm; public final int address; public final int size; @@ -202,22 +199,14 @@ public class MspMoteMemory implements MoteMemory, AddressMemory { this.size = size; } - public void cpuAction(int type, final int adr, int data) { - final MemoryEventType t; - if (type == CPUMonitor.MEMORY_WRITE) { - t = MemoryEventType.WRITE; - } else { - t = MemoryEventType.READ; - } + @Override + public void notifyReadAfter(int address, AccessMode mode, AccessType type) { + mm.memoryChanged(MspMoteMemory.this, MemoryEventType.READ, address); + } - /* XXX Workaround to avoid using soon-obsolete data argument. - * This causes a delay between memory rw and listener notifications */ - TimeEvent e = new MoteTimeEvent(mote, 0) { - public void execute(long time) { - mm.memoryChanged(MspMoteMemory.this, t, adr); - } - }; - mote.getSimulation().scheduleEvent(e, mote.getSimulation().getSimulationTime()); + @Override + public void notifyWriteAfter(int dstAddress, int data, AccessMode mode) { + mm.memoryChanged(MspMoteMemory.this, MemoryEventType.WRITE, dstAddress); } } diff --git a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/ESBLED.java b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/ESBLED.java index 6c21cb151..9dac2d3f7 100644 --- a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/ESBLED.java +++ b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/ESBLED.java @@ -68,7 +68,7 @@ public class ESBLED extends LED implements PortListener { /* Listen for port writes */ IOUnit unit = this.mote.getCPU().getIOUnit("Port 2"); if (unit instanceof IOPort) { - ((IOPort) unit).setPortListener(this); + ((IOPort) unit).addPortListener(this); } } diff --git a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/Exp5438LED.java b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/Exp5438LED.java index 4bf039da3..be2fdfcb8 100755 --- a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/Exp5438LED.java +++ b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/Exp5438LED.java @@ -72,7 +72,7 @@ public class Exp5438LED extends LED { IOUnit unit = mspMote.getCPU().getIOUnit("P1"); if (unit instanceof IOPort) { - ((IOPort) unit).setPortListener(new PortListener() { + ((IOPort) unit).addPortListener(new PortListener() { public void portWrite(IOPort source, int data) { redOn = (data & Exp5438Node.LEDS_CONF_RED) != 0; yellowOn = (data & Exp5438Node.LEDS_CONF_YELLOW) != 0; diff --git a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/MspDebugOutput.java b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/MspDebugOutput.java index ea189faa4..0fe83ec6c 100644 --- a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/MspDebugOutput.java +++ b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/MspDebugOutput.java @@ -43,7 +43,8 @@ import se.sics.cooja.Mote; import se.sics.cooja.interfaces.Log; import se.sics.cooja.mspmote.MspMote; import se.sics.cooja.mspmote.MspMoteMemory; -import se.sics.mspsim.core.CPUMonitor; +import se.sics.mspsim.core.Memory; +import se.sics.mspsim.core.MemoryMonitor; /** * Observes writes to a special (hardcoded) Contiki variable: cooja_debug_ptr. @@ -67,7 +68,7 @@ public class MspDebugOutput extends Log { private MspMoteMemory mem; private String lastLog = null; - private CPUMonitor cpuMonitor = null; + private MemoryMonitor memoryMonitor = null; public MspDebugOutput(Mote mote) { this.mote = (MspMote) mote; @@ -78,18 +79,15 @@ public class MspDebugOutput extends Log { return; } this.mote.getCPU().addWatchPoint(mem.getVariableAddress(CONTIKI_POINTER), - cpuMonitor = new CPUMonitor() { - public void cpuAction(int type, int adr, int data) { - if (type != MEMORY_WRITE) { - return; - } - - String msg = extractString(mem, data); - if (msg != null && msg.length() > 0) { - lastLog = "DEBUG: " + msg; - setChanged(); - notifyObservers(MspDebugOutput.this.mote); - } + memoryMonitor = new MemoryMonitor.Adapter() { + @Override + public void notifyWriteAfter(int adr, int data, Memory.AccessMode mode) { + String msg = extractString(mem, data); + if (msg != null && msg.length() > 0) { + lastLog = "DEBUG: " + msg; + setChanged(); + notifyObservers(MspDebugOutput.this.mote); + } } }); } @@ -138,8 +136,8 @@ public class MspDebugOutput extends Log { public void removed() { super.removed(); - if (cpuMonitor != null) { - mote.getCPU().removeWatchPoint(mem.getVariableAddress(CONTIKI_POINTER), cpuMonitor); + if (memoryMonitor != null) { + mote.getCPU().removeWatchPoint(mem.getVariableAddress(CONTIKI_POINTER), memoryMonitor); } } } diff --git a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/MspMoteID.java b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/MspMoteID.java index b3f0d455e..b87227312 100644 --- a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/MspMoteID.java +++ b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/MspMoteID.java @@ -39,12 +39,11 @@ import javax.swing.JPanel; import org.apache.log4j.Logger; import se.sics.cooja.Mote; -import se.sics.cooja.MoteTimeEvent; -import se.sics.cooja.Simulation; import se.sics.cooja.interfaces.MoteID; import se.sics.cooja.mspmote.MspMote; import se.sics.cooja.mspmote.MspMoteMemory; -import se.sics.mspsim.core.CPUMonitor; +import se.sics.mspsim.core.Memory; +import se.sics.mspsim.core.MemoryMonitor; /** * Mote ID. @@ -60,7 +59,7 @@ public class MspMoteID extends MoteID { private boolean writeFlashHeader = true; private int moteID = -1; - private CPUMonitor cpuMonitor; + private MemoryMonitor memoryMonitor; /** * Creates an interface to the mote ID at mote. @@ -110,41 +109,23 @@ public class MspMoteID extends MoteID { if (moteMem.variableExists("ActiveMessageAddressC$addr")) { moteMem.setIntValueOf("ActiveMessageAddressC$addr", newID); } - if (cpuMonitor == null) { - final MoteTimeEvent writeIDEvent = new MoteTimeEvent(mote, 0) { - public void execute(long t) { - setMoteID(moteID); + if (memoryMonitor == null) { + memoryMonitor = new MemoryMonitor.Adapter() { + + @Override + public void notifyWriteAfter(int dstAddress, int data, Memory.AccessMode mode) { + byte[] id = new byte[2]; + id[0] = (byte) (moteID & 0xff); + id[1] = (byte) ((moteID >> 8) & 0xff); + moteMem.setMemorySegment(dstAddress & ~1, id); } + }; - cpuMonitor = new CPUMonitor() { - public void cpuAction(int type, int address, int data) { - if (type != MEMORY_WRITE) { - return; - } - if (data == moteID) { - return; - } - if (writeIDEvent.isScheduled()) { - return; - } - Simulation s = mote.getSimulation(); - s.scheduleEvent(writeIDEvent, s.getSimulationTime()); - } - }; - - if (moteMem.variableExists("node_id")) { - this.mote.getCPU().addWatchPoint(moteMem.getVariableAddress("node_id"), cpuMonitor); - } - if (moteMem.variableExists("TOS_NODE_ID")) { - this.mote.getCPU().addWatchPoint(moteMem.getVariableAddress("TOS_NODE_ID"), cpuMonitor); - } - if (moteMem.variableExists("ActiveMessageAddressC__addr")) { - this.mote.getCPU().addWatchPoint(moteMem.getVariableAddress("ActiveMessageAddressC__addr"), cpuMonitor); - } - if (moteMem.variableExists("ActiveMessageAddressC$addr")) { - this.mote.getCPU().addWatchPoint(moteMem.getVariableAddress("ActiveMessageAddressC$addr"), cpuMonitor); - } + addMonitor("node_id", memoryMonitor); + addMonitor("TOS_NODE_ID", memoryMonitor); + addMonitor("ActiveMessageAddressC__addr", memoryMonitor); + addMonitor("ActiveMessageAddressC$addr", memoryMonitor); } notifyObservers(); @@ -182,20 +163,32 @@ public class MspMoteID extends MoteID { public void removed() { super.removed(); - if (cpuMonitor != null) { - if (moteMem.variableExists("node_id")) { - this.mote.getCPU().removeWatchPoint(moteMem.getVariableAddress("node_id"), cpuMonitor); - } - if (moteMem.variableExists("TOS_NODE_ID")) { - this.mote.getCPU().removeWatchPoint(moteMem.getVariableAddress("TOS_NODE_ID"), cpuMonitor); - } - if (moteMem.variableExists("ActiveMessageAddressC__addr")) { - this.mote.getCPU().removeWatchPoint(moteMem.getVariableAddress("ActiveMessageAddressC__addr"), cpuMonitor); - } - if (moteMem.variableExists("ActiveMessageAddressC$addr")) { - this.mote.getCPU().removeWatchPoint(moteMem.getVariableAddress("ActiveMessageAddressC$addr"), cpuMonitor); - } - cpuMonitor = null; + if (memoryMonitor != null) { + removeMonitor("node_id", memoryMonitor); + removeMonitor("TOS_NODE_ID", memoryMonitor); + removeMonitor("ActiveMessageAddressC__addr", memoryMonitor); + removeMonitor("ActiveMessageAddressC$addr", memoryMonitor); + memoryMonitor = null; } } + + private void addMonitor(String variable, MemoryMonitor monitor) { + if (moteMem.variableExists(variable)) { + int address = moteMem.getVariableAddress(variable); + if ((address & 1) != 0) { + // Variable can not be a word - must be a byte + } else { + mote.getCPU().addWatchPoint(address, monitor); + mote.getCPU().addWatchPoint(address + 1, monitor); + } + } + } + + private void removeMonitor(String variable, MemoryMonitor monitor) { + if (moteMem.variableExists(variable)) { + int address = moteMem.getVariableAddress(variable); + mote.getCPU().removeWatchPoint(address, monitor); + mote.getCPU().removeWatchPoint(address + 1, monitor); + } + } } diff --git a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/MspSerial.java b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/MspSerial.java index 714e33969..6b0ee14a3 100644 --- a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/MspSerial.java +++ b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/MspSerial.java @@ -73,7 +73,7 @@ public class MspSerial extends SerialUI implements SerialPort { IOUnit ioUnit = this.mote.getCPU().getIOUnit(ioConfigString()); if (ioUnit instanceof USARTSource) { usart = (USARTSource) ioUnit; - usart.setUSARTListener(new USARTListener() { + usart.addUSARTListener(new USARTListener() { public void dataReceived(USARTSource source, int data) { MspSerial.this.dataReceived(data); } diff --git a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/SkyByteRadio.java b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/SkyByteRadio.java index 18e98f09e..a0b1db589 100644 --- a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/SkyByteRadio.java +++ b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/SkyByteRadio.java @@ -46,6 +46,7 @@ import se.sics.cooja.interfaces.Radio; import se.sics.cooja.mspmote.MspMote; import se.sics.cooja.mspmote.MspMoteTimeEvent; import se.sics.mspsim.chip.CC2420; +import se.sics.mspsim.chip.ChannelListener; import se.sics.mspsim.chip.RFListener; import se.sics.mspsim.core.Chip; import se.sics.mspsim.core.OperatingModeListener; @@ -89,7 +90,7 @@ public class SkyByteRadio extends Radio implements CustomDataRadio { throw new IllegalStateException("Mote is not equipped with a CC2420"); } - cc2420.setRFListener(new RFListener() { + cc2420.addRFListener(new RFListener() { int len = 0; int expLen = 0; byte[] buffer = new byte[127 + 15]; @@ -158,8 +159,8 @@ public class SkyByteRadio extends Radio implements CustomDataRadio { } }); - cc2420.setChannelListener(new CC2420.ChannelListener() { - public void changedChannel(int channel) { + cc2420.addChannelListener(new ChannelListener() { + public void channelChanged(int channel) { /* XXX Currently assumes zero channel switch time */ lastEvent = RadioEvent.UNKNOWN; lastEventTime = SkyByteRadio.this.mote.getSimulation().getSimulationTime(); diff --git a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/SkyLED.java b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/SkyLED.java index da562f270..bb37ebf05 100644 --- a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/SkyLED.java +++ b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/SkyLED.java @@ -69,7 +69,7 @@ public class SkyLED extends LED { IOUnit unit = mspMote.getCPU().getIOUnit("Port 5"); if (unit instanceof IOPort) { - ((IOPort) unit).setPortListener(new PortListener() { + ((IOPort) unit).addPortListener(new PortListener() { public void portWrite(IOPort source, int data) { blueOn = (data & SkyNode.BLUE_LED) == 0; greenOn = (data & SkyNode.GREEN_LED) == 0; diff --git a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/TR1001Radio.java b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/TR1001Radio.java index d61d4994b..d873e579b 100644 --- a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/TR1001Radio.java +++ b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/TR1001Radio.java @@ -108,7 +108,7 @@ public class TR1001Radio extends Radio implements USARTListener, CustomDataRadio IOUnit usart = this.mote.getCPU().getIOUnit("USART 0"); if (usart != null && usart instanceof USART) { radioUSART = (USART) usart; - radioUSART.setUSARTListener(this); + radioUSART.addUSARTListener(this); } else { throw new RuntimeException("Bad TR1001 IO: " + usart); } diff --git a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/TyndallLED.java b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/TyndallLED.java index 9d7f0b902..ae71a7d50 100755 --- a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/TyndallLED.java +++ b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/TyndallLED.java @@ -73,7 +73,7 @@ public class TyndallLED extends LED { IOUnit unit = mspMote.getCPU().getIOUnit("P7"); if (unit instanceof IOPort) { - ((IOPort) unit).setPortListener(new PortListener() { + ((IOPort) unit).addPortListener(new PortListener() { public void portWrite(IOPort source, int data) { redOn = (data & TyndallNode.LEDS_CONF_RED) == 0; setChanged(); @@ -83,7 +83,7 @@ public class TyndallLED extends LED { } unit = mspMote.getCPU().getIOUnit("P8"); if (unit instanceof IOPort) { - ((IOPort) unit).setPortListener(new PortListener() { + ((IOPort) unit).addPortListener(new PortListener() { public void portWrite(IOPort source, int data) { greenOn = (data & TyndallNode.LEDS_CONF_GREEN) == 0; setChanged(); diff --git a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/plugins/MspBreakpoint.java b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/plugins/MspBreakpoint.java index e6d881e97..4735d4069 100644 --- a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/plugins/MspBreakpoint.java +++ b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/plugins/MspBreakpoint.java @@ -43,7 +43,8 @@ import org.jdom.Element; import se.sics.cooja.Watchpoint; import se.sics.cooja.mspmote.MspMote; import se.sics.cooja.util.StringUtils; -import se.sics.mspsim.core.CPUMonitor; +import se.sics.mspsim.core.Memory; +import se.sics.mspsim.core.MemoryMonitor; /** * Mspsim watchpoint. @@ -59,7 +60,7 @@ public class MspBreakpoint implements Watchpoint { private File codeFile = null; /* Source code, may be null*/ private int lineNr = -1; /* Source code line number, may be null */ - private CPUMonitor cpuMonitor = null; + private MemoryMonitor memoryMonitor = null; private boolean stopsSimulation = true; @@ -130,16 +131,17 @@ public class MspBreakpoint implements Watchpoint { } private void createMonitor() { - cpuMonitor = new CPUMonitor() { - public void cpuAction(int type, int adr, int data) { - if (type != CPUMonitor.EXECUTE) { + memoryMonitor = new MemoryMonitor.Adapter() { + @Override + public void notifyReadBefore(int addr, Memory.AccessMode mode, Memory.AccessType type) { + if (type != Memory.AccessType.EXECUTE) { return; } mspMote.signalBreakpointTrigger(MspBreakpoint.this); } }; - mspMote.getCPU().addWatchPoint(address, cpuMonitor); + mspMote.getCPU().addWatchPoint(address, memoryMonitor); /* Remember Contiki code, to verify it when reloaded */ @@ -156,7 +158,7 @@ public class MspBreakpoint implements Watchpoint { } public void unregisterBreakpoint() { - mspMote.getCPU().removeWatchPoint(address, cpuMonitor); + mspMote.getCPU().removeWatchPoint(address, memoryMonitor); } public Collection getConfigXML() { diff --git a/tools/mspsim/mspsim.jar b/tools/mspsim/mspsim.jar index fa3178fce..dd8a2482e 100644 Binary files a/tools/mspsim/mspsim.jar and b/tools/mspsim/mspsim.jar differ