Merge branch 'master' of ssh://contiki.git.sourceforge.net/gitroot/contiki/contiki

This commit is contained in:
Adam Dunkels 2011-08-29 21:31:51 +02:00
commit 8faaaa2c83
13 changed files with 653 additions and 157 deletions

View file

@ -34,6 +34,10 @@ CONTIKI_TARGET_SOURCEFILES += $(USB)
//AVR = clock.c mtarch.c eeprom.c flash.c leds-arch.c watchdog.c rtimer-arch.c //AVR = clock.c mtarch.c eeprom.c flash.c leds-arch.c watchdog.c rtimer-arch.c
endif endif
ifdef WITH_RPL
CFLAGS += -DUIP_CONF_IPV6_RPL=$(WITH_RPL)
endif
#For a coffee file system, the application makefile can define COFFEE_FILES=n #For a coffee file system, the application makefile can define COFFEE_FILES=n
#to select the type and COFFEE_ADDRESS=0xaaaaaaaa as the starting byte address. #to select the type and COFFEE_ADDRESS=0xaaaaaaaa as the starting byte address.
#If only one is define the other will use the (Raven webserver 1284p) defaults #If only one is define the other will use the (Raven webserver 1284p) defaults

View file

@ -253,4 +253,4 @@ ISR( _VECTOR(76)) {while (1) x++;}
ISR( _VECTOR(77)) {while (1) x++;} ISR( _VECTOR(77)) {while (1) x++;}
ISR( _VECTOR(78)) {while (1) x++;} ISR( _VECTOR(78)) {while (1) x++;}
ISR( _VECTOR(79)) {while (1) x++;} ISR( _VECTOR(79)) {while (1) x++;}
#endif #endif

View file

@ -9,6 +9,7 @@
* Mike Vidales mavida404@gmail.com * Mike Vidales mavida404@gmail.com
* Kevin Brown kbrown3@uccs.edu * Kevin Brown kbrown3@uccs.edu
* Nate Bohlmann nate@elfwerks.com * Nate Bohlmann nate@elfwerks.com
* David Kopf dak664@embarqmail.com
* *
* All rights reserved. * All rights reserved.
* *
@ -45,7 +46,6 @@
* \file * \file
* \brief This file contains radio driver code. * \brief This file contains radio driver code.
* *
* $Id: rf230bb.h,v 1.6 2010/12/15 16:50:44 dak664 Exp $
*/ */
#ifndef RADIO_H #ifndef RADIO_H
@ -228,4 +228,4 @@ uint8_t rf230_get_raw_rssi(void);
#endif #endif
/** @} */ /** @} */
/*EOF*/ /*EOF*/

View file

@ -27,3 +27,8 @@ clean:
# rm ../../platform/avr-raven/apps/raven-webserver/httpd-fsdata.c # rm ../../platform/avr-raven/apps/raven-webserver/httpd-fsdata.c
rm symbols.c symbols.h webserver6.elf $(OUTFILE).elf $(OUTFILE).hex rm symbols.c symbols.h webserver6.elf $(OUTFILE).elf $(OUTFILE).hex
rm -rf obj_avr-raven rm -rf obj_avr-raven
connect:
#Connect to serial debug port for timestamp log (requires PERL).
#Change the baud rate and device to agree with your serial connection.
../../tools/serial-log.pl -b 57600 -t /dev/com1 -l

View file

@ -4,6 +4,8 @@ all: webserver6
APPS=raven-webserver raven-lcd-interface APPS=raven-webserver raven-lcd-interface
TARGET=avr-raven TARGET=avr-raven
UIP_CONF_IPV6=1 UIP_CONF_IPV6=1
#WITH_RPL=1 //RPL is not yet the default.
#RF230BB=1 //Use radio driver that communicates with the core MAC layer. Now the default. #RF230BB=1 //Use radio driver that communicates with the core MAC layer. Now the default.
#COFFEE_FILES=1 //Use coffee file system in EEPROM #COFFEE_FILES=1 //Use coffee file system in EEPROM
#COFFEE_FILES=2 //Use coffee file system in program flash #COFFEE_FILES=2 //Use coffee file system in program flash

View file

@ -40,3 +40,15 @@ $make WEBDIR=xxx always forces regeneration of web content into httpd-fsdata.c a
so requires PERL. A bare $make after that will not regenerate httpd-fsdata.c. so requires PERL. A bare $make after that will not regenerate httpd-fsdata.c.
Use $make WEBDIR=default to switch back to the default /http-fs/ content. Use $make WEBDIR=default to switch back to the default /http-fs/ content.
See Makefile.webserver for optional switches for RPL or a coffee file system.
$make WITH_RPL=1 for a RPL node, or if rpl has become the contiki default,
$make WITH_RPL=0 to override
Much headbanging can result if you do not $make clean when changing make options,
as the normal build dependencies are bypassed and the needed object modules
may not be rebuilt.
$make connect will invoke the /tools/serial-log.pl perl script to connect to
your serial debug port. This will log to the console and optional log file,
adding useful time stamps. Edit the makefile for your serial port configuration.

View file

@ -452,12 +452,12 @@ raven_lcd_show_text(char *text) {
static void static void
lcd_show_servername(void) { lcd_show_servername(void) {
//extern uint8_t mac_address[8]; //These are defined in httpd-fsdata.c via makefsdata.h //extern uint8_t eemem_mac_address[8]; //These are defined in httpd-fsdata.c via makefsdata.h
extern uint8_t server_name[16]; extern uint8_t eemem_server_name[16];
//extern uint8_t domain_name[30]; //extern uint8_t eemem_domain_name[30];
char buf[sizeof(server_name)+1]; char buf[sizeof(eemem_server_name)+1];
eeprom_read_block (buf,server_name, sizeof(server_name)); eeprom_read_block (buf,eemem_server_name, sizeof(eemem_server_name));
buf[sizeof(server_name)]=0; buf[sizeof(eemem_server_name)]=0;
raven_lcd_show_text(buf); //must fit in all the buffers or it will be truncated! raven_lcd_show_text(buf); //must fit in all the buffers or it will be truncated!
} }
#endif #endif

View file

@ -1,7 +1,10 @@
#include <avr/eeprom.h> #include <avr/eeprom.h>
/* Link layer ipv6 address will become fe80::11:22ff:fe33:4455 */ /* Link layer ipv6 address will become fe80::11:22ff:fe33:4455 */
uint8_t mac_address[8] EEMEM = {0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x55}; uint8_t default_mac_address[8] PROGMEM = {0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x55};
uint8_t server_name[16] EEMEM = "Contiki-Raven"; uint8_t default_server_name[16] PROGMEM = "Contiki-Raven";
uint8_t domain_name[30] EEMEM = "localhost"; uint8_t default_domain_name[30] PROGMEM = "localhost";
uint8_t eemem_mac_address[8] EEMEM = {0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x55};
uint8_t eemem_server_name[16] EEMEM = "Contiki-Raven";
uint8_t eemem_domain_name[30] EEMEM = "localhost";

View file

@ -99,11 +99,22 @@ unsigned long clock_seconds(void);
//#define RADIO_CONF_CALIBRATE_INTERVAL 256 //#define RADIO_CONF_CALIBRATE_INTERVAL 256
/* RADIOSTATS is used in rf230bb, clock.c and the webserver cgi to report radio usage */ /* RADIOSTATS is used in rf230bb, clock.c and the webserver cgi to report radio usage */
#define RADIOSTATS 1 #define RADIOSTATS 1
/* More extensive stats */
#define ENERGEST_CONF_ON 0
/* Use settings manager to save configuration in EEPROM */
/* Adds ~1700 bytes to progmem */
#define CONTIKI_CONF_SETTINGS_MANAGER 1
/* Possible watchdog timeouts depend on mcu. Default is WDTO_2S. -1 Disables the watchdog. */ /* Possible watchdog timeouts depend on mcu. Default is WDTO_2S. -1 Disables the watchdog. */
/* AVR Studio simulator tends to reboot due to clocking the WD 8 times too fast */
//#define WATCHDOG_CONF_TIMEOUT -1 //#define WATCHDOG_CONF_TIMEOUT -1
/* Debugflow macro, useful for tracing path through mac and radio interrupts */
//#define DEBUGFLOWSIZE 128
/* Network setup. The new NETSTACK interface requires RF230BB (as does ip4) */ /* Network setup. The new NETSTACK interface requires RF230BB (as does ip4) */
#if RF230BB #if RF230BB
#undef PACKETBUF_CONF_HDR_SIZE //Use the packetbuf default for header size #undef PACKETBUF_CONF_HDR_SIZE //Use the packetbuf default for header size

View file

@ -30,14 +30,28 @@
* *
* @(#)$$ * @(#)$$
*/ */
#define ANNOUNCE_BOOT 1 //adds about 600 bytes to program size
#define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args) #define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
#define ANNOUNCE_BOOT 1 //adds about 600 bytes to program size
#if ANNOUNCE_BOOT
#define PRINTA(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
#else
#define PRINTA(...)
#endif
#define DEBUG 0 #define DEBUG 0
#if DEBUG #if DEBUG
#define PRINTFD(FORMAT,args...) printf_P(PSTR(FORMAT),##args) #define PRINTD(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
#else #else
#define PRINTFD(...) #define PRINTD(...)
#endif
/* Track interrupt flow through mac, rdc and radio driver */
#if DEBUGFLOWSIZE
uint8_t debugflowsize,debugflow[DEBUGFLOWSIZE];
#define DEBUGFLOW(c) if (debugflowsize<(DEBUGFLOWSIZE-1)) debugflow[debugflowsize++]=c
#else
#define DEBUGFLOW(c)
#endif #endif
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
@ -93,85 +107,334 @@
#include "net/rime.h" #include "net/rime.h"
/* Test rtimers, also for pings, stack monitor, neighbor/route printout and time stamps */ /* Get periodic prints from idle loop, from clock seconds or rtimer interrupts */
#define TESTRTIMER 0 /* Use of rtimer will conflict with other rtimer interrupts such as contikimac radio cycling */
#if TESTRTIMER /* STAMPS will print ENERGEST outputs if that is enabled. */
#define PERIODICPRINTS 1
#if PERIODICPRINTS
//#define PINGS 64 //#define PINGS 64
#define ROUTES 300 #define ROUTES 600
#define STAMPS 60 #define STAMPS 60
#define STACKMONITOR 600 #define STACKMONITOR 600
uint32_t clocktime;
#define TESTRTIMER 0
#if TESTRTIMER
uint8_t rtimerflag=1; uint8_t rtimerflag=1;
uint16_t rtime;
struct rtimer rt; struct rtimer rt;
void rtimercycle(void) {rtimerflag=1;} void rtimercycle(void) {rtimerflag=1;}
static void ipaddr_add(const uip_ipaddr_t *addr); #endif
#endif
#endif /* TESTRTIMER */ #if WITH_NODE_ID
uint16_t node_id;
#endif
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
/*----------------------Configuration of the .elf file---------------------*/ /*----------------------Configuration of the .elf file---------------------*/
typedef struct {unsigned char B2;unsigned char B1;unsigned char B0;} __signature_t; #if 1
/* The proper way to set the signature is */
#include <avr/signature.h>
#else
/* Older avr-gcc's may not define the needed SIGNATURE bytes. Do it manually if you get an error */
typedef struct {const unsigned char B2;const unsigned char B1;const unsigned char B0;} __signature_t;
#define SIGNATURE __signature_t __signature __attribute__((section (".signature"))) #define SIGNATURE __signature_t __signature __attribute__((section (".signature")))
SIGNATURE = { SIGNATURE = {
/* Older AVR-GCCs may not define the SIGNATURE_n bytes so use explicit 1284p values */ .B2 = 0x05,//SIGNATURE_2, //ATMEGA1284p
.B2 = 0x05,//SIGNATURE_2, .B1 = 0x97,//SIGNATURE_1, //128KB flash
.B1 = 0x97,//SIGNATURE_1, .B0 = 0x1E,//SIGNATURE_0, //Atmel
.B0 = 0x1E,//SIGNATURE_0,
}; };
#endif
/* JTAG, SPI enabled, Internal RC osc, Boot flash size 4K, 6CK+65msec delay, brownout disabled */
FUSES ={.low = 0xe2, .high = 0x99, .extended = 0xff,}; FUSES ={.low = 0xe2, .high = 0x99, .extended = 0xff,};
/*----------------------Configuration of EEPROM---------------------------*/ /* Put the default settings into program flash memory */
/* Use existing EEPROM if it passes the integrity test, else reinitialize with build values */ /* Webserver builds can set some defaults in httpd-fsdata.c via makefsdata.h */
/* Put default MAC address in EEPROM */
#if AVR_WEBSERVER #if AVR_WEBSERVER
extern uint8_t mac_address[8]; //These are defined in httpd-fsdata.c via makefsdata.h extern uint8_t default_mac_address[8];
extern uint8_t server_name[16]; extern uint8_t default_server_name[16];
extern uint8_t domain_name[30]; extern uint8_t default_domain_name[30];
#else #else
uint8_t mac_address[8] EEMEM = {0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x55}; #ifdef MAC_ADDRESS
uint8_t default_mac_address[8] PROGMEM = MAC_ADDRESS;
#else
uint8_t default_mac_address[8] PROGMEM = {0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x55};
#endif #endif
#ifdef SERVER_NAME
uint8_t default_server_name[16] PROGMEM = SERVER_NAME;
#else
uint8_t default_server_name[16] PROGMEM = "Raven_webserver";
#endif
#ifdef DOMAIN_NAME
uint8_t default_domain_name[30] PROGMEM = DOMAIN_NAME
#else
uint8_t default_domain_name[30] PROGMEM = "localhost";
#endif
#endif /* AVR_WEBSERVER */
#ifdef NODE_ID
uint16_t default_nodeid PROGMEM = NODEID;
#else
uint16_t default_nodeid PROGMEM = 0;
#endif
#ifdef CHANNEL_802_15_4 #ifdef CHANNEL_802_15_4
uint8_t rf_channel[2] EEMEM = {CHANNEL_802_15_4, ~CHANNEL_802_15_4}; uint8_t default_channel PROGMEM = CHANNEL_802_15_4;
#else #else
uint8_t rf_channel[2] EEMEM = {22, ~22}; uint8_t default_channel PROGMEM = 26;
#endif
#ifdef IEEE802154_PANID
uint16_t default_panid PROGMEM = IEEE802154_PANID;
#else
uint16_t default_panid PROGMEM = 0xABCD;
#endif
#ifdef IEEE802154_PANADDR
uint16_t default_panaddr PROGMEM = IEEE802154_PANID;
#else
uint16_t default_panaddr PROGMEM = 0;
#endif
#ifdef RF230_MAX_TX_POWER
uint8_t default_txpower PROGMEM = RF230_MAX_TX_POWER;
#else
uint8_t default_txpower PROGMEM = 0;
#endif #endif
volatile uint8_t eeprom_channel;
static uint8_t get_channel_from_eeprom() {
// volatile uint8_t eeprom_channel;
uint8_t eeprom_check;
eeprom_channel = eeprom_read_byte(&rf_channel[0]);
eeprom_check = eeprom_read_byte(&rf_channel[1]);
if(eeprom_channel==~eeprom_check) /* Get a pseudo random number using the ADC */
return eeprom_channel; static uint8_t
rng_get_uint8(void) {
uint8_t i,j;
ADCSRA=1<<ADEN; //Enable ADC, not free running, interrupt disabled, fastest clock
for (i=0;i<4;i++) {
ADMUX = 0; //toggle reference to increase noise
ADMUX =0x1E; //Select AREF as reference, measure 1.1 volt bandgap reference.
ADCSRA|=1<<ADSC; //Start conversion
while (ADCSRA&(1<<ADSC)); //Wait till done
j = (j<<2) + ADC;
}
ADCSRA=0; //Disable ADC
PRINTD("rng issues %d\n",j);
return j;
}
#if CONTIKI_CONF_RANDOM_MAC
static void
generate_new_eui64(uint8_t eui64[8]) {
eui64[0] = 0x02;
eui64[1] = rng_get_uint8();
eui64[2] = rng_get_uint8();
eui64[3] = 0xFF;
eui64[4] = 0xFE;
eui64[5] = rng_get_uint8();
eui64[6] = rng_get_uint8();
eui64[7] = rng_get_uint8();
}
#endif
#if !CONTIKI_CONF_SETTINGS_MANAGER
/****************************No settings manager*****************************/
/* If not using the settings manager, put the default values into EEMEM
* These can be manually changed and kept over program reflash.
* The channel and bit complement are used to check EEMEM integrity,
* If corrupt all values will be rewritten with the default flash values.
* To make this work, get the channel before anything else.
*/
#if AVR_WEBSERVER
extern uint8_t eemem_mac_address[8]; //These are defined in httpd-fsdata.c via makefsdata.h
extern uint8_t eemem_server_name[16];
extern uint8_t eemem_domain_name[30];
#else
#ifdef MAC_ADDRESS
uint8_t eemem_mac_address[8] EEMEM = MAC_ADDRESS;
#else
uint8_t eemem_mac_address[8] EEMEM = {0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x55};
#endif
#ifdef SERVER_NAME
uint8_t eemem_server_name[16] EEMEM = SERVER_NAME;
#else
uint8_t eemem_server_name[16] EEMEM = "Raven_webserver";
#endif
#ifdef DOMAIN_NAME
uint8_t eemem_domain_name[30] EEMEM = DOMAIN_NAME
#else
uint8_t eemem_domain_name[30] EEMEM = "localhost";
#endif
#endif /*AVR_WEBSERVER */
#ifdef NODE_ID
uint16_t eemem_nodeid EEMEM = NODEID;
#else
uint16_t eemem_nodeid EEMEM = 0;
#endif
#ifdef CHANNEL_802_15_4 #ifdef CHANNEL_802_15_4
return(CHANNEL_802_15_4); uint8_t eemem_channel[2] EEMEM = {CHANNEL_802_15_4, ~CHANNEL_802_15_4};
#else #else
return 26; uint8_t eemem_channel[2] EMEM = {26, ~26};
#endif #endif
#ifdef IEEE802154_PANID
uint16_t eemem_panid EEMEM = IEEE802154_PANID;
#else
uint16_t eemem_panid EEMEM = 0xABCD;
#endif
#ifdef IEEE802154_PANADDR
uint16_t eemem_panaddr EEMEM = IEEE802154_PANADDR;
#else
uint16_t eemem_panaddr EEMEM = 0;
#endif
#ifdef RF230_MAX_TX_POWER
uint8_t eemem_txpower EEMEM = RF230_MAX_TX_POWER;
#else
uint8_t eemem_txpower EEMEM = 0;
#endif
static uint8_t
get_channel_from_eeprom() {
uint8_t x[2];
*(uint16_t *)x = eeprom_read_word ((uint16_t *)&eemem_channel);
/* Don't return an invalid channel number */
if( (x[0]<11) || (x[0] > 26)) x[1]=x[0];
/* Do exclusive or test on the two values read */
if((uint8_t)x[0]!=(uint8_t)~x[1]) {//~x[1] can promote comparison to 16 bit
/* Verification fails, rewrite everything */
uint8_t i,buffer[32];
PRINTD("EEPROM is corrupt, rewriting with defaults.\n");
#if CONTIKI_CONF_RANDOM_MAC
PRINTA("Generating random MAC address.\n");
generate_new_eui64(&buffer);
#else
for (i=0;i<sizeof(default_mac_address);i++) buffer[i] = pgm_read_byte_near(default_mac_address+i);
#endif
cli();
eeprom_write_block(&buffer, &eemem_mac_address, sizeof(eemem_mac_address));
for (i=0;i<sizeof(default_server_name);i++) buffer[i] = pgm_read_byte_near(default_server_name+i);
eeprom_write_block(&buffer, &eemem_server_name, sizeof(eemem_server_name));
for (i=0;i<sizeof(default_domain_name);i++) buffer[i] = pgm_read_byte_near(default_domain_name+i);
eeprom_write_block(&buffer, &eemem_domain_name, sizeof(eemem_domain_name));
eeprom_write_word(&eemem_panid , pgm_read_word_near(&default_panid));
eeprom_write_word(&eemem_panaddr, pgm_read_word_near(&default_panaddr));
eeprom_write_byte(&eemem_txpower, pgm_read_byte_near(&default_txpower));
eeprom_write_word(&eemem_nodeid, pgm_read_word_near(&default_nodeid));
x[0] = pgm_read_byte_near(&default_channel);
x[1]= ~x[0];
eeprom_write_word((uint16_t *)&eemem_channel, *(uint16_t *)x);
sei();
}
/* Always returns a valid channel */
return x[0];
}
static bool
get_eui64_from_eeprom(uint8_t macptr[sizeof(rimeaddr_t)]) {
cli();
eeprom_read_block ((void *)macptr, &eemem_mac_address, sizeof(rimeaddr_t));
sei();
return macptr[0]!=0xFF;
}
static uint16_t
get_panid_from_eeprom(void) {
return eeprom_read_word(&eemem_panid);
}
static uint16_t
get_panaddr_from_eeprom(void) {
return eeprom_read_word (&eemem_panaddr);
}
static uint8_t
get_txpower_from_eeprom(void)
{
return eeprom_read_byte(&eemem_txpower);
} }
static bool get_mac_from_eeprom(uint8_t* macptr) { #else /* !CONTIKI_CONF_SETTINGS_MANAGER */
eeprom_read_block ((void *)macptr, &mac_address, 8); /******************************Settings manager******************************/
return true; #include "settings.h"
} /* Disable the settings add routines to reduce eeprom wear during testing */
#if 0
#define settings_add(...) 0
#define settings_add_uint8(...) 0
#define settings_add_uint16(...) 0
#endif
static uint16_t get_panid_from_eeprom(void) { #if AVR_WEBSERVER
// TODO: Writeme! extern uint8_t eemem_mac_address[8]; //These are defined in httpd-fsdata.c via makefsdata.h
return IEEE802154_PANID; extern uint8_t eemem_server_name[16];
} extern uint8_t eemem_domain_name[30];
#endif
static uint16_t get_panaddr_from_eeprom(void) { static uint8_t
// TODO: Writeme! get_channel_from_eeprom() {
return 0; uint8_t x;
size_t size = 1;
if (settings_get(SETTINGS_KEY_CHANNEL, 0,(unsigned char*)&x, &size) == SETTINGS_STATUS_OK) {
if ((x<11) || (x>26)) {
PRINTF("Unusual RF channel %u in EEPROM\n",x);
}
PRINTD("<=Get RF channel %u.\n",x);
} else {
x = pgm_read_byte_near(&default_channel);
if (settings_add_uint8(SETTINGS_KEY_CHANNEL,x ) == SETTINGS_STATUS_OK) {
PRINTD("->Set EEPROM RF channel to %d.\n",x);
}
}
return x;
} }
static bool
void calibrate_rc_osc_32k(); get_eui64_from_eeprom(uint8_t macptr[8]) {
size_t size = sizeof(rimeaddr_t);
if(settings_get(SETTINGS_KEY_EUI64, 0, (unsigned char*)macptr, &size) == SETTINGS_STATUS_OK) {
PRINTD("<=Get MAC address.\n");
return true;
}
#if CONTIKI_CONF_RANDOM_MAC
PRINTD("--Generating random MAC address.\n");
generate_new_eui64(macptr);
#else
{uint8_t i;for (i=0;i<8;i++) macptr[i] = pgm_read_byte_near(default_mac_address+i);}
#endif
if (settings_add(SETTINGS_KEY_EUI64,(unsigned char*)macptr,8)) {
PRINTD("->Set EEPROM MAC address.\n");
}
return true;
}
static uint16_t
get_panid_from_eeprom(void) {
uint16_t x;
size_t size = 2;
if (settings_get(SETTINGS_KEY_PAN_ID, 0,(unsigned char*)&x, &size) == SETTINGS_STATUS_OK) {
PRINTD("<-Get PAN ID of %04x.\n",x);
} else {
x=pgm_read_word_near(&default_panid);
if (settings_add_uint16(SETTINGS_KEY_PAN_ID,x)==SETTINGS_STATUS_OK) {
PRINTD("->Set EEPROM PAN ID to %04x.\n",x);
}
}
return x;
}
static uint16_t
get_panaddr_from_eeprom(void) {
uint16_t x;
size_t size = 2;
if (settings_get(SETTINGS_KEY_PAN_ADDR, 0,(unsigned char*)&x, &size) == SETTINGS_STATUS_OK) {
PRINTD("<-Get PAN address of %04x.\n",x);
} else {
x=pgm_read_word_near(&default_panaddr);
if (settings_add_uint16(SETTINGS_KEY_PAN_ADDR,x)==SETTINGS_STATUS_OK) {
PRINTD("->Set EEPROM PAN address to %04x.\n",x);
}
}
return x;
}
static uint8_t
get_txpower_from_eeprom(void) {
uint8_t x;
size_t size = 1;
if (settings_get(SETTINGS_KEY_TXPOWER, 0,(unsigned char*)&x, &size) == SETTINGS_STATUS_OK) {
PRINTD("<-Get tx power of %d. (0=max)\n",x);
} else {
x=pgm_read_byte_near(&default_txpower);
if (settings_add_uint8(SETTINGS_KEY_TXPOWER,x)==SETTINGS_STATUS_OK) {
PRINTD("->Set EEPROM tx power of %d. (0=max)\n",x);
}
}
return x;
}
#endif /* CONTIKI_CONF_SETTINGS_MANAGER */
/*-------------------------Low level initialization------------------------*/ /*-------------------------Low level initialization------------------------*/
/*------Done in a subroutine to keep main routine stack usage small--------*/ /*------Done in a subroutine to keep main routine stack usage small--------*/
@ -195,7 +458,7 @@ void initialize(void)
#if STACKMONITOR #if STACKMONITOR
/* Simple stack pointer highwater monitor. Checks for magic numbers in the main /* Simple stack pointer highwater monitor. Checks for magic numbers in the main
* loop. In conjuction with TESTRTIMER, never-used stack will be printed * loop. In conjuction with PERIODICPRINTS, never-used stack will be printed
* every STACKMONITOR seconds. * every STACKMONITOR seconds.
*/ */
{ {
@ -212,23 +475,18 @@ uint16_t p=(uint16_t)&__bss_end;
* Some layers will ignore duplicates found in a history (e.g. Contikimac) * Some layers will ignore duplicates found in a history (e.g. Contikimac)
* causing the initial packets to be ignored after a short-cycle restart. * causing the initial packets to be ignored after a short-cycle restart.
*/ */
ADMUX =0x1E; //Select AREF as reference, measure 1.1 volt bandgap reference. random_init(rng_get_uint8());
ADCSRA=1<<ADEN; //Enable ADC, not free running, interrupt disabled, fastest clock
ADCSRA|=1<<ADSC; //Start conversion
while (ADCSRA&(1<<ADSC)); //Wait till done
PRINTFD("ADC=%d\n",ADC);
random_init(ADC);
ADCSRA=0; //Disable ADC
#define CONF_CALIBRATE_OSCCAL 0 #define CONF_CALIBRATE_OSCCAL 0
#if CONF_CALIBRATE_OSCCAL #if CONF_CALIBRATE_OSCCAL
void calibrate_rc_osc_32k();
{ {
extern uint8_t osccal_calibrated; extern uint8_t osccal_calibrated;
uint8_t i; uint8_t i;
PRINTF("\nBefore calibration OSCCAL=%x\n",OSCCAL); PRINTD("\nBefore calibration OSCCAL=%x\n",OSCCAL);
for (i=0;i<10;i++) { for (i=0;i<10;i++) {
calibrate_rc_osc_32k(); calibrate_rc_osc_32k();
PRINTF("Calibrated=%x\n",osccal_calibrated); PRINTD("Calibrated=%x\n",osccal_calibrated);
//#include <util/delay_basic.h> //#include <util/delay_basic.h>
//#define delay_us( us ) ( _delay_loop_2(1+(us*F_CPU)/4000000UL) ) //#define delay_us( us ) ( _delay_loop_2(1+(us*F_CPU)/4000000UL) )
// delay_us(50000); // delay_us(50000);
@ -237,16 +495,15 @@ uint8_t i;
} }
#endif #endif
#if ANNOUNCE_BOOT PRINTA("\n*******Booting %s*******\n",CONTIKI_VERSION_STRING);
PRINTF("\n*******Booting %s*******\n",CONTIKI_VERSION_STRING);
#endif
/* rtimers needed for radio cycling */ /* rtimers needed for radio cycling */
rtimer_init(); rtimer_init();
/* Initialize process subsystem */ /* Initialize process subsystem */
process_init(); process_init();
/* etimers must be started before ctimer_init */
/* etimers must be started before ctimer_init */
process_start(&etimer_process, NULL); process_start(&etimer_process, NULL);
#if RF230BB #if RF230BB
@ -258,22 +515,37 @@ uint8_t i;
/* Set addresses BEFORE starting tcpip process */ /* Set addresses BEFORE starting tcpip process */
rimeaddr_t addr; rimeaddr_t addr;
memset(&addr, 0, sizeof(rimeaddr_t)); // memset(&addr, 0, sizeof(rimeaddr_t));
get_mac_from_eeprom(addr.u8); get_eui64_from_eeprom(addr.u8);
#if UIP_CONF_IPV6 #if UIP_CONF_IPV6
memcpy(&uip_lladdr.addr, &addr.u8, 8); memcpy(&uip_lladdr.addr, &addr.u8, sizeof(rimeaddr_t));
#elif WITH_NODE_ID
node_id=get_panaddr_from_eeprom();
addr.u8[1]=node_id&0xff;
addr.u8[0]=(node_id&0xff00)>>8;
PRINTA("Node ID from eeprom: %X\n",node_id);
#endif #endif
rimeaddr_set_node_addr(&addr);
rf230_set_pan_addr( rf230_set_pan_addr(
get_panid_from_eeprom(), get_panid_from_eeprom(),
get_panaddr_from_eeprom(), get_panaddr_from_eeprom(),
(uint8_t *)&addr.u8 (uint8_t *)&addr.u8
); );
rf230_set_channel(get_channel_from_eeprom()); rf230_set_channel(get_channel_from_eeprom());
rf230_set_txpower(get_txpower_from_eeprom());
rimeaddr_set_node_addr(&addr); #if UIP_CONF_IPV6
PRINTA("MAC address %x:%x:%x:%x:%x:%x:%x:%x\n\r",addr.u8[0],addr.u8[1],addr.u8[2],addr.u8[3],addr.u8[4],addr.u8[5],addr.u8[6],addr.u8[7]);
PRINTFD("MAC address %x:%x:%x:%x:%x:%x:%x:%x\n",addr.u8[0],addr.u8[1],addr.u8[2],addr.u8[3],addr.u8[4],addr.u8[5],addr.u8[6],addr.u8[7]); #else
PRINTA("MAC address ");
uint8_t i;
for (i=sizeof(rimeaddr_t); i>0; i--){
PRINTA("%x:",addr.u8[i-1]);
}
PRINTA("\n");
#endif
/* Initialize stack protocols */ /* Initialize stack protocols */
queuebuf_init(); queuebuf_init();
@ -282,20 +554,20 @@ uint8_t i;
NETSTACK_NETWORK.init(); NETSTACK_NETWORK.init();
#if ANNOUNCE_BOOT #if ANNOUNCE_BOOT
PRINTF("%s %s, channel %u",NETSTACK_MAC.name, NETSTACK_RDC.name,rf230_get_channel()); PRINTA("%s %s, channel %u power %u",NETSTACK_MAC.name, NETSTACK_RDC.name,rf230_get_channel()),rf230_get_txpower();
if (NETSTACK_RDC.channel_check_interval) {//function pointer is zero for sicslowmac if (NETSTACK_RDC.channel_check_interval) {//function pointer is zero for sicslowmac
unsigned short tmp; unsigned short tmp;
tmp=CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval == 0 ? 1:\ tmp=CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval == 0 ? 1:\
NETSTACK_RDC.channel_check_interval()); NETSTACK_RDC.channel_check_interval());
if (tmp<65535) printf_P(PSTR(", check rate %u Hz"),tmp); if (tmp<65535) PRINTA(", check rate %u Hz",tmp);
} }
PRINTF("\n"); PRINTA("\n");
#if UIP_CONF_IPV6_RPL #if UIP_CONF_IPV6_RPL
PRINTF("RPL Enabled\n"); PRINTA("RPL Enabled\n");
#endif #endif
#if UIP_CONF_ROUTER #if UIP_CONF_ROUTER
PRINTF("Routing Enabled\n"); PRINTA("Routing Enabled\n");
#endif #endif
#endif /* ANNOUNCE_BOOT */ #endif /* ANNOUNCE_BOOT */
@ -305,12 +577,12 @@ uint8_t i;
process_start(&tcpip_process, NULL); process_start(&tcpip_process, NULL);
#else #else /* !RF230BB */
/* Original RF230 combined mac/radio driver */ /* Original RF230 combined mac/radio driver */
/* mac process must be started before tcpip process! */ /* mac process must be started before tcpip process! */
process_start(&mac_process, NULL); process_start(&mac_process, NULL);
process_start(&tcpip_process, NULL); process_start(&tcpip_process, NULL);
#endif /*RF230BB*/ #endif /* RF230BB */
#ifdef RAVEN_LCD_INTERFACE #ifdef RAVEN_LCD_INTERFACE
process_start(&raven_lcd_process, NULL); process_start(&raven_lcd_process, NULL);
@ -326,13 +598,13 @@ uint8_t i;
#if COFFEE_FILES #if COFFEE_FILES
int fa = cfs_open( "/index.html", CFS_READ); int fa = cfs_open( "/index.html", CFS_READ);
if (fa<0) { //Make some default web content if (fa<0) { //Make some default web content
PRINTF("No index.html file found, creating upload.html!\n"); PRINTA("No index.html file found, creating upload.html!\n");
PRINTF("Formatting FLASH file system for coffee..."); PRINTA("Formatting FLASH file system for coffee...");
cfs_coffee_format(); cfs_coffee_format();
PRINTF("Done!\n"); PRINTA("Done!\n");
fa = cfs_open( "/index.html", CFS_WRITE); fa = cfs_open( "/index.html", CFS_WRITE);
int r = cfs_write(fa, &"It works!", 9); int r = cfs_write(fa, &"It works!", 9);
if (r<0) PRINTF("Can''t create /index.html!\n"); if (r<0) PRINTA("Can''t create /index.html!\n");
cfs_close(fa); cfs_close(fa);
// fa = cfs_open("upload.html"), CFW_WRITE); // fa = cfs_open("upload.html"), CFW_WRITE);
// <html><body><form action="upload.html" enctype="multipart/form-data" method="post"><input name="userfile" type="file" size="50" /><input value="Upload" type="submit" /></form></body></html> // <html><body><form action="upload.html" enctype="multipart/form-data" method="post"><input name="userfile" type="file" size="50" /><input value="Upload" type="submit" /></form></body></html>
@ -351,7 +623,7 @@ uint8_t i;
/*--------------------------Announce the configuration---------------------*/ /*--------------------------Announce the configuration---------------------*/
#if ANNOUNCE_BOOT #if ANNOUNCE_BOOT
{
#if AVR_WEBSERVER #if AVR_WEBSERVER
uint8_t i; uint8_t i;
char buf[80]; char buf[80];
@ -360,36 +632,59 @@ uint8_t i;
for (i=0;i<UIP_DS6_ADDR_NB;i++) { for (i=0;i<UIP_DS6_ADDR_NB;i++) {
if (uip_ds6_if.addr_list[i].isused) { if (uip_ds6_if.addr_list[i].isused) {
httpd_cgi_sprint_ip6(uip_ds6_if.addr_list[i].ipaddr,buf); httpd_cgi_sprint_ip6(uip_ds6_if.addr_list[i].ipaddr,buf);
PRINTF("IPv6 Address: %s\n",buf); PRINTA("IPv6 Address: %s\n",buf);
} }
} }
eeprom_read_block (buf,server_name, sizeof(server_name)); cli();
buf[sizeof(server_name)]=0; eeprom_read_block (buf,eemem_server_name, sizeof(eemem_server_name));
PRINTF("%s",buf); sei();
eeprom_read_block (buf,domain_name, sizeof(domain_name)); buf[sizeof(eemem_server_name)]=0;
buf[sizeof(domain_name)]=0; PRINTA("%s",buf);
cli();
eeprom_read_block (buf,eemem_domain_name, sizeof(eemem_domain_name));
sei();
buf[sizeof(eemem_domain_name)]=0;
size=httpd_fs_get_size(); size=httpd_fs_get_size();
#ifndef COFFEE_FILES #ifndef COFFEE_FILES
PRINTF(".%s online with fixed %u byte web content\n",buf,size); PRINTA(".%s online with fixed %u byte web content\n",buf,size);
#elif COFFEE_FILES==1 #elif COFFEE_FILES==1
PRINTF(".%s online with static %u byte EEPROM file system\n",buf,size); PRINTA(".%s online with static %u byte EEPROM file system\n",buf,size);
#elif COFFEE_FILES==2 #elif COFFEE_FILES==2
PRINTF(".%s online with dynamic %u KB EEPROM file system\n",buf,size>>10); PRINTA(".%s online with dynamic %u KB EEPROM file system\n",buf,size>>10);
#elif COFFEE_FILES==3 #elif COFFEE_FILES==3
PRINTF(".%s online with static %u byte program memory file system\n",buf,size); PRINTA(".%s online with static %u byte program memory file system\n",buf,size);
#elif COFFEE_FILES==4 #elif COFFEE_FILES==4
PRINTF(".%s online with dynamic %u KB program memory file system\n",buf,size>>10); PRINTA(".%s online with dynamic %u KB program memory file system\n",buf,size>>10);
#endif /* COFFEE_FILES */ #endif /* COFFEE_FILES */
#else #else
PRINTF("Online\n"); PRINTA("Online\n");
#endif /* AVR_WEBSERVER */ #endif /* AVR_WEBSERVER */
#endif /* ANNOUNCE_BOOT */ #endif /* ANNOUNCE_BOOT */
} }
}
#if RF230BB #if ROUTES && UIP_CONF_IPV6
extern char rf230_interrupt_flag, rf230processflag; static void
ipaddr_add(const uip_ipaddr_t *addr)
{
uint16_t a;
int8_t i, f;
for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) {
a = (addr->u8[i] << 8) + addr->u8[i + 1];
if(a == 0 && f >= 0) {
if(f++ == 0) PRINTF("::");
} else {
if(f > 0) {
f = -1;
} else if(i > 0) {
PRINTF(":");
}
PRINTF("%x",a);
}
}
}
#endif #endif
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
@ -422,39 +717,64 @@ main(void)
*/ */
extern uint8_t rf230_calibrated; extern uint8_t rf230_calibrated;
if (rf230_calibrated) { if (rf230_calibrated) {
PRINTF("\nRF230 calibrated!\n"); PRINTD("\nRF230 calibrated!\n");
rf230_calibrated=0; rf230_calibrated=0;
} }
#endif #endif
#if DEBUGFLOWSIZE
if (debugflowsize) {
debugflow[debugflowsize]=0;
PRINTF("%s",debugflow);
debugflowsize=0;
}
#endif
watchdog_periodic();
#if PERIODICPRINTS
#if TESTRTIMER #if TESTRTIMER
/* Timeout can be increased up to 8 seconds maximum (at 8MHz with 1024 prescaler) /* Timeout can be increased up to 8 seconds maximum.
* A one second cycle is convenient for triggering the various debug printouts. * A one second cycle is convenient for triggering the various debug printouts.
* The triggers are staggered to avoid printing everything at once. * The triggers are staggered to avoid printing everything at once.
*/ */
if (rtimerflag) { if (rtimerflag) {
rtimer_set(&rt, RTIMER_NOW()+ RTIMER_ARCH_SECOND*1UL, 1,(void *) rtimercycle, NULL); rtimer_set(&rt, RTIMER_NOW()+ RTIMER_ARCH_SECOND*1UL, 1,(void *) rtimercycle, NULL);
rtimerflag=0; rtimerflag=0;
#else
if (clocktime!=clock_seconds()) {
clocktime=clock_seconds();
#endif
#if STAMPS #if STAMPS
if ((rtime%STAMPS)==0) { if ((clocktime%STAMPS)==0) {
PRINTF("%us ",rtime); #if ENERGEST_CONF_ON
#include "lib/print-stats.h"
print_stats();
#elif RADIOSTATS
extern volatile unsigned long radioontime;
PRINTF("%u(%u)s\n",clocktime,radioontime);
#else
PRINTF("%us\n",clocktime);
#endif
} }
#endif #endif
rtime+=1; #if TESTRTIMER
clocktime+=1;
#endif
#if PINGS #if PINGS && UIP_CONF_IPV6
if ((rtime%PINGS)==1) { extern void raven_ping6(void);
if ((clocktime%PINGS)==1) {
PRINTF("**Ping\n"); PRINTF("**Ping\n");
raven_ping6(); raven_ping6();
} }
#endif #endif
#if ROUTES #if ROUTES && UIP_CONF_IPV6
if ((rtime%ROUTES)==2) { if ((clocktime%ROUTES)==2) {
//#if UIP_CONF_IPV6_RPL
//#include "rpl.h"
extern uip_ds6_nbr_t uip_ds6_nbr_cache[]; extern uip_ds6_nbr_t uip_ds6_nbr_cache[];
extern uip_ds6_route_t uip_ds6_routing_table[]; extern uip_ds6_route_t uip_ds6_routing_table[];
extern uip_ds6_netif_t uip_ds6_if; extern uip_ds6_netif_t uip_ds6_if;
@ -462,7 +782,7 @@ extern uip_ds6_netif_t uip_ds6_if;
uint8_t i,j; uint8_t i,j;
PRINTF("\nAddresses [%u max]\n",UIP_DS6_ADDR_NB); PRINTF("\nAddresses [%u max]\n",UIP_DS6_ADDR_NB);
for (i=0;i<UIP_DS6_ADDR_NB;i++) { for (i=0;i<UIP_DS6_ADDR_NB;i++) {
if (uip_ds6_if.addr_list[i].isused) { if (uip_ds6_if.addr_list[i].isused) {
ipaddr_add(&uip_ds6_if.addr_list[i].ipaddr); ipaddr_add(&uip_ds6_if.addr_list[i].ipaddr);
PRINTF("\n"); PRINTF("\n");
} }
@ -496,7 +816,7 @@ extern uip_ds6_netif_t uip_ds6_if;
#endif #endif
#if STACKMONITOR #if STACKMONITOR
if ((rtime%STACKMONITOR)==3) { if ((clocktime%STACKMONITOR)==3) {
extern uint16_t __bss_end; extern uint16_t __bss_end;
uint16_t p=(uint16_t)&__bss_end; uint16_t p=(uint16_t)&__bss_end;
do { do {
@ -510,19 +830,10 @@ if ((rtime%STACKMONITOR)==3) {
#endif #endif
} }
#endif /* TESTRTIMER */ #endif /* PERIODICPRINTS */
//Use with RF230BB DEBUGFLOW to show path through driver
#if RF230BB&&0
extern uint8_t debugflowsize,debugflow[];
if (debugflowsize) {
debugflow[debugflowsize]=0;
PRINTF("%s",debugflow);
debugflowsize=0;
}
#endif
#if RF230BB&&0 #if RF230BB&&0
extern uint8_t rf230processflag;
if (rf230processflag) { if (rf230processflag) {
PRINTF("rf230p%d",rf230processflag); PRINTF("rf230p%d",rf230processflag);
rf230processflag=0; rf230processflag=0;
@ -530,6 +841,7 @@ extern uint8_t debugflowsize,debugflow[];
#endif #endif
#if RF230BB&&0 #if RF230BB&&0
extern uint8_t rf230_interrupt_flag;
if (rf230_interrupt_flag) { if (rf230_interrupt_flag) {
// if (rf230_interrupt_flag!=11) { // if (rf230_interrupt_flag!=11) {
PRINTF("**RI%u",rf230_interrupt_flag); PRINTF("**RI%u",rf230_interrupt_flag);
@ -547,25 +859,3 @@ void log_message(char *m1, char *m2)
{ {
PRINTF("%s%s\n", m1, m2); PRINTF("%s%s\n", m1, m2);
} }
#if ROUTES
static void
ipaddr_add(const uip_ipaddr_t *addr)
{
uint16_t a;
int8_t i, f;
for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) {
a = (addr->u8[i] << 8) + addr->u8[i + 1];
if(a == 0 && f >= 0) {
if(f++ == 0) PRINTF("::");
} else {
if(f > 0) {
f = -1;
} else if(i > 0) {
PRINTF(":");
}
PRINTF("%x",a);
}
}
}
#endif

View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 2005, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef NODE_ID_H
#define NODE_ID_H
#include "contiki-conf.h"
void node_id_restore(void);
void node_id_burn(uint16_t node_id);
extern uint16_t node_id;
#endif /* !NODE_ID_H */

View file

@ -280,7 +280,7 @@ uint16_t eemem_panid EEMEM = IEEE802154_PANID;
uint16_t eemem_panid EEMEM = 0xABCD; uint16_t eemem_panid EEMEM = 0xABCD;
#endif #endif
#ifdef IEEE802154_PANADDR #ifdef IEEE802154_PANADDR
uint16_t eemem_panaddr EEMEM = IEEE802154_PANID; uint16_t eemem_panaddr EEMEM = IEEE802154_PANADDR;
#else #else
uint16_t eemem_panaddr EEMEM = 0; uint16_t eemem_panaddr EEMEM = 0;
#endif #endif

124
tools/serial-log.pl Normal file
View file

@ -0,0 +1,124 @@
#!/usr/bin/perl -w
#Log serial port to terminal and file with timestamps
#D.Kopf 8/28/2001
#
use Device::SerialPort;
use Term::ReadKey;
use Getopt::Long;
use Time::HiRes qw(usleep);
use strict;
my $term = '/dev/com1';
my $baud = '57600';
my $rts = 'none';
my $logfile = 'none';
my $ssss = '';
GetOptions ('terminal=s' => \$term,
'baud=s' => \$baud,
'rts=s' => \$rts,
'seconds!' => \$ssss,
'logfile:s' =>\$logfile
) or goto printhelp;
goto bypass;
printhelp:
print "Example serial-log.pl -t /dev/ttyS0 -b 57600 -r none -l logfile\n";
print " -t, --terminal\n";
print " -b, --baud\n";
print " -r,--rts [none|rts] flow control\n";
print " -s,--seconds Display ssss instead of hh:mm:ss\n";
print " -l,--logfile outputfile (.log will be added, -l defaults to serial.log)\n";
print "\n";
print "The default is equivalent to serial-log.pl -t /dev/com1 -b 57600 -r none\n";
exit;
bypass:
my $ob = Device::SerialPort->new ($term) or die "Can't start $term\n";
# next test will die at runtime unless $ob
$ob->baudrate($baud);
$ob->parity('none');
$ob->databits(8);
$ob->stopbits(1);
if($rts eq 'rts') {
$ob->handshake('rts');
} else {
$ob->handshake('none');
}
$ob->read_const_time(1000); # 1 second per unfulfilled "read" call
$ob->rts_active(1);
my $c; my $count;
my ($hh,$mm,$ss,$mday,$mon,$year,$wday,$yday,$isdst,$theTime,$seconds,$startseconds);
#use POSIX qw(strftime);
($ss,$mm,$hh,$mday,$mon,$year,$wday,$yday,$isdst) = localtime;
$theTime = sprintf "on %02d/%02d/%04d at %02d:%02d:%02d\n", $mon+1, $mday, $year+1900, $hh, $mm, $ss;
if($logfile ne 'none') {
if($logfile eq '') {$logfile = 'serial';}
$logfile ="${logfile}.log";
$c=1;
open LOGFILE, "$logfile" or do {$c=0;};
if ($c) {
print "File $logfile exists. Restart, append, or quit (r,a,q) (q) ? ";
#$| = 1; # force a flush after print
$_ = <STDIN>;chomp;
if ($_ eq 'r') {
open LOGFILE, ">$logfile" or die $!;
print "Restarting $logfile $theTime\n";
print LOGFILE "serial-log.pl logging to $logfile started $theTime\n";
} else {
if ($_ eq 'a') {
open LOGFILE, ">>$logfile" or die $!;
print "Appending to $logfile $theTime\n";
print LOGFILE "serial-log.pl appending to $logfile $theTime\n";
} else {
print "Quitting, file unchanged.\n";
exit;
}
}
} else {
open LOGFILE, ">$logfile" or die $!;
print LOGFILE "serial-log.pl logging to $logfile started $theTime\n";
print "Starting $logfile $theTime\n";
}
LOGFILE->autoflush(1);
} else {
$logfile='';
print "Serial logging of $term started $theTime\n";
}
if($ssss ne '') {
$startseconds=$hh*3600+$mm*60+$ss;
}
$theTime='';
while(1) {
($count, $c) = $ob->read(1);
if (defined($count) && ($count != 0)) {
if ($theTime eq '') {
($ss,$mm,$hh) = localtime(time);
if ($ssss ne '') {
$seconds = $hh*3600+$mm*60+$ss-$startseconds;
if ($seconds < 0) {$seconds+=24*60*60;}
$theTime = sprintf("%04d ",$seconds);
} else {
$theTime = sprintf("%02d:%02s:%02d ", $hh,$mm,$ss);
#$theTime = strftime "%H:%M:%S ", localtime;
}
print $theTime ;
if ($logfile) {LOGFILE->autoflush(1);print LOGFILE $theTime;}
}
print $c ;
if ($logfile) { print LOGFILE $c;}
if ($c eq "\n") {$theTime=''};
}
}
if ($logfile) {close LOGFILE or die $!}
$ob -> close or die "Serial port close failed: $!\n";
ReadMode 0;
undef $ob; # closes port AND frees memory in perl
exit;