From 63ea56256885b376d6fdfa3845bb81dbb8486924 Mon Sep 17 00:00:00 2001 From: simonduq Date: Mon, 26 Mar 2012 22:49:28 +0200 Subject: [PATCH 01/21] base encounter_time on the time before last strobe, remove unused previous_txtime --- core/net/mac/contikimac.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/core/net/mac/contikimac.c b/core/net/mac/contikimac.c index 93bf4f5ea..ded95cada 100644 --- a/core/net/mac/contikimac.c +++ b/core/net/mac/contikimac.c @@ -522,7 +522,7 @@ static int send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, struct rdc_buf_list *buf_list) { rtimer_clock_t t0; - rtimer_clock_t encounter_time = 0, previous_txtime = 0; + rtimer_clock_t encounter_time = 0; int strobes; uint8_t got_strobe_ack = 0; int hdrlen, len; @@ -723,7 +723,6 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, struct rdc_buf_ watchdog_periodic(); t0 = RTIMER_NOW(); seqno = packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO); - previous_txtime = RTIMER_NOW(); for(strobes = 0, collisions = 0; got_strobe_ack == 0 && collisions == 0 && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + STROBE_TIME); strobes++) { @@ -751,7 +750,7 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, struct rdc_buf_ if(ret == RADIO_TX_OK) { if(!is_broadcast) { got_strobe_ack = 1; - encounter_time = previous_txtime; + encounter_time = txtime; break; } } else if (ret == RADIO_TX_NOACK) { @@ -776,7 +775,7 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, struct rdc_buf_ len = NETSTACK_RADIO.read(ackbuf, ACK_LEN); if(len == ACK_LEN && seqno == ackbuf[ACK_LEN-1]) { got_strobe_ack = 1; - encounter_time = previous_txtime; + encounter_time = txtime; break; } else { PRINTF("contikimac: collisions while sending\n"); @@ -784,8 +783,6 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, struct rdc_buf_ } } #endif /* RDC_CONF_HARDWARE_ACK */ - - previous_txtime = txtime; } } From 10b41052008041bf7805baa740103756c5372345 Mon Sep 17 00:00:00 2001 From: simonduq Date: Mon, 26 Mar 2012 22:55:57 +0200 Subject: [PATCH 02/21] added %.ramprof and %.flashprof targets for easy memory profiling of linked binary (e.g. make hello-world.ramprof) --- Makefile.include | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Makefile.include b/Makefile.include index cf2d67d2c..64f3be221 100644 --- a/Makefile.include +++ b/Makefile.include @@ -228,6 +228,12 @@ ifndef CUSTOM_RULE_LINK $(LD) $(LDFLAGS) $(TARGET_STARTFILES) ${filter-out %.a,$^} ${filter %.a,$^} $(TARGET_LIBFILES) -o $@ endif +%.ramprof: %.$(TARGET) + nm -S -td --size-sort $< | grep -i " [abdrw] " | cut -d' ' -f2,4 + +%.flashprof: %.$(TARGET) + nm -S -td --size-sort $< | grep -i " [t] " | cut -d' ' -f2,4 + # Don't treat %.$(TARGET) as an intermediate file because it is # in fact the primary target. .PRECIOUS: %.$(TARGET) From ea85cc13965bacae81748b74637a458ccbb4a5fe Mon Sep 17 00:00:00 2001 From: simonduq Date: Fri, 23 Mar 2012 11:09:32 +0100 Subject: [PATCH 03/21] added motelist-linux for stm32w platforms --- tools/stm32w/motelist-linux | 280 ++++++++++++++++++++++++++++++++++++ 1 file changed, 280 insertions(+) create mode 100644 tools/stm32w/motelist-linux diff --git a/tools/stm32w/motelist-linux b/tools/stm32w/motelist-linux new file mode 100644 index 000000000..5a6be5f53 --- /dev/null +++ b/tools/stm32w/motelist-linux @@ -0,0 +1,280 @@ +#!/usr/bin/perl -w +use strict; +# $Id: motelist-linux,v 1.1 2007/05/29 19:34:30 adam Exp $ +# @author Cory Sharp +# @author Joe Polastre + +my $help = <<'EOF'; +usage: motelist [options] + + $Revision: 1.1 $ + +options: + -h display this help + -c compact format, not pretty but easier for parsing + -f specify the usb-serial file (for smote.cs) + -k kernel version: 2.4, 2.6, auto (default) + -m method to scan usb: procfs, sysfs, auto (default) + -dev_prefix force the device prefix for the serial device + -usb display extra usb information +EOF + +my %Opt = ( + compact => 0, + usb => 0, + method => "auto", + kernel => "auto", + dev_prefix => [ "/dev/usb/tts/", "/dev/ttyUSB", "/dev/tts/USB" ], + usbserial => "sudo cat /proc/tty/driver/usbserial |", +); + +while (@ARGV) { + last unless $ARGV[0] =~ /^-/; + my $opt = shift @ARGV; + if( $opt eq "-h" ) { print "$help\n"; exit 0; } + elsif( $opt eq "-c" ) { $Opt{compact} = 1; } + elsif( $opt eq "-f" ) { $Opt{usbserial} = shift @ARGV; } + elsif( $opt eq "-k" ) { $Opt{kernel} = shift @ARGV; } + elsif( $opt eq "-m" ) { $Opt{method} = shift @ARGV; } + elsif( $opt eq "-dev_prefix" ) { $Opt{dev_prefix} = shift @ARGV; } + elsif( $opt eq "-usb" ) { $Opt{usb} = 1; } + else { print STDERR "$help\nerror, unknown command line option $opt\n"; exit 1; } +} + +if( $Opt{kernel} eq "auto" ) { + $Opt{kernel} = "unknown"; + $Opt{kernel} = $1 if snarf("/proc/version") =~ /\bLinux version (\d+\.\d+)/; +} + +if( $Opt{method} eq "auto" ) { + $Opt{method} = ($Opt{kernel} eq "2.4") ? "procfs" : "sysfs"; +} + +my @devs = $Opt{method} eq "procfs" ? scan_procfs() : scan_sysfs(); +print_motelist( sort { cmp_usbdev($a,$b) } @devs ); + + +# +# SysFS +# +sub scan_sysfs { + + # Scan /sys/bus/usb/drivers/usb for FTDI devices + my @ftdidevs = + grep { ($_->{UsbVendor}||"") eq "0403" && ($_->{UsbProduct}||"") eq "6001" && ($_->{UsbBcdDevice}||"") eq "0600"} + map { { + SysPath => $_, + UsbVendor => snarf("$_/idVendor",1), + UsbProduct => snarf("$_/idProduct",1), + UsbBcdDevice => snarf("$_/bcdDevice",1), + } } + glob("/sys/bus/usb/drivers/usb/*"); + + # Gather information about each FTDI device + for my $f (@ftdidevs) { + my $syspath = $f->{SysPath}; + + $f->{InfoManufacturer} = snarf("$syspath/manufacturer",1); + $f->{InfoProduct} = snarf("$syspath/product",1); + $f->{InfoSerial} = snarf("$syspath/serial",1); + $f->{UsbDevNum} = snarf("$syspath/devnum",1); + print $syspath; + print "\n"; + + my $devstr = readlink($syspath); + if( $devstr =~ m{([^/]+)/usb(\d+)/.*-([^/]+)$} ) { + $f->{UsbPath} = "usb-$1-$3"; + $f->{UsbBusNum} = $2; + } + ($f->{SysDev} = $syspath) =~ s{^.*/}{}; + + my $port = "$syspath/$f->{SysDev}:1.0"; + ($f->{DriverName} = readlink("$port/driver")) =~ s{^.*/}{} if -l "$port/driver"; + ($f->{SerialDevName} = (glob("$port/tty*"),undef)[0]) =~ s{^.*/}{}; + $f->{SerialDevNum} = $1 if $f->{SerialDevName} =~ /(\d+)/; + $f->{SerialDevName} = getSerialDevName( $f->{SerialDevNum} ) || " (none)"; + } + + return @ftdidevs; +} + + +# +# Scan Procfs +# +sub scan_procfs { + + my $text_devs = snarf("< /proc/bus/usb/devices"); + my $text_serial = snarf($Opt{usbserial}); + + my @usbdevs = map { {parse_usb_devices_text($_)} } + grep { !/^\s*$/ } split /\n+(?=T:)/, $text_devs; + my %usbtree = build_usb_tree( @usbdevs ); + my %usbserialtree = build_usbserial_tree( $text_serial ); + for my $tts ( values %usbserialtree ) { + $usbtree{usbkey($tts->{path})}{usbserial} = $tts if defined $tts->{path}; + } + + my @ftdidevs = map { { + UsbVendor => $_->{Vendor}, + UsbProduct => $_->{ProdID}, + UsbBcdDevice => $_->{BcdDevice}, + InfoManufacturer => $_->{Manufacturer}, + InfoProduct => $_->{Product}, + InfoSerial => $_->{SerialNumber}, + UsbBusNum => $_->{nbus}, + UsbDevNum => $_->{ndev}, + UsbPath => (($Opt{kernel} eq "2.4") ? $_->{usbserial}{path} : $_->{usbpath}), + DriverName => $_->{driver}, + SerialDevNum => $_->{usbserial}{tts}, + SerialDevName => getSerialDevName($_->{usbserial}{tts}) || " (none)", + } } + grep { ($_->{Vendor}||"") eq "0403" && ($_->{ProdID}||"") eq "6001" && ($_->{BcdDevice}||"") eq "0600"} + values %usbtree; + + return @ftdidevs; +} + +sub build_usb_tree { + my @devs = @_; + my %tree = (); + for my $dev (sort { $a->{Lev} <=> $b->{Lev} } @devs) { + my ($bus,$lev,$prnt) = ( $dev->{Bus}+0, $dev->{Lev}+0, $dev->{Prnt}+0 ); + my $devnum = $dev->{"Dev#"}+0; + $dev->{nbus} = $bus; + $dev->{ndev} = $devnum; + $tree{"bus$bus"} = {} unless exists $tree{"bus$bus"}; + $tree{"bus$bus"}{"dev$devnum"} = $dev; + if( $lev == 0 ) { + $dev->{usbpath} = "usb-$dev->{SerialNumber}"; + } else { + my $sep = ($lev==1) ? "-" : "."; + $dev->{parent} = $tree{"bus$bus"}{"dev$prnt"}; + $dev->{usbpath} = $dev->{parent}{usbpath} . $sep . ($dev->{Port}+1); + } + $tree{usbkey($dev->{usbpath})} = $dev; + } + return %tree; +} + +sub parse_usb_devices_text { + my $text = shift; + $text =~ s/^\S+\s*//gm; + $text =~ s/\s*(\S+=)/\001$1/g; + return map { m/(.*?)=(.*)/ } split /\001/, $text; +} + +sub build_usbserial_tree { + my $text = shift; + my %tree = (); + while( $text =~ /^([^:]+):(.*)/mg ) { + my ($tts,$params) = ($1,$2); + $tree{$tts} = { tts => $tts }; + while ($params =~ m/\s+([^:]+):(?:"([^"]*)"|(\S+))/g) { + $tree{$tts}{$1} = $2||$3; + } + } + return %tree; +} + +sub usbkey { + if( $Opt{kernel} eq "2.4" ) { + (my $key = $_[0]) =~ s/^.*-//; + return $key; + } + return $_[0]; +} + + +# +# getSerialDevName +# +# For each device, force to use dev_prefix if it's not an array. Otherwise, +# assume it's a list of candidate prefixes. Check them and commit to the +# first one that actually exists. +# +sub getSerialDevName { + my $devnum = shift; + my $devname = undef; + if( defined $devnum ) { + if( ref($Opt{dev_prefix}) eq "ARRAY" ) { + $devname = $devnum; + for my $prefix (@{$Opt{dev_prefix}}) { + my $file = $prefix . $devnum; + if( -e $file ) { $devname = $file; last; } + } + } else { + $devname = $Opt{dev_prefix} . $devnum; + } + } + return $devname; +} + + +# +# Print motelist +# +sub print_motelist { + my @devs = @_; + + # If none were found, quit + if( @devs == 0 ) { + print "No devices found.\n"; + return; + } + + # Print a header + if( !$Opt{compact} ) { + if( $Opt{usb} ) { + print << "EOF" unless $Opt{compact}; +Bus Dev USB Path Reference Device Description +--- --- ------------------------ ---------- ---------------- ------------------------------------- +EOF + } else { + print << "EOF" unless $Opt{compact}; +Reference Device Description +---------- ---------------- --------------------------------------------- +EOF + } + } + + # Print the usb information + for my $dev (sort { cmp_usbdev($a,$b) } @devs) { + my $desc = join( " ", $dev->{InfoManufacturer}||"", $dev->{InfoProduct}||"" ) || " (none)"; + my @output = ( $dev->{InfoSerial}||" (none)", $dev->{SerialDevName}, $desc ); + @output = ( $dev->{UsbBusNum}, $dev->{UsbDevNum}, $dev->{UsbPath}, @output ) if $Opt{usb}; + if( $Opt{compact} ) { + print join(",",@output) . "\n"; + } else { + printf( ($Opt{usb}?"%3d %3d %-24s ":"")."%-10s %-16s %s\n", @output ); + } + } +} + + +# +# Cmp Usbdev's +# +sub cmp_usbdev { + my ($a,$b) = @_; + if( defined $a->{SerialDevNum} ) { + if( defined $b->{SerialDevNum} ) { + return $a->{SerialDevNum} <=> $b->{SerialDevNum}; + } + return -1; + } + return 1 if defined $b->{SerialDevNum}; + return ($a->{InfoSerial}||"") cmp ($b->{InfoSerial}||""); +} + +# +# Read a file in +# +sub snarf { + open my $fh, $_[0] or return undef; + my $text = do{local $/;<$fh>}; + close $fh; + $text =~ s/\s+$// if $_[1]; + return $text; +} + From 95ae5c5d516e73bc4e93d692e38b9d1930568016 Mon Sep 17 00:00:00 2001 From: simonduq Date: Fri, 23 Mar 2012 19:54:11 +0100 Subject: [PATCH 04/21] avoid unnecessary symbols.c/h copying --- cpu/msp430/Makefile.msp430 | 2 +- cpu/stm32w108/Makefile.stm32w108 | 2 +- cpu/x86/Makefile.x86 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cpu/msp430/Makefile.msp430 b/cpu/msp430/Makefile.msp430 index 7d71d4029..4057b3c5a 100644 --- a/cpu/msp430/Makefile.msp430 +++ b/cpu/msp430/Makefile.msp430 @@ -166,8 +166,8 @@ loader-init.o: ${CONTIKI_TARGET}/loader/loader-init.S $(AS) -o $(notdir $(<:.S=.o)) $< # cp loader-init.o build-app/ -.PHONY: symbols.c symbols.h ifdef CORE +.PHONY: symbols.c symbols.h symbols.c: $(NM) $(CORE) | awk -f $(CONTIKI)/tools/mknmlist > symbols.c else diff --git a/cpu/stm32w108/Makefile.stm32w108 b/cpu/stm32w108/Makefile.stm32w108 index 7eae06d4c..8fbb1e9b6 100644 --- a/cpu/stm32w108/Makefile.stm32w108 +++ b/cpu/stm32w108/Makefile.stm32w108 @@ -224,11 +224,11 @@ CUSTOM_RULE_C_TO_CE = 1 CUSTOM_RULE_LINK = 1 -.PHONY: symbols.c symbols.h ifdef CORE ifeq ($(wildcard $(CORE)),) ${error $(CORE) doesn't exist} endif +.PHONY: symbols.c symbols.h symbols.c: $(NM) $(CORE) | awk -f $(CONTIKI)/tools/mknmlist > symbols.c else diff --git a/cpu/x86/Makefile.x86 b/cpu/x86/Makefile.x86 index 612603f52..0aececd4d 100644 --- a/cpu/x86/Makefile.x86 +++ b/cpu/x86/Makefile.x86 @@ -21,8 +21,8 @@ endif %.so: $(OBJECTDIR)/%.o $(LD) -shared -o $@ $^ -# .PHONY: symbols.c symbols.h ifdef CORE +.PHONY: symbols.c symbols.h symbols.c symbols.h: $(NM) $(CORE) | awk -f $(CONTIKI)/tools/mknmlist > symbols.c else From 946f00bf7b52b16a67b53821abd0809f725e1d33 Mon Sep 17 00:00:00 2001 From: simonduq Date: Mon, 26 Mar 2012 10:56:01 +0200 Subject: [PATCH 05/21] stm32w: added ability to upload and reset all connected boards, and login using MOTE=x --- cpu/stm32w108/Makefile.stm32w108 | 47 ++++++++++++++++++++++++++++---- platform/mb851/Makefile.mb851 | 5 ---- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/cpu/stm32w108/Makefile.stm32w108 b/cpu/stm32w108/Makefile.stm32w108 index 8fbb1e9b6..c408f7c16 100644 --- a/cpu/stm32w108/Makefile.stm32w108 +++ b/cpu/stm32w108/Makefile.stm32w108 @@ -1,6 +1,11 @@ .SUFFIXES: +define \n + + +endef + ifdef IAR ${info Using IAR...} #IAR_PATH = C:/Program\ Files/IAR\ Systems/Embedded\ Workbench\ 5.4\ Evaluation @@ -18,7 +23,7 @@ CONTIKI_CPU_DIRS = . dev hal simplemac hal/micro/cortexm3 hal/micro/cortexm3/stm STM32W_C = leds-arch.c leds.c clock.c watchdog.c uart1.c uart1-putchar.c slip_uart1.c slip.c\ stm32w-radio.c stm32w_systick.c uip_arch.c rtimer-arch.c adc.c micro.c sleep.c \ - micro-common.c micro-common-internal.c clocks.c mfg-token.c nvm.c flash.c rand.c system-timer.c + micro-common.c micro-common-internal.c clocks.c mfg-token.c nvm.c flash.c rand.c system-timer.c mpu.c STM32W_S = spmr.s79 context-switch.s79 @@ -163,7 +168,7 @@ endif -FLASHER = $(CONTIKI)/tools/stm32w/stm32w_flasher/stm32w_flasher +FLASHER = sudo $(CONTIKI)/tools/stm32w/stm32w_flasher/stm32w_flasher # Check if we are running under Windows ifeq ($(HOST_OS),Windows) @@ -250,6 +255,19 @@ endif endif #IAR +MOTELIST = $(CONTIKI)/tools/stm32w/motelist-linux + +MOTES = $(shell $(MOTELIST) 2>&- | grep USB | \ + cut -f 4 -d \ | \ + perl -ne 'print $$1 . " " if(m-(/dev/\w+)-);') + +motelist: stm-motelist + +stm-motelist: + $(MOTELIST) +stm-motes: + @echo $(MOTES) + $(OBJECTDIR)/%.o: %.s79 $(AS) $(ASFLAGS) -o $@ $< @@ -258,7 +276,24 @@ $(OBJECTDIR)/%.o: %.s %.bin: %.$(TARGET) $(OBJCOPY) $(OBJOPTS) $< $@ - -%.flash: %.bin - $(FLASHER) $(FLASHEROPTS) $< - + +# reset all stm32w devices sequentially, as stm32w_flasher cannot access different ports in parallel +stm-reset: + $(foreach PORT, $(MOTES), $(FLASHER) -r -p $(PORT);$(\n)) + @echo Done + +ifdef MOTE +%.upload: %.bin + $(FLASHER) $(FLASHEROPTS) $< -p $(word $(MOTE), $(MOTES)) +else # MOTE +%.upload: %.bin + $(foreach PORT, $(MOTES), $(FLASHER) $(FLASHEROPTS) $< -p $(PORT);$(\n)) +endif # MOTE + +ifdef MOTE +login: + $(SERIALDUMP) -b115200 -d10000 $(USBDEVPREFIX)$(word $(MOTE), $(MOTES)) +else +login: + $(SERIALDUMP) -b115200 -d10000 $(USBDEVPREFIX)$(firstword $(MOTES)) +endif diff --git a/platform/mb851/Makefile.mb851 b/platform/mb851/Makefile.mb851 index ba3ac91a2..4b24b82b2 100644 --- a/platform/mb851/Makefile.mb851 +++ b/platform/mb851/Makefile.mb851 @@ -22,8 +22,3 @@ SERIALDUMP = $(CONTIKI)/tools/stm32w/serialdump-linux ifeq ($(HOST_OS),Windows) SERIALDUMP = $(CONTIKI)/tools/stm32w/serialdump-windows endif - - - -login: - $(SERIALDUMP) -b115200 -d10000 $(PORT) From c6b3a9957d969e31e2bc8dc5559001f46a1087d9 Mon Sep 17 00:00:00 2001 From: Ivan Delamer Date: Mon, 26 Mar 2012 14:53:57 -0600 Subject: [PATCH 06/21] Ignore 6LowPAN fragments which won't fit in UIP_BUFSIZE (in case UIP_BUFSIZE < 1280). Otherwise we'll have a buffer overrun. --- core/net/sicslowpan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/net/sicslowpan.c b/core/net/sicslowpan.c index cfc11f943..319bb5b01 100644 --- a/core/net/sicslowpan.c +++ b/core/net/sicslowpan.c @@ -1624,7 +1624,7 @@ input(void) * reassembly is off * start it if we received a fragment */ - if(frag_size > 0) { + if((frag_size > 0) && (frag_size <= UIP_BUFSIZE)) { sicslowpan_len = frag_size; reass_tag = frag_tag; timer_set(&reass_timer, SICSLOWPAN_REASS_MAXAGE*CLOCK_SECOND); From 436cbec844fc6f8c3da51afb66250395866b9893 Mon Sep 17 00:00:00 2001 From: Ivan Delamer Date: Mon, 26 Mar 2012 15:19:02 -0600 Subject: [PATCH 07/21] Separated processed_ip_len into processed_ip_in_len and processed_ip_out_len to avoid corruption, in case we send a packet in the middle of receiving a fragmented packet. --- core/net/sicslowpan.c | 55 ++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/core/net/sicslowpan.c b/core/net/sicslowpan.c index 319bb5b01..442b36b73 100644 --- a/core/net/sicslowpan.c +++ b/core/net/sicslowpan.c @@ -234,7 +234,7 @@ static uip_buf_t sicslowpan_aligned_buf; * length of the ip packet already sent / received. * It includes IP and transport headers. */ -static uint16_t processed_ip_len; +static uint16_t processed_ip_in_len; /** Datagram tag to be put in the fragments I send. */ static uint16_t my_tag; @@ -1353,6 +1353,9 @@ output(uip_lladdr_t *localdest) /* The MAC address of the destination of the packet */ rimeaddr_t dest; + /* Number of bytes processed. */ + uint16_t processed_ip_out_len; + /* init */ uncomp_hdr_len = 0; rime_hdr_len = 0; @@ -1443,6 +1446,7 @@ output(uip_lladdr_t *localdest) ((SICSLOWPAN_DISPATCH_FRAG1 << 8) | uip_len)); /* RIME_FRAG_BUF->tag = uip_htons(my_tag); */ SET16(RIME_FRAG_PTR, RIME_FRAG_TAG, my_tag); + my_tag++; /* Copy payload and send */ rime_hdr_len += SICSLOWPAN_FRAG1_HDR_LEN; @@ -1461,8 +1465,8 @@ output(uip_lladdr_t *localdest) queuebuf_free(q); q = NULL; - /* set processed_ip_len to what we already sent from the IP payload*/ - processed_ip_len = rime_payload_len + uncomp_hdr_len; + /* set processed_ip_out_len to what we already sent from the IP payload*/ + processed_ip_out_len = rime_payload_len + uncomp_hdr_len; /* * Create following fragments @@ -1475,19 +1479,19 @@ output(uip_lladdr_t *localdest) SET16(RIME_FRAG_PTR, RIME_FRAG_DISPATCH_SIZE, ((SICSLOWPAN_DISPATCH_FRAGN << 8) | uip_len)); rime_payload_len = (MAC_MAX_PAYLOAD - rime_hdr_len) & 0xf8; - while(processed_ip_len < uip_len) { + while(processed_ip_out_len < uip_len) { PRINTFO("sicslowpan output: fragment "); - RIME_FRAG_PTR[RIME_FRAG_OFFSET] = processed_ip_len >> 3; + RIME_FRAG_PTR[RIME_FRAG_OFFSET] = processed_ip_out_len >> 3; /* Copy payload and send */ - if(uip_len - processed_ip_len < rime_payload_len) { + if(uip_len - processed_ip_out_len < rime_payload_len) { /* last fragment */ - rime_payload_len = uip_len - processed_ip_len; + rime_payload_len = uip_len - processed_ip_out_len; } PRINTFO("(offset %d, len %d, tag %d)\n", - processed_ip_len >> 3, rime_payload_len, my_tag); + processed_ip_out_len >> 3, rime_payload_len, my_tag); memcpy(rime_ptr + rime_hdr_len, - (uint8_t *)UIP_IP_BUF + processed_ip_len, rime_payload_len); + (uint8_t *)UIP_IP_BUF + processed_ip_out_len, rime_payload_len); packetbuf_set_datalen(rime_payload_len + rime_hdr_len); q = queuebuf_new_from_packetbuf(); if(q == NULL) { @@ -1498,12 +1502,9 @@ output(uip_lladdr_t *localdest) queuebuf_to_packetbuf(q); queuebuf_free(q); q = NULL; - processed_ip_len += rime_payload_len; + processed_ip_out_len += rime_payload_len; } - /* end: reset global variables */ - my_tag++; - processed_ip_len = 0; #else /* SICSLOWPAN_CONF_FRAG */ PRINTFO("sicslowpan output: Packet too large to be sent without fragmentation support; dropping packet\n"); return 0; @@ -1558,7 +1559,7 @@ input(void) /* if reassembly timed out, cancel it */ if(timer_expired(&reass_timer)) { sicslowpan_len = 0; - processed_ip_len = 0; + processed_ip_in_len = 0; } /* * Since we don't support the mesh and broadcast header, the first header @@ -1593,10 +1594,10 @@ input(void) /* If this is the last fragment, we may shave off any extrenous bytes at the end. We must be liberal in what we accept. */ - PRINTFI("last_fragment?: processed_ip_len %d rime_payload_len %d frag_size %d\n", - processed_ip_len, packetbuf_datalen() - rime_hdr_len, frag_size); + PRINTFI("last_fragment?: processed_ip_in_len %d rime_payload_len %d frag_size %d\n", + processed_ip_in_len, packetbuf_datalen() - rime_hdr_len, frag_size); - if(processed_ip_len + packetbuf_datalen() - rime_hdr_len >= frag_size) { + if(processed_ip_in_len + packetbuf_datalen() - rime_hdr_len >= frag_size) { last_fragment = 1; } break; @@ -1604,7 +1605,7 @@ input(void) break; } - if(processed_ip_len > 0) { + if(processed_ip_in_len > 0) { /* reassembly is ongoing */ /* printf("frag %d %d\n", reass_tag, frag_tag);*/ if((frag_size > 0 && @@ -1690,22 +1691,22 @@ input(void) rime_payload_len = packetbuf_datalen() - rime_hdr_len; memcpy((uint8_t *)SICSLOWPAN_IP_BUF + uncomp_hdr_len + (uint16_t)(frag_offset << 3), rime_ptr + rime_hdr_len, rime_payload_len); - /* update processed_ip_len if fragment, sicslowpan_len otherwise */ + /* update processed_ip_in_len if fragment, sicslowpan_len otherwise */ #if SICSLOWPAN_CONF_FRAG if(frag_size > 0) { /* Add the size of the header only for the first fragment. */ if(first_fragment != 0) { - processed_ip_len += uncomp_hdr_len; + processed_ip_in_len += uncomp_hdr_len; } /* For the last fragment, we are OK if there is extrenous bytes at the end of the packet. */ if(last_fragment != 0) { - processed_ip_len = frag_size; + processed_ip_in_len = frag_size; } else { - processed_ip_len += rime_payload_len; + processed_ip_in_len += rime_payload_len; } - PRINTF("processed_ip_len %d, rime_payload_len %d\n", processed_ip_len, rime_payload_len); + PRINTF("processed_ip_in_len %d, rime_payload_len %d\n", processed_ip_in_len, rime_payload_len); } else { #endif /* SICSLOWPAN_CONF_FRAG */ @@ -1717,15 +1718,15 @@ input(void) * If we have a full IP packet in sicslowpan_buf, deliver it to * the IP stack */ - PRINTF("sicslowpan_init processed_ip_len %d, sicslowpan_len %d\n", - processed_ip_len, sicslowpan_len); - if(processed_ip_len == 0 || (processed_ip_len == sicslowpan_len)) { + PRINTF("sicslowpan_init processed_ip_in_len %d, sicslowpan_len %d\n", + processed_ip_in_len, sicslowpan_len); + if(processed_ip_in_len == 0 || (processed_ip_in_len == sicslowpan_len)) { PRINTFI("sicslowpan input: IP packet ready (length %d)\n", sicslowpan_len); memcpy((uint8_t *)UIP_IP_BUF, (uint8_t *)SICSLOWPAN_IP_BUF, sicslowpan_len); uip_len = sicslowpan_len; sicslowpan_len = 0; - processed_ip_len = 0; + processed_ip_in_len = 0; #endif /* SICSLOWPAN_CONF_FRAG */ #if DEBUG From f9d5d71fde627e9418870789147594a09994b188 Mon Sep 17 00:00:00 2001 From: Ivan Delamer Date: Mon, 26 Mar 2012 15:37:17 -0600 Subject: [PATCH 08/21] 6LowPAN: check tx result, if fail then do not send subsequent fragments. Serves to save energy and also as collision avoidance. --- core/net/sicslowpan.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/core/net/sicslowpan.c b/core/net/sicslowpan.c index 442b36b73..7a5cdccdd 100644 --- a/core/net/sicslowpan.c +++ b/core/net/sicslowpan.c @@ -211,6 +211,11 @@ static uint8_t rime_payload_len; * is used this includes the UDP header in addition to the IP header). */ static uint8_t uncomp_hdr_len; + +/** + * the result of the last transmitted fragment + */ +static int last_tx_status; /** @} */ #if SICSLOWPAN_CONF_FRAG @@ -1308,6 +1313,7 @@ packet_sent(void *ptr, int status, int transmissions) if(callback != NULL) { callback->output_callback(status); } + last_tx_status = status; } /*--------------------------------------------------------------------*/ /** @@ -1465,6 +1471,14 @@ output(uip_lladdr_t *localdest) queuebuf_free(q); q = NULL; + /* Check tx result. */ + if((last_tx_status == MAC_TX_COLLISION) || + (last_tx_status == MAC_TX_ERR) || + (last_tx_status == MAC_TX_ERR_FATAL)) { + PRINTFO("error in fragment tx, dropping subsequent fragments.\n"); + return 0; + } + /* set processed_ip_out_len to what we already sent from the IP payload*/ processed_ip_out_len = rime_payload_len + uncomp_hdr_len; @@ -1503,8 +1517,15 @@ output(uip_lladdr_t *localdest) queuebuf_free(q); q = NULL; processed_ip_out_len += rime_payload_len; + + /* Check tx result. */ + if((last_tx_status == MAC_TX_COLLISION) || + (last_tx_status == MAC_TX_ERR) || + (last_tx_status == MAC_TX_ERR_FATAL)) { + PRINTFO("error in fragment tx, dropping subsequent fragments.\n"); + return 0; + } } - #else /* SICSLOWPAN_CONF_FRAG */ PRINTFO("sicslowpan output: Packet too large to be sent without fragmentation support; dropping packet\n"); return 0; From 7482fd696231371e854c4237666aea6a982a82a2 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Tue, 27 Mar 2012 11:09:54 +0200 Subject: [PATCH 09/21] quick fix for enabling native-border router to run under windows - need to cleanup the arguments --- platform/native/contiki-main.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/platform/native/contiki-main.c b/platform/native/contiki-main.c index 7a0be95bf..a870670cb 100644 --- a/platform/native/contiki-main.c +++ b/platform/native/contiki-main.c @@ -172,6 +172,18 @@ main(int argc, char **argv) contiki_argc = argc; contiki_argv = argv; + /* native under windows is hardcoded to use the first one or two args */ + /* for wpcap configuration so this needs to be "removed" from */ + /* contiki_args (used by the native-border-router) */ +#ifdef __CYGWIN__ + contiki_argc--; + contiki_argv++; +#ifdef UIP_FALLBACK_INTERFACE + contiki_argc--; + contiki_argv++; +#endif +#endif + process_init(); process_start(&etimer_process, NULL); ctimer_init(); From 419ffddd0a90307afe463fbfd5a40dcaa80d9600 Mon Sep 17 00:00:00 2001 From: Ivan Delamer Date: Tue, 27 Mar 2012 18:04:51 -0600 Subject: [PATCH 10/21] remove unnecessary stimer call in tcpip_ipv6_output() --- core/net/tcpip.c | 1 - 1 file changed, 1 deletion(-) diff --git a/core/net/tcpip.c b/core/net/tcpip.c index e65123f0b..fda1b519f 100644 --- a/core/net/tcpip.c +++ b/core/net/tcpip.c @@ -643,7 +643,6 @@ tcpip_ipv6_output(void) PRINTF("tcpip_ipv6_output: nbr cache entry stale moving to delay\n"); } - stimer_set(&nbr->sendns, uip_ds6_if.retrans_timer / 1000); tcpip_output(&nbr->lladdr); #if UIP_CONF_IPV6_QUEUE_PKT From 51e399905434a77e2c388ba0dffe504dcf440640 Mon Sep 17 00:00:00 2001 From: Ivan Delamer Date: Tue, 27 Mar 2012 18:06:48 -0600 Subject: [PATCH 11/21] Simplified reachability detections by sending probes only in PROBE state. --- core/net/uip-ds6.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/core/net/uip-ds6.c b/core/net/uip-ds6.c index ad4f9ab9c..9cc4a4c6b 100644 --- a/core/net/uip-ds6.c +++ b/core/net/uip-ds6.c @@ -212,12 +212,11 @@ uip_ds6_periodic(void) } break; case NBR_DELAY: - if(stimer_expired(&locnbr->reachable) && (uip_len == 0)) { + if(stimer_expired(&locnbr->reachable)) { locnbr->state = NBR_PROBE; - locnbr->nscount = 1; - PRINTF("DELAY: moving to PROBE + NS %u\n", locnbr->nscount); - uip_nd6_ns_output(NULL, &locnbr->ipaddr, &locnbr->ipaddr); - stimer_set(&locnbr->sendns, uip_ds6_if.retrans_timer / 1000); + locnbr->nscount = 0; + PRINTF("DELAY: moving to PROBE\n"); + stimer_set(&locnbr->sendns, 0); } break; case NBR_PROBE: From 5c232e7263af3ca0548e992bff83bd7f20e5d21c Mon Sep 17 00:00:00 2001 From: Ivan Delamer Date: Tue, 27 Mar 2012 19:48:26 -0600 Subject: [PATCH 12/21] Remove compiler warning for remove_ext_header(). --- core/net/tcpip.c | 1 + 1 file changed, 1 insertion(+) diff --git a/core/net/tcpip.c b/core/net/tcpip.c index fda1b519f..f6184144a 100644 --- a/core/net/tcpip.c +++ b/core/net/tcpip.c @@ -570,6 +570,7 @@ tcpip_ipv6_output(void) PRINTF("FALLBACK: removing ext hdrs & setting proto %d %d\n", uip_ext_len, *((uint8_t *)UIP_IP_BUF + 40)); if(uip_ext_len > 0) { + extern void remove_ext_hdr(void); uint8_t proto = *((uint8_t *)UIP_IP_BUF + 40); remove_ext_hdr(); /* This should be copied from the ext header... */ From 21663c1033f3d4dab3c497dac2a3c5fa9ef95ba0 Mon Sep 17 00:00:00 2001 From: Fredrik Osterlind Date: Wed, 28 Mar 2012 10:45:12 +0200 Subject: [PATCH 13/21] removed debugging output --- tools/cooja/java/se/sics/cooja/plugins/ScriptRunner.java | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/cooja/java/se/sics/cooja/plugins/ScriptRunner.java b/tools/cooja/java/se/sics/cooja/plugins/ScriptRunner.java index d67d86384..e1729e8e0 100644 --- a/tools/cooja/java/se/sics/cooja/plugins/ScriptRunner.java +++ b/tools/cooja/java/se/sics/cooja/plugins/ScriptRunner.java @@ -696,7 +696,6 @@ public class ScriptRunner extends VisPlugin { } }); if (fileChooser.showOpenDialog(scriptRunner) != JFileChooser.APPROVE_OPTION) { - logger.debug("cancel"); return; } scriptRunner.setLinkFile(fileChooser.getSelectedFile()); From 3c3610d9cc12de16131aa611800d43e77c925551 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20=27Morty=27=20Str=C3=BCbe?= Date: Wed, 28 Mar 2012 10:55:01 +0200 Subject: [PATCH 14/21] Allow setting a log4j config file --- tools/cooja/java/se/sics/cooja/GUI.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/tools/cooja/java/se/sics/cooja/GUI.java b/tools/cooja/java/se/sics/cooja/GUI.java index 3d2227f8e..ac1369075 100644 --- a/tools/cooja/java/se/sics/cooja/GUI.java +++ b/tools/cooja/java/se/sics/cooja/GUI.java @@ -2943,10 +2943,24 @@ public class GUI extends Observable { * null */ public static void main(String[] args) { - + String logConfigFile = null; + for (String element : args) { + if (element.startsWith("-log4j=")) { + String arg = element.substring("-log4j=".length()); + logConfigFile = arg; + } + } + try { // Configure logger - if ((new File(LOG_CONFIG_FILE)).exists()) { + if ( logConfigFile != null){ + if(new File(logConfigFile).exists()) { + DOMConfigurator.configure(logConfigFile); + } else { + System.err.println("Failed to open " + logConfigFile); + System.exit(1); + } + } else if ((new File(LOG_CONFIG_FILE)).exists()) { DOMConfigurator.configure(LOG_CONFIG_FILE); } else { // Used when starting from jar From 7c2b6238fe27d5c805cffd6def1d10ef666579c2 Mon Sep 17 00:00:00 2001 From: Fredrik Osterlind Date: Wed, 28 Mar 2012 11:01:17 +0200 Subject: [PATCH 15/21] code style --- tools/cooja/java/se/sics/cooja/GUI.java | 28 ++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/tools/cooja/java/se/sics/cooja/GUI.java b/tools/cooja/java/se/sics/cooja/GUI.java index ac1369075..c35492fb0 100644 --- a/tools/cooja/java/se/sics/cooja/GUI.java +++ b/tools/cooja/java/se/sics/cooja/GUI.java @@ -2943,24 +2943,24 @@ public class GUI extends Observable { * null */ public static void main(String[] args) { - String logConfigFile = null; + String logConfigFile = null; for (String element : args) { - if (element.startsWith("-log4j=")) { - String arg = element.substring("-log4j=".length()); - logConfigFile = arg; - } + if (element.startsWith("-log4j=")) { + String arg = element.substring("-log4j=".length()); + logConfigFile = arg; + } } - + try { // Configure logger - if ( logConfigFile != null){ - if(new File(logConfigFile).exists()) { - DOMConfigurator.configure(logConfigFile); - } else { - System.err.println("Failed to open " + logConfigFile); - System.exit(1); - } - } else if ((new File(LOG_CONFIG_FILE)).exists()) { + if (logConfigFile != null) { + if (new File(logConfigFile).exists()) { + DOMConfigurator.configure(logConfigFile); + } else { + System.err.println("Failed to open " + logConfigFile); + System.exit(1); + } + } else if (new File(LOG_CONFIG_FILE).exists()) { DOMConfigurator.configure(LOG_CONFIG_FILE); } else { // Used when starting from jar From 65b5fd0dde47bc2a5e5dde6c87def687c1268611 Mon Sep 17 00:00:00 2001 From: Fredrik Osterlind Date: Wed, 28 Mar 2012 12:28:25 +0200 Subject: [PATCH 16/21] documenting potential bug --- .../apps/mspsim/src/se/sics/cooja/mspmote/plugins/CodeUI.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/plugins/CodeUI.java b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/plugins/CodeUI.java index e58257b66..ee8c91988 100644 --- a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/plugins/CodeUI.java +++ b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/plugins/CodeUI.java @@ -163,6 +163,8 @@ public class CodeUI extends JPanel { } /* Configure breakpoint menu options */ + /* XXX TODO We should ask for the file specified in the firmware, not + * the actual file on disk. */ Integer address = CodeUI.this.mote.getExecutableAddressOf(displayedFile, line); if (address == null) { From 0c94b567b995f1e21310c9f26e647536dd09b688 Mon Sep 17 00:00:00 2001 From: Fredrik Osterlind Date: Wed, 28 Mar 2012 12:29:54 +0200 Subject: [PATCH 17/21] supporting multiple path substituion rules in mspcodewatcher --- .../cooja/mspmote/plugins/MspCodeWatcher.java | 606 +++++++++++------- 1 file changed, 390 insertions(+), 216 deletions(-) diff --git a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/plugins/MspCodeWatcher.java b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/plugins/MspCodeWatcher.java index a11e31592..809fa54f2 100644 --- a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/plugins/MspCodeWatcher.java +++ b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/plugins/MspCodeWatcher.java @@ -32,12 +32,15 @@ package se.sics.cooja.mspmote.plugins; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; +import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; +import java.util.Comparator; import java.util.Observable; import java.util.Observer; @@ -47,16 +50,17 @@ import javax.swing.Box; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JDialog; -import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JSplitPane; import javax.swing.JTabbedPane; -import javax.swing.JTextField; +import javax.swing.JTable; import javax.swing.SwingUtilities; -import javax.swing.filechooser.FileFilter; import javax.swing.plaf.basic.BasicComboBoxRenderer; +import javax.swing.table.AbstractTableModel; import org.apache.log4j.Logger; import org.jdom.Element; @@ -72,6 +76,7 @@ import se.sics.cooja.VisPlugin; import se.sics.cooja.Watchpoint; import se.sics.cooja.WatchpointMote; import se.sics.cooja.WatchpointMote.WatchpointListener; +import se.sics.cooja.dialogs.MessageList; import se.sics.cooja.mspmote.MspMote; import se.sics.cooja.mspmote.MspMoteType; import se.sics.mspsim.core.EmulationException; @@ -103,11 +108,14 @@ public class MspCodeWatcher extends VisPlugin implements MotePlugin { private WatchpointListener watchpointListener; private JComboBox fileComboBox; - private String[] debugInfoMap = null; private File[] sourceFiles; private JTabbedPane mainPane; + private ArrayList rules; + private ELFDebug debug; + private String[] debugSourceFiles; + /** * Mini-debugger for MSP Motes. * Visualizes instructions, source code and allows a user to manipulate breakpoints. @@ -121,6 +129,21 @@ public class MspCodeWatcher extends VisPlugin implements MotePlugin { simulation = simulationToVisualize; this.mspMote = (MspMote) mote; this.watchpointMote = (WatchpointMote) mote; + try { + debug = ((MspMoteType)mspMote.getType()).getELF().getDebug(); + if (debug == null) { + throw new RuntimeException("No debugging info found in firmware, aborting"); + } + debugSourceFiles = debug.getSourceFiles(); + if (debugSourceFiles == null) { + throw new RuntimeException("No debugging info found in firmware, aborting"); + } + } catch (IOException e1) { + throw new RuntimeException("No debugging info found in firmware, aborting"); + } + rules = new ArrayList(); + + loadDefaultRules(); getContentPane().setLayout(new BorderLayout()); @@ -150,7 +173,6 @@ public class MspCodeWatcher extends VisPlugin implements MotePlugin { return this; } }); - updateFileComboBox(); /* Browse code control (north) */ Box sourceCodeControl = Box.createHorizontalBox(); @@ -223,8 +245,13 @@ public class MspCodeWatcher extends VisPlugin implements MotePlugin { showCurrentPC(); } + public void startPlugin() { + super.startPlugin(); + updateFileComboBox(); + } + private void updateFileComboBox() { - sourceFiles = getSourceFiles(mspMote, debugInfoMap); + sourceFiles = getSourceFiles(mspMote, rules); fileComboBox.removeAllItems(); fileComboBox.addItem("[view sourcefile]"); for (File f: sourceFiles) { @@ -288,39 +315,22 @@ public class MspCodeWatcher extends VisPlugin implements MotePlugin { currentCodeFile = null; try { - ELFDebug debug = ((MspMoteType)mspMote.getType()).getELF().getDebug(); - if (debug == null) { - return; - } int pc = mspMote.getCPU().getPC(); DebugInfo debugInfo = debug.getDebugInfo(pc); + if (pc <= 0) { + return; + } if (debugInfo == null) { - if (pc != 0) { - logger.warn("No sourcecode info at " + String.format("0x%04x", mspMote.getCPU().getPC())); - } + logger.warn("No source info at " + String.format("0x%04x", pc)); + return; + } + File f = applySubstitutionRules(new File(debugInfo.getPath(), debugInfo.getFile()), rules); + if (f == null || !f.exists()) { + logger.warn("Unknown source at " + String.format("0x%04x", pc) + ": " + debugInfo.getPath() + " " + debugInfo.getFile()); return; } - String path = new File(debugInfo.getPath(), debugInfo.getFile()).getPath(); - if (path == null) { - return; - } - path = path.replace('\\', '/'); - - /* Debug info to source file map */ - if (debugInfoMap != null && debugInfoMap.length == 2) { - if (path.startsWith(debugInfoMap[0])) { - path = debugInfoMap[1] + path.substring(debugInfoMap[0].length()); - } - } - - /* Nasty Cygwin-Windows fix */ - if (path.length() > 10 && path.startsWith("/cygdrive/")) { - char driveCharacter = path.charAt(10); - path = driveCharacter + ":/" + path.substring(11); - } - - currentCodeFile = new File(path).getCanonicalFile(); + currentCodeFile = f; currentLineNumber = debugInfo.getLine(); } catch (Exception e) { logger.fatal("Exception: " + e.getMessage(), e); @@ -329,147 +339,332 @@ public class MspCodeWatcher extends VisPlugin implements MotePlugin { } } - private void tryMapDebugInfo() { - final String[] debugFiles; - try { - - ELFDebug debug = ((MspMoteType)mspMote.getType()).getELF().getDebug(); - debugFiles = debug != null ? debug.getSourceFiles() : null; - if (debugFiles == null) { - logger.fatal("Error: No debug information is available"); - return; - } - } catch (IOException e1) { - logger.fatal("Error: " + e1.getMessage(), e1); - return; + private int getLocatedSourcesCount() { + File files[] = getSourceFiles(mspMote, rules); + if (files == null) { + return 0; } - String[] map = new RunnableInEDT() { - public String[] work() { - /* Select which source file to use */ - int counter = 0, n; - File correspondingFile = null; - while (true) { - n = JOptionPane.showOptionDialog(GUI.getTopParentContainer(), - "Choose which source file to manually locate.\n\n" + - "Some source files may not exist, as debug info is also inherited from the toolchain.\n" + - "\"Next File\" proceeds to the next source file in the debug info.\n\n" + - debugFiles[counter] + " (" + (counter+1) + '/' + debugFiles.length + ')', - "Select source file to locate", JOptionPane.YES_NO_CANCEL_OPTION, - JOptionPane.QUESTION_MESSAGE, null, - new String[] { "Next File", "Locate File", "Cancel"}, "Next File"); - if (n == JOptionPane.CANCEL_OPTION || n == JOptionPane.CLOSED_OPTION) { - return null; - } - if (n == JOptionPane.NO_OPTION) { - /* Locate file */ - final String filename = new File(debugFiles[counter]).getName(); - JFileChooser fc = new JFileChooser(); - fc.setFileFilter(new FileFilter() { - public boolean accept(File file) { - if (file.isDirectory()) { return true; } - if (file.getName().equals(filename)) { - return true; - } - return false; - } - public String getDescription() { - return "Source file " + filename; - } - }); - fc.setCurrentDirectory(new File(GUI.getExternalToolsSetting("PATH_CONTIKI", "."))); - int returnVal = fc.showOpenDialog(GUI.getTopParentContainer()); - if (returnVal == JFileChooser.APPROVE_OPTION) { - correspondingFile = fc.getSelectedFile(); - break; - } - } + return files.length; + } - if (n == JOptionPane.YES_OPTION) { - /* Next file */ - counter = (counter+1) % debugFiles.length; - } - } - - /* Match files */ - try { - String canonDebug = debugFiles[counter]; - String canonSelected = correspondingFile.getCanonicalFile().getPath().replace('\\', '/'); - - int offset = 0; - while (canonDebug.regionMatches( - true, - canonDebug.length()-offset, - canonSelected, canonSelected.length()-offset, - offset)) { - offset++; - if (offset >= canonDebug.length() || - offset >= canonSelected.length()) - break; - } - offset--; - String replace = canonDebug.substring(0, canonDebug.length() - offset); - String replacement = canonSelected.substring(0, canonSelected.length() - offset); - - { - JTextField replaceInput = new JTextField(replace); - replaceInput.setEditable(true); - JTextField replacementInput = new JTextField(replacement); - replacementInput.setEditable(true); - - Box box = Box.createVerticalBox(); - box.add(new JLabel("Debug info file:")); - box.add(new JLabel(canonDebug)); - box.add(new JLabel("Selected file:")); - box.add(new JLabel(canonSelected)); - box.add(Box.createVerticalStrut(20)); - box.add(new JLabel("Replacing:")); - box.add(replaceInput); - box.add(new JLabel("with:")); - box.add(replacementInput); - - JOptionPane optionPane = new JOptionPane(); - optionPane.setMessage(box); - optionPane.setMessageType(JOptionPane.INFORMATION_MESSAGE); - optionPane.setOptions(new String[] { "OK" }); - optionPane.setInitialValue("OK"); - JDialog dialog = optionPane.createDialog( - GUI.getTopParentContainer(), - "Mapping debug info to real sources"); - dialog.setVisible(true); - - replace = replaceInput.getText(); - replacement = replacementInput.getText(); - } - - replace = replace.replace('\\', '/'); - replacement = replacement.replace('\\', '/'); - return new String[] { replace, replacement }; - } catch (IOException e) { - logger.fatal("Error: " + e.getMessage(), e); - return null; - } - } - }.invokeAndWait(); - - if (map != null) { - debugInfoMap = map; - updateFileComboBox(); + private void updateRulesUsage() { + for (Rule rule: rules) { + rule.prefixMatches = 0; + rule.locatesFile = 0; + } + getSourceFiles(mspMote, rules); + rulesMatched = new int[rules.size()]; + rulesOK = new int[rules.size()]; + for (int i=0; i < rules.size(); i++) { + rulesMatched[i] = rules.get(i).prefixMatches; + rulesOK[i] = rules.get(i).locatesFile; } } - private static File[] getSourceFiles(MspMote mote, String[] map) { - final String[] sourceFiles; - try { - ELFDebug debug = ((MspMoteType)mote.getType()).getELF().getDebug(); - sourceFiles = debug != null ? debug.getSourceFiles() : null; - if (sourceFiles == null) { - logger.fatal("Error: No debug information is available"); - return new File[0]; + private class Rule { + String from = ""; + String to = ""; + int prefixMatches = 0; + int locatesFile = 0; + public Rule(String from, String to) { + this.from = from; + this.to = to; + } + File apply(File f) { + if (f == null) { + return null; } - } catch (IOException e1) { - logger.fatal("Error: " + e1.getMessage(), e1); + if (from == null) { + return null; + } + if (!f.getPath().startsWith(from)) { + if (rulesWithDebuggingOutput) { + rulesDebuggingOutput.addMessage(this + " does not match: " + f.getPath(), MessageList.ERROR); + } + return null; + } + prefixMatches++; + if (rulesWithDebuggingOutput) { + rulesDebuggingOutput.addMessage(this + " testing on: " + f.getPath()); + } + if (to == null) { + if (rulesWithDebuggingOutput) { + rulesDebuggingOutput.addMessage(this + " enter substition: " + f.getPath(), MessageList.ERROR); + } + return null; + } + File file = new File(to + f.getPath().substring(from.length())); + if (!file.exists()) { + if (rulesWithDebuggingOutput) { + rulesDebuggingOutput.addMessage(this + " not found: " + file.getPath(), MessageList.ERROR); + } + return null; + } + if (rulesWithDebuggingOutput) { + rulesDebuggingOutput.addMessage(this + " OK: " + f.getPath()); + } + locatesFile++; + return file; + } + public String toString() { + return "[" + from + "|" + to + "]"; + } + } + + private static File applySubstitutionRules(String file, Collection rules) { + return applySubstitutionRules(new File(file), rules); + } + private static File applySubstitutionRules(File file, Collection rules) { + if (file == null) { return null; } + if (file.exists()) { + return file; + } + + for (Rule rule: rules) { + File f = rule.apply(file); + if (f != null && f.exists()) { + return f; + } + } + return null; + } + + private void loadDefaultRules() { + String rulesString = GUI.getExternalToolsSetting("MSPCODEWATCHER_RULES", "/cygdrive/c/*c:/"); + String[] rulesArr = rulesString.split("\\*"); + rules.clear(); + for (int i=0; i < rulesArr.length/2; i++) { + Rule r = new Rule(rulesArr[i*2], rulesArr[i*2+1]); + if (r.from.equals("[empty]")) { + r.from = ""; + } + if (r.to.equals("[empty]")) { + r.to = ""; + } + rules.add(r); + } + } + + private MessageList rulesDebuggingOutput = new MessageList(); + private boolean rulesWithDebuggingOutput = false; + private int[] rulesMatched = null; + private int[] rulesOK = null; + private JTable table = null; + private void tryMapDebugInfo() { + /* called from AWT */ + int r = JOptionPane.showConfirmDialog(GUI.getTopParentContainer(), + "The firmware file " + mspMote.getType().getContikiFirmwareFile().getName() + " references " + debugSourceFiles.length + " source files.\n" + + "This function tries to locate these files on disk with a set of simple substitution rules.\n" + + "\n" + + "Right now " + getLocatedSourcesCount() + "/" + debugSourceFiles.length + " source files can be found.", + "Locate source files", JOptionPane.OK_CANCEL_OPTION); + if (r != JOptionPane.OK_OPTION) { + return; + } + + /* table with rules */ + rulesDebuggingOutput.clearMessages(); + final JDialog dialog = new JDialog((Window)GUI.getTopParentContainer(), "Locate source files"); + dialog.setModal(true); + updateRulesUsage(); + AbstractTableModel model = new AbstractTableModel() { + public int getRowCount() { + return 10; + } + public int getColumnCount() { + return 4; + } + public String getColumnName(int col) { + if (col == 0) { + return "Prefix"; + } + if (col == 1) { + return "Substitution"; + } + if (col == 2) { + return "Matched"; + } + if (col == 3) { + return "OK"; + } + return null; + } + public Object getValueAt(int rowIndex, int columnIndex) { + if (rowIndex < 0 || rowIndex >= rules.size()) { + return null; + } + Rule rule = rules.get(rowIndex); + if (columnIndex == 0) { + return rule.from; + } + if (columnIndex == 1) { + return rule.to; + } + if (columnIndex == 2) { + if (rulesMatched == null || rowIndex >= rulesMatched.length) { + return "[click Apply]"; + } + return rulesMatched[rowIndex]; + } + if (columnIndex == 3) { + if (rulesOK == null || rowIndex >= rulesOK.length) { + return "[click Apply]"; + } + return rulesOK[rowIndex]; + } + return null; + } + public boolean isCellEditable(int row, int column) { + if (column == 0) { + return true; + } + if (column == 1) { + return true; + } + return false; + } + public void setValueAt(Object aValue, int rowIndex, int columnIndex) { + Rule rule; + if (rowIndex < 0) { + return; + } + if (rowIndex < rules.size()) { + rule = rules.get(rowIndex); + } else { + do { + rule = new Rule("", ""); + rules.add(rule); + } while (rowIndex >= rules.size()); + } + if (columnIndex == 0) { + rule.from = (String) aValue; + } + if (columnIndex == 1) { + rule.to = (String) aValue; + } + rulesMatched = null; + rulesOK = null; + table.invalidate(); + table.repaint(); + } + }; + table = new JTable(model); + + /* control panel: save/load, clear/apply/close */ + final JButton applyButton = new JButton("Apply"); + applyButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + /* Remove trailing empty rules */ + ArrayList trimmedRules = new ArrayList(); + for (Rule rule: rules) { + if (rule.from == null || rule.from.trim().isEmpty()) { + rule.from = ""; + } + if (rule.to == null || rule.to.trim().isEmpty()) { + rule.to = ""; + } + if (rule.from.isEmpty() && rule.to.isEmpty()) { + /* ignore */ + continue; + } + trimmedRules.add(rule); + } + rules = trimmedRules; + + rulesDebuggingOutput.clearMessages(); + rulesDebuggingOutput.addMessage("Applying " + rules.size() + " substitution rules"); + rulesWithDebuggingOutput = true; + updateRulesUsage(); + rulesWithDebuggingOutput = false; + rulesDebuggingOutput.addMessage("Done! " + "Located sources: " + getLocatedSourcesCount() + "/" + debugSourceFiles.length); + rulesDebuggingOutput.addMessage(" "); + for (String s: debugSourceFiles) { + File f = applySubstitutionRules(s, rules); + if (f == null || !f.exists()) { + rulesDebuggingOutput.addMessage("Not yet located: " + s, MessageList.ERROR); + } + } + + table.invalidate(); + table.repaint(); + } + }); + JButton clearButton = new JButton("Clear"); + clearButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + rules.clear(); + applyButton.doClick(); + } + }); + + JButton loadButton = new JButton("Load default"); + loadButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + loadDefaultRules(); + applyButton.doClick(); + } + }); + JButton saveButton = new JButton("Save as default"); + saveButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + StringBuilder sb = new StringBuilder(); + for (Rule r: rules) { + sb.append("*"); + if (r.from.isEmpty()) { + sb.append("[empty]"); + } else { + sb.append(r.from); + } + sb.append("*"); + if (r.to.isEmpty()) { + sb.append("[empty]"); + } else { + sb.append(r.to); + } + } + if (sb.length() >= 1) { + GUI.setExternalToolsSetting("MSPCODEWATCHER_RULES", sb.substring(1)); + } else { + GUI.setExternalToolsSetting("MSPCODEWATCHER_RULES", ""); + } + } + }); + + JButton closeButton = new JButton("Close"); + closeButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + updateFileComboBox(); + dialog.dispose(); + } + }); + Box control = Box.createHorizontalBox(); + control.add(loadButton); + control.add(saveButton); + control.add(Box.createHorizontalGlue()); + control.add(clearButton); + control.add(applyButton); + control.add(closeButton); + + final JSplitPane split = new JSplitPane(JSplitPane.VERTICAL_SPLIT, + new JScrollPane(table), + new JScrollPane(rulesDebuggingOutput)); + SwingUtilities.invokeLater(new Runnable() { + public void run() { + split.setDividerLocation(0.5); + applyButton.doClick(); + } + }); + dialog.getContentPane().add(BorderLayout.CENTER, split); + dialog.getContentPane().add(BorderLayout.SOUTH, control); + dialog.getRootPane().setDefaultButton(closeButton); + dialog.setSize(550, 500); + dialog.setLocationRelativeTo(GUI.getTopParentContainer()); + dialog.setVisible(true); + } + + private File[] getSourceFiles(MspMote mote, ArrayList rules) { File contikiSource = mote.getType().getContikiSourceFile(); if (contikiSource != null) { try { @@ -480,50 +675,25 @@ public class MspCodeWatcher extends VisPlugin implements MotePlugin { /* Verify that files exist */ ArrayList existing = new ArrayList(); - for (String sourceFile: sourceFiles) { - + for (String sourceFile: debugSourceFiles) { /* Debug info to source file map */ - sourceFile = sourceFile.replace('\\', '/'); - if (map != null && map.length == 2) { - if (sourceFile.startsWith(map[0])) { - sourceFile = map[1] + sourceFile.substring(map[0].length()); - } - } - - /* Nasty Cygwin-Windows fix */ - if (sourceFile.length() > 10 && sourceFile.contains("/cygdrive/")) { - char driveCharacter = sourceFile.charAt(10); - sourceFile = driveCharacter + ":/" + sourceFile.substring(11); - } - - File file = new File(sourceFile); - try { - file = file.getCanonicalFile(); - } catch (IOException e1) { - } - if (!GUI.isVisualizedInApplet()) { - if (file.exists() && file.isFile()) { - existing.add(file); - } else { - /*logger.warn("Can't locate source file, skipping: " + file.getPath());*/ - } - } else { - /* Accept all files without existence check */ - existing.add(file); + File f = applySubstitutionRules(sourceFile, rules); + if (f != null && f.exists()) { + existing.add(f); } } /* If no files were found, suggest map function */ - if (sourceFiles.length > 0 && existing.isEmpty() && GUI.isVisualized()) { + if (debugSourceFiles.length > 0 && existing.isEmpty() && GUI.isVisualized()) { new RunnableInEDT() { public Boolean work() { JOptionPane.showMessageDialog( GUI.getTopParentContainer(), - "The firmware debug info specifies " + sourceFiles.length + " source files.\n" + - "However, Msp Code Watcher could not find any of these files.\n" + + "The firmware debug info specifies " + debugSourceFiles.length + " source files.\n" + + "However, MspCodeWatcher could not find any of these files.\n" + "Make sure the source files were not moved after the firmware compilation.\n" + "\n" + - "If you want to manually locate the sources, click \"Map\" button.", + "If you want to manually locate the sources, click the \"Locate sources\" button.", "No source files found", JOptionPane.WARNING_MESSAGE); return true; @@ -532,23 +702,13 @@ public class MspCodeWatcher extends VisPlugin implements MotePlugin { } /* Sort alphabetically */ - ArrayList sorted = new ArrayList(); - for (File file: existing) { - int index = 0; - for (index=0; index < sorted.size(); index++) { - if (file.getName().compareToIgnoreCase(sorted.get(index).getName()) < 0) { - break; - } + File[] sorted = existing.toArray(new File[0]); + Arrays.sort(sorted, new Comparator() { + public int compare(File o1, File o2) { + return o1.getName().compareToIgnoreCase(o2.getName()); } - sorted.add(index, file); - } - - /* Add Contiki source first */ - if (contikiSource != null && contikiSource.exists()) { - sorted.add(0, contikiSource); - } - - return sorted.toArray(new File[0]); + }); + return sorted; } public Collection getConfigXML() { @@ -559,13 +719,27 @@ public class MspCodeWatcher extends VisPlugin implements MotePlugin { element.addContent("" + mainPane.getSelectedIndex()); config.add(element); + for (Rule rule: rules) { + element = new Element("rule"); + element.setAttribute("from", rule.from==null?"":rule.from); + element.setAttribute("to", rule.to==null?"":rule.to); + config.add(element); + } + return config; } public boolean setConfigXML(Collection configXML, boolean visAvailable) { + boolean clearedRules = false; for (Element element : configXML) { if (element.getName().equals("tab")) { mainPane.setSelectedIndex(Integer.parseInt(element.getText())); + } else if (element.getName().equals("rule")) { + if (!clearedRules) { + rules.clear(); + clearedRules = true; + } + rules.add(new Rule(element.getAttributeValue("from"), element.getAttributeValue("to"))); } } return true; @@ -582,7 +756,7 @@ public class MspCodeWatcher extends VisPlugin implements MotePlugin { } }; - private AbstractAction mapAction = new AbstractAction("Locate sources") { + private AbstractAction mapAction = new AbstractAction("Locate sources...") { private static final long serialVersionUID = -3929432830596292495L; public void actionPerformed(ActionEvent e) { From 4222d0adcdd485609e080311fc54d4f7a8ecbb9a Mon Sep 17 00:00:00 2001 From: Fredrik Osterlind Date: Wed, 28 Mar 2012 14:44:59 +0200 Subject: [PATCH 18/21] bugfixed parsing of files read from mspsim --- .../src/se/sics/cooja/mspmote/MspMote.java | 9 +-- .../se/sics/cooja/mspmote/MspMoteType.java | 62 ++++++++++--------- 2 files changed, 34 insertions(+), 37 deletions(-) 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 ecc77fafa..1e0662046 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 @@ -36,7 +36,6 @@ import java.io.IOException; import java.io.PrintStream; import java.util.ArrayList; import java.util.Collection; -import java.util.Enumeration; import java.util.Hashtable; import java.util.Observable; @@ -582,9 +581,7 @@ public abstract class MspMote extends AbstractEmulatedMote implements Mote, Watc /* Match file */ Hashtable lineTable = debuggingInfo.get(file); if (lineTable == null) { - Enumeration fileEnum = debuggingInfo.keys(); - while (fileEnum.hasMoreElements()) { - File f = fileEnum.nextElement(); + for (File f: debuggingInfo.keySet()) { if (f != null && f.getName().equals(file.getName())) { lineTable = debuggingInfo.get(f); break; @@ -598,9 +595,7 @@ public abstract class MspMote extends AbstractEmulatedMote implements Mote, Watc /* Match line number */ Integer address = lineTable.get(lineNr); if (address != null) { - Enumeration lineEnum = lineTable.keys(); - while (lineEnum.hasMoreElements()) { - Integer l = lineEnum.nextElement(); + for (Integer l: lineTable.keySet()) { if (l != null && l.intValue() == lineNr) { /* Found line address */ return lineTable.get(l); diff --git a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/MspMoteType.java b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/MspMoteType.java index c55ef47bb..324132ee3 100644 --- a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/MspMoteType.java +++ b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/MspMoteType.java @@ -317,7 +317,7 @@ public abstract class MspMoteType implements MoteType { logger.warn("Old simulation config detected: SkySerial was replaced by MspSerial"); intfClass = MspSerial.class.getName(); } - + Class moteInterfaceClass = simulation.getGUI().tryLoadClass(this, MoteInterface.class, intfClass); @@ -368,7 +368,7 @@ public abstract class MspMoteType implements MoteType { private static ELF loadELF(String filepath) throws IOException { return ELF.readELF(filepath); } - + private ELF elf; /* cached */ public ELF getELF() throws IOException { if (elf == null) { @@ -379,9 +379,9 @@ public abstract class MspMoteType implements MoteType { } return elf; } - + private Hashtable> debuggingInfo = null; /* cached */ - public Hashtable> getFirmwareDebugInfo() + public Hashtable> getFirmwareDebugInfo() throws IOException { if (debuggingInfo == null) { debuggingInfo = getFirmwareDebugInfo(getELF()); @@ -407,33 +407,35 @@ public abstract class MspMoteType implements MoteType { for (int address: addresses) { DebugInfo info = elf.getDebugInfo(address); - - if (info != null && info.getPath() != null && info.getFile() != null && info.getLine() >= 0) { - - /* Nasty Cygwin-Windows fix */ - String path = info.getPath(); - if (path.contains("/cygdrive/")) { - int index = path.indexOf("/cygdrive/"); - char driveCharacter = path.charAt(index+10); - - path = path.replace("/cygdrive/" + driveCharacter + "/", driveCharacter + ":/"); - } - - File file = new File(path, info.getFile()); - try { - file = file.getCanonicalFile(); - } catch (IOException e) { - } catch (java.security.AccessControlException e) { - } - - Hashtable lineToAddrHash = fileToLineHash.get(file); - if (lineToAddrHash == null) { - lineToAddrHash = new Hashtable(); - fileToLineHash.put(file, lineToAddrHash); - } - - lineToAddrHash.put(info.getLine(), address); + if (info == null) { + continue; } + if (info.getPath() == null && info.getFile() == null) { + continue; + } + if (info.getLine() < 0) { + continue; + } + + File file; + if (info.getPath() != null) { + file = new File(info.getPath(), info.getFile()); + } else { + file = new File(info.getFile()); + } + try { + file = file.getCanonicalFile(); + } catch (IOException e) { + } catch (java.security.AccessControlException e) { + } + + Hashtable lineToAddrHash = fileToLineHash.get(file); + if (lineToAddrHash == null) { + lineToAddrHash = new Hashtable(); + fileToLineHash.put(file, lineToAddrHash); + } + + lineToAddrHash.put(info.getLine(), address); } return fileToLineHash; From e3a12703da75424dbc0e3c64a1f7a262a9521c81 Mon Sep 17 00:00:00 2001 From: Fredrik Osterlind Date: Wed, 28 Mar 2012 14:52:30 +0200 Subject: [PATCH 19/21] added temporary workaround that removes file duplicates, removed warning message --- .../cooja/mspmote/plugins/MspCodeWatcher.java | 39 ++++++++++--------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/plugins/MspCodeWatcher.java b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/plugins/MspCodeWatcher.java index 809fa54f2..4221035f8 100644 --- a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/plugins/MspCodeWatcher.java +++ b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/plugins/MspCodeWatcher.java @@ -67,7 +67,6 @@ import org.jdom.Element; import se.sics.cooja.ClassDescription; import se.sics.cooja.GUI; -import se.sics.cooja.GUI.RunnableInEDT; import se.sics.cooja.Mote; import se.sics.cooja.MotePlugin; import se.sics.cooja.PluginType; @@ -141,6 +140,26 @@ public class MspCodeWatcher extends VisPlugin implements MotePlugin { } catch (IOException e1) { throw new RuntimeException("No debugging info found in firmware, aborting"); } + + /* XXX Temporary workaround: source file removing duplicates awaiting Mspsim update */ + { + ArrayList newDebugSourceFiles = new ArrayList(); + for (String sf: debugSourceFiles) { + boolean found = false; + for (String nsf: newDebugSourceFiles) { + if (sf.equals(nsf)) { + found = true; + break; + } + } + if (!found) { + newDebugSourceFiles.add(sf); + } + } + debugSourceFiles = newDebugSourceFiles.toArray(new String[0]); + } + + rules = new ArrayList(); loadDefaultRules(); @@ -683,24 +702,6 @@ public class MspCodeWatcher extends VisPlugin implements MotePlugin { } } - /* If no files were found, suggest map function */ - if (debugSourceFiles.length > 0 && existing.isEmpty() && GUI.isVisualized()) { - new RunnableInEDT() { - public Boolean work() { - JOptionPane.showMessageDialog( - GUI.getTopParentContainer(), - "The firmware debug info specifies " + debugSourceFiles.length + " source files.\n" + - "However, MspCodeWatcher could not find any of these files.\n" + - "Make sure the source files were not moved after the firmware compilation.\n" + - "\n" + - "If you want to manually locate the sources, click the \"Locate sources\" button.", - "No source files found", - JOptionPane.WARNING_MESSAGE); - return true; - } - }.invokeAndWait(); - } - /* Sort alphabetically */ File[] sorted = existing.toArray(new File[0]); Arrays.sort(sorted, new Comparator() { From 173f512f6ce8d7c73796ea50c33a8545a21c8015 Mon Sep 17 00:00:00 2001 From: Fredrik Osterlind Date: Wed, 28 Mar 2012 14:53:45 +0200 Subject: [PATCH 20/21] disable editor when no source code is showing --- .../apps/mspsim/src/se/sics/cooja/mspmote/plugins/CodeUI.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/plugins/CodeUI.java b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/plugins/CodeUI.java index ee8c91988..50faff24c 100644 --- a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/plugins/CodeUI.java +++ b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/plugins/CodeUI.java @@ -256,7 +256,8 @@ public class CodeUI extends JPanel { SwingUtilities.invokeLater(new Runnable() { public void run() { displayedFile = null; - codeEditor.setText(null); + codeEditor.setText("[no source displayed]"); + codeEditor.setEnabled(false); codeEditorLines.clear(); displayLine(-1, markCurrent); } @@ -277,6 +278,7 @@ public class CodeUI extends JPanel { displayNoCode(markCurrent); return; } + codeEditor.setEnabled(true); String[] lines = data.split("\n"); logger.info("Opening " + codeFile + " (" + lines.length + " lines)"); From 7bf4fa4bfff182e5876b86b81721d8ccb8e41854 Mon Sep 17 00:00:00 2001 From: Niclas Finne Date: Wed, 28 Mar 2012 21:51:19 +0200 Subject: [PATCH 21/21] Removed obsolete mac pointer --- apps/shell/shell-sky.c | 5 +++-- core/net/rime.h | 2 -- core/net/rime/rime.c | 3 --- examples/sky/rssi-scanner.c | 3 ++- examples/sky/sky-collect.c | 5 +++-- examples/z1/rssi_scanner/rssi-scanner.c | 3 ++- 6 files changed, 10 insertions(+), 11 deletions(-) diff --git a/apps/shell/shell-sky.c b/apps/shell/shell-sky.c index bfdb19351..52063be7e 100644 --- a/apps/shell/shell-sky.c +++ b/apps/shell/shell-sky.c @@ -44,6 +44,7 @@ #include "dev/watchdog.h" #include "net/rime.h" +#include "net/netstack.h" #include "dev/cc2420.h" #include "dev/leds.h" #include "dev/sht11.h" @@ -97,7 +98,7 @@ do_rssi(void) static int sample; int channel; - rime_mac->off(0); + NETSTACK_MAC.off(0); cc2420_on(); for(channel = 11; channel <= 26; ++channel) { @@ -105,7 +106,7 @@ do_rssi(void) rssi_samples[sample].channel[channel - 11] = cc2420_rssi() + 53; } - rime_mac->on(); + NETSTACK_MAC.on(); sample = (sample + 1) % NUM_SAMPLES; diff --git a/core/net/rime.h b/core/net/rime.h index cfd36c6fe..8db7b935e 100644 --- a/core/net/rime.h +++ b/core/net/rime.h @@ -89,8 +89,6 @@ void rime_input(void); int rime_output(struct channel *c); -extern const struct mac_driver *rime_mac; - struct rime_sniffer { struct rime_sniffer *next; void (* input_callback)(void); diff --git a/core/net/rime/rime.c b/core/net/rime/rime.c index 24ce008b5..2d49cc371 100644 --- a/core/net/rime/rime.c +++ b/core/net/rime/rime.c @@ -61,8 +61,6 @@ #include "lib/list.h" -const struct mac_driver *rime_mac; - #ifdef RIME_CONF_BROADCAST_ANNOUNCEMENT_CHANNEL #define BROADCAST_ANNOUNCEMENT_CHANNEL RIME_CONF_BROADCAST_ANNOUNCEMENT_CHANNEL #else /* RIME_CONF_BROADCAST_ANNOUNCEMENT_CHANNEL */ @@ -130,7 +128,6 @@ init(void) packetbuf_clear(); announcement_init(); - rime_mac = &NETSTACK_MAC; chameleon_init(); /* XXX This is initializes the transmission of announcements but it diff --git a/examples/sky/rssi-scanner.c b/examples/sky/rssi-scanner.c index 9f728626e..c30a33a17 100644 --- a/examples/sky/rssi-scanner.c +++ b/examples/sky/rssi-scanner.c @@ -41,6 +41,7 @@ #include "contiki.h" #include "net/rime.h" +#include "net/netstack.h" #include "dev/leds.h" #include "dev/cc2420.h" @@ -81,7 +82,7 @@ PROCESS_THREAD(scanner_process, ev, data) { PROCESS_BEGIN(); /* switch mac layer off, and turn radio on */ - rime_mac->off(0); + NETSTACK_MAC.off(0); cc2420_on(); while(1) { diff --git a/examples/sky/sky-collect.c b/examples/sky/sky-collect.c index b2d00afa0..2a41a5a0b 100644 --- a/examples/sky/sky-collect.c +++ b/examples/sky/sky-collect.c @@ -39,6 +39,7 @@ */ #include "contiki.h" +#include "net/netstack.h" #include "net/rime.h" #include "net/rime/collect.h" #include "net/rime/collect-neighbor.h" @@ -133,7 +134,7 @@ do_rssi(void) static int sample; int channel; - rime_mac->off(0); + NETSTACK_MAC.off(0); cc2420_on(); for(channel = 11; channel <= 26; ++channel) { @@ -141,7 +142,7 @@ do_rssi(void) rssi_samples[sample].channel[channel - 11] = cc2420_rssi() + 53; } - rime_mac->on(); + NETSTACK_MAC.on(); sample = (sample + 1) % NUM_SAMPLES; diff --git a/examples/z1/rssi_scanner/rssi-scanner.c b/examples/z1/rssi_scanner/rssi-scanner.c index d47e61410..f9976e71a 100644 --- a/examples/z1/rssi_scanner/rssi-scanner.c +++ b/examples/z1/rssi_scanner/rssi-scanner.c @@ -41,6 +41,7 @@ #include "contiki.h" #include "net/rime.h" +#include "net/netstack.h" #include "dev/leds.h" #include "dev/cc2420.h" @@ -83,7 +84,7 @@ PROCESS_THREAD(scanner_process, ev, data) { PROCESS_BEGIN(); /* switch mac layer off, and turn radio on */ - rime_mac->off(0); + NETSTACK_MAC.off(0); cc2420_on(); while(1) {