From 53787ff65f3141d81e9bf59eaebb9cb6a0b43fbc Mon Sep 17 00:00:00 2001 From: klueska Date: Thu, 7 Jun 2007 07:22:18 +0000 Subject: [PATCH] Added support for MAC OS in tools compilation --- tools/configure.ac | 8 + tools/platforms/msp430/motelist/Makefile.am | 7 +- .../platforms/msp430/motelist/motelist-macos | 75 +++ .../java/serial/NativeSerial_darwin.cpp | 511 ++++++++++++++++++ tools/tinyos/misc/tos-install-jni.in | 2 +- tools/tinyos/misc/tos-locate-jre | 21 +- 6 files changed, 619 insertions(+), 5 deletions(-) create mode 100644 tools/platforms/msp430/motelist/motelist-macos create mode 100644 tools/tinyos/java/serial/NativeSerial_darwin.cpp diff --git a/tools/configure.ac b/tools/configure.ac index 60ec10cb..197c8990 100644 --- a/tools/configure.ac +++ b/tools/configure.ac @@ -77,6 +77,13 @@ case $host in INSTALLJNI="install --group=SYSTEM" CYGWIN=yes ;; + *-apple-darwin*) + JNIPREFIX=lib + JNISUFFIX=jnilib + INSTALLJNI="install" + AC_MSG_RESULT(no) + DARWIN=yes + ;; *) JNIPREFIX=lib JNISUFFIX=so @@ -86,6 +93,7 @@ case $host in esac AM_CONDITIONAL([CYGWIN], [test "$CYGWIN"]) +AM_CONDITIONAL([DARWIN], [test "$DARWIN"]) AC_MSG_CHECKING(for JDK location) JAVAC_DIR=`/bin/sh tinyos/misc/tos-locate-jre --javac` diff --git a/tools/platforms/msp430/motelist/Makefile.am b/tools/platforms/msp430/motelist/Makefile.am index 54b7191e..f0b5e9d9 100644 --- a/tools/platforms/msp430/motelist/Makefile.am +++ b/tools/platforms/msp430/motelist/Makefile.am @@ -5,7 +5,12 @@ dist_man_MANS = motelist.1 if CYGWIN motelist: motelist-win32.cpp g++ -O3 -Wall -o motelist motelist-win32.cpp -else +else !CYGWIN +if DARWIN +motelist: motelist-macos + cp motelist-macos motelist +else !DARWIN motelist: motelist-linux cp motelist-linux motelist endif +endif diff --git a/tools/platforms/msp430/motelist/motelist-macos b/tools/platforms/msp430/motelist/motelist-macos new file mode 100644 index 00000000..ee5618b1 --- /dev/null +++ b/tools/platforms/msp430/motelist/motelist-macos @@ -0,0 +1,75 @@ +#!/usr/bin/perl -w +use strict; + +my $help = <<'EOF'; +usage: motelist [options] + +options: + -h display this help + -c compact format, not pretty but easier for parsing +EOF + +my %Opt = ( + compact => 0, + dev_prefix => [ "/dev/tty.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; } + else { print STDERR "$help\nerror, unknown command line option $opt\n"; exit 1; } +} + +print_motelist( scan_dev() ); + +# +# Scan /dev for tty.usbserial-* +# +sub scan_dev { + my @devs; + foreach (`ls /dev/tty.usbserial-* 2>&1`) { + my($dev, $serial) = /(\/dev\/tty.usbserial-(\S+))/; + if ($serial ne "*:") { + my $d; + $d->{"InfoSerial"} = $serial; + $d->{"SerialDevName"} = $dev; + push(@devs, $d); + } + } + return @devs; +} + + +# +# 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} ) { + print << "EOF" unless $Opt{compact}; +Reference Device Description +---------- --------------------------- --------------------------------------- +EOF + } + + # Print the usb information + for my $dev (@devs) { + my $desc = "(none)"; + my @output = ( $dev->{"InfoSerial"}, $dev->{"SerialDevName"}, $desc ); + if( $Opt{compact} ) { + print join(",",@output) . "\n"; + } else { + printf( "%-10s %-27s %s\n", @output ); + } + } +} diff --git a/tools/tinyos/java/serial/NativeSerial_darwin.cpp b/tools/tinyos/java/serial/NativeSerial_darwin.cpp new file mode 100644 index 00000000..6a167fdf --- /dev/null +++ b/tools/tinyos/java/serial/NativeSerial_darwin.cpp @@ -0,0 +1,511 @@ +//$Id$ + +/* "Copyright (c) 2000-2003 The Regents of the University of California. + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose, without fee, and without written agreement + * is hereby granted, provided that the above copyright notice, the following + * two paragraphs and the author appear in all copies of this software. + * + * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT + * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY + * OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." + */ + +//@author Cory Sharp + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "NativeSerialEnums.h" +using namespace NativeSerialEnums; + + +class comm_port_error : public std::runtime_error +{ + public: + comm_port_error( const char* msg ): std::runtime_error(msg) { } +}; + + +class NativeSerial +{ +public: + typedef std::string String; + +private: + + std::string m_portname; + int m_fd; + int m_events_in; + int m_events_out; + bool m_wait_for_events; + +protected: + + void note( std::string s ) + { + //std::cout << "NativeSerial_linux " << m_portname << ": " << s << std::endl; + } + + String cat( const char* prefix, const String& err ) + { + return (prefix == NULL ? "" : String(prefix)+": ") + err; + } + + void errno_wrap( bool error, const char* extra_err = NULL ) + { + if( error && (errno != 0) ) + throw comm_port_error( cat(extra_err, strerror(errno)).c_str() ); + } + + void block_on_read( bool block ) + { +note( "block_on_read begin" ); + fcntl( m_fd, F_SETFL, (block ? 0 : FNDELAY) ); +note( "block_on_read end" ); + } + + struct termios get_comm_state() + { +note( "get_comm_state begin" ); + struct termios options; + errno_wrap( tcgetattr( m_fd, &options ) == -1, "get_comm_state" ); +note( "get_comm_state end" ); + return options; + } + + + int get_modem_status() + { +note( "get_modem_status begin" ); + int status = 0; + errno_wrap( ioctl( m_fd, TIOCMGET, &status ) == -1, "get_modem_status" ); +note( "get_modem_status end" ); + return status; + } + + void set_modem_status( int status ) + { +note( "set_modem_status begin" ); + errno_wrap( ioctl( m_fd, TIOCMSET, &status ) == -1, "set_modem_status" ); +note( "set_modem_status end" ); + } + + int baud_to_enum( int baud ) + { + switch( baud ) + { + case 0: return B0; + case 50: return B50; + case 75: return B75; + case 110: return B110; + case 134: return B134; + case 150: return B150; + case 200: return B200; + case 300: return B300; + case 600: return B600; + case 1200: return B1200; + case 1800: return B1800; + case 2400: return B2400; + case 4800: return B4800; + case 9600: return B9600; + case 19200: return B19200; + case 38400: return B38400; + case 57600: return B57600; + case 115200: return B115200; + case 230400: return B230400; + } + throw comm_port_error("baud_to_enum, bad baud rate"); + } + + int enum_to_baud( int baudenum ) + { + switch( baudenum ) + { + case B0: return 0; + case B50: return 50; + case B75: return 75; + case B110: return 110; + case B134: return 134; + case B150: return 150; + case B200: return 200; + case B300: return 300; + case B600: return 600; + case B1200: return 1200; + case B1800: return 1800; + case B2400: return 2400; + case B4800: return 4800; + case B9600: return 9600; + case B19200: return 19200; + case B38400: return 38400; + case B57600: return 57600; + case B115200: return 115200; + case B230400: return 230400; + } + throw comm_port_error("enum_to_baud, bad baud rate"); + } + +/* + static DWORD map_events_to_win32( int event ) + { + DWORD ev = 0; + if( event & DATA_AVAILABLE ) ev |= EV_RXCHAR; + if( event & OUTPUT_EMPTY ) ev |= EV_TXEMPTY; + if( event & CTS ) ev |= EV_CTS; + if( event & DSR ) ev |= EV_DSR; + if( event & RING_INDICATOR ) ev |= EV_RING; + if( event & CARRIER_DETECT ) ev |= EV_RLSD; + if( event & OVERRUN_ERROR ) ev |= EV_ERR; + if( event & PARITY_ERROR ) ev |= EV_ERR; + if( event & FRAMING_ERROR ) ev |= EV_ERR; + if( event & BREAK_INTERRUPT ) ev |= EV_BREAK; + return ev; + } + + static int map_events_from_win32( DWORD ev, DWORD errors ) + { + int event = 0; + if( ev & EV_RXCHAR ) event |= DATA_AVAILABLE; + if( ev & EV_TXEMPTY ) event |= OUTPUT_EMPTY; + if( ev & EV_CTS ) event |= CTS; + if( ev & EV_DSR ) event |= DSR; + if( ev & EV_RING ) event |= RING_INDICATOR; + if( ev & EV_RLSD ) event |= CARRIER_DETECT; + if( ev & EV_ERR ) + { + if( errors & CE_BREAK ) event |= BREAK_INTERRUPT; + if( errors & CE_FRAME ) event |= FRAMING_ERROR; + if( errors & CE_IOE ) throw comm_port_error("Win32 Comm IO Error"); + if( errors & CE_MODE ) throw comm_port_error("Win32 Comm Invalid Mode"); + if( errors & CE_OVERRUN ) event |= OVERRUN_ERROR; + if( errors & CE_RXOVER ) event |= OVERRUN_ERROR; //?? okay + if( errors & CE_RXPARITY ) event |= PARITY_ERROR; + if( errors & CE_TXFULL ) event |= OVERRUN_ERROR; //?? okay + } + if( ev & EV_BREAK ) event |= BREAK_INTERRUPT; + return event; + } +*/ + +public: + + void setSerialPortParams( int baudrate, int databits, int stopbits, int parity ) + { +note( "setSerialPortParams begin" ); + struct termios state = get_comm_state(); + + int baudenum = baud_to_enum(baudrate); + errno_wrap( cfsetispeed( &state, baudenum ) == -1, "baudrate" ); + errno_wrap( cfsetospeed( &state, baudenum ) == -1, "baudrate" ); + + //throw comm_port_error("nuthin"); + + state.c_cflag &= ~CSIZE; + switch( databits ) + { + case 5: state.c_cflag |= CS5; break; + case 6: state.c_cflag |= CS6; break; + case 7: state.c_cflag |= CS7; break; + case 8: default: state.c_cflag |= CS8; + } + + if( stopbits == STOPBITS_2 ) + state.c_cflag |= CSTOPB; + else + state.c_cflag &= ~CSTOPB; + + state.c_cflag |= PARENB; + switch( parity ) + { + case NPARITY_EVEN: state.c_cflag &= ~PARODD; break; + case NPARITY_ODD: state.c_cflag |= PARODD; break; + case NPARITY_NONE: default: state.c_cflag &= ~PARENB; + } + + errno_wrap( tcsetattr( m_fd, TCSANOW, &state ) == -1, "set_comm_state" ); +note( "setSerialPortParams end" ); + } + + int getBaudRate() + { + struct termios state = get_comm_state(); + return enum_to_baud( cfgetospeed( &state ) ); + } + + int getDataBits() + { + switch( get_comm_state().c_cflag & CSIZE ) + { + case CS5: return 5; + case CS6: return 6; + case CS7: return 7; + case CS8: default: return 8; + } + } + + int getStopBits() + { + int stop = get_comm_state().c_cflag; + return (stop & CSTOPB) ? STOPBITS_2 : STOPBITS_1; + } + + int getParity() + { + int parity = get_comm_state().c_cflag; + if( parity & PARENB ) + return (parity & PARODD) ? NPARITY_ODD : NPARITY_EVEN; + return NPARITY_NONE; + } + + int read( signed char* buffer, int off, int len ) + { +note( "read begin" ); + int nread = ::read( m_fd, buffer+off, len ); + errno_wrap( nread == -1, "read" ); +#if 0 +printf(" ... read:"); +for( int i=0; i 0) ? ((unsigned char)byte) : -1; + } + + int write( int b ) + { + signed char byte = b; + return write( &byte, 0, 1 ); + } + + int available() + { +note( "available begin" ); + int navail = 0; + int rv = 0; + errno_wrap( rv=ioctl( m_fd, FIONREAD, &navail ) == -1, "available" ); +//printf("... fionread=%d, rv=%d\n",navail,rv); +note( "available end" ); + return navail; + } + + void notifyOn( int event, bool enable ) + { + if( enable ) + m_events_in |= event; + else + m_events_in &= ~event; + } + + bool isNotifyOn( int event ) + { + return (m_events_in & event) != 0; + } + + bool waitForEvent() + { +note( "waitForEvent begin" ); + fd_set input; + struct timeval tv; + m_events_out = 0; + + while( m_wait_for_events && (m_fd != -1) && (m_events_out == 0) ) + { + FD_ZERO( &input ); + FD_SET( m_fd, &input ); + tv.tv_sec = 0; + tv.tv_usec = 100*1000; // 1ms is the minimum resolution, at best + + if( select( m_fd+1, &input, NULL, NULL, &tv ) == -1 ) + { + if( errno == EINTR ) + break; + errno_wrap( true, "waitForEvent.select" ); + } + + if( FD_ISSET( m_fd, &input ) ) + m_events_out |= DATA_AVAILABLE; + } + + m_wait_for_events = true; +note( "waitForEvent end" ); + return (m_events_out != 0); + } + + bool cancelWait() + { +note( "cancelWait begin" ); + m_wait_for_events = false; +note( "cancelWait end" ); + } + + bool didEventOccur( int event ) + { + return (m_events_out & event) != 0; + } + + void setDTR( bool high ) + { + if( high ) + set_modem_status( get_modem_status() | TIOCM_DTR ); + else + set_modem_status( get_modem_status() & ~TIOCM_DTR ); + } + + void setRTS( bool high ) + { + if( high ) + set_modem_status( get_modem_status() | TIOCM_RTS ); + else + set_modem_status( get_modem_status() & ~TIOCM_RTS ); + } + + bool isDTR() + { + return (get_modem_status() & TIOCM_DTR) != 0; + } + + bool isRTS() + { + return (get_modem_status() & TIOCM_RTS) != 0; + } + + bool isCTS() + { + return (get_modem_status() & TIOCM_CTS) != 0; + } + + bool isDSR() + { + return (get_modem_status() & TIOCM_DSR) != 0; + } + + bool isRI() + { + return (get_modem_status() & TIOCM_RI) != 0; + } + + bool isCD() + { + return (get_modem_status() & TIOCM_CD) != 0; + } + + void sendBreak( int millis ) + { + } + + NativeSerial( const char* portname ): + m_fd(-1), + m_events_in(0), + m_events_out(0), + m_wait_for_events(true) + { + m_portname = portname; +note( "constructor begin" ); + m_fd = open( portname, O_RDWR | O_NOCTTY | O_NONBLOCK ); + errno_wrap( m_fd == -1, "open" ); + +//std::cout << "NativeSerial constructor [1] " << portname << std::endl; + + block_on_read(false); + + // set default port parmeters + struct termios options = get_comm_state(); + + // disable rts/cts, no parity bits, one stop bit, clear databits mask + //local mode, enable receiver, 8 databits + options.c_cflag = CLOCAL | CREAD | CS8; + + //raw mode + options.c_lflag = 0; + + //disable software flow control, etc + options.c_iflag = IGNPAR | IGNBRK; + + //raw output mode + options.c_oflag = 0; + + //set thresholds + options.c_cc[VMIN] = 0; + options.c_cc[VTIME] = 0; + + errno_wrap( tcflush( m_fd, TCIOFLUSH ) == -1, "flush" ); + errno_wrap( tcsetattr( m_fd, TCSANOW, &options ) == -1, "setattr" ); + + setDTR(false); + setRTS(false); +note( "constructor end" ); + } + + ~NativeSerial() + { +note( "destructor begin" ); + close(); +note( "destructor end" ); + } + + void close() + { +note( "close begin" ); +//std::cout << "NativeSerial_linux close fd=" << m_fd << std::endl; + if( m_fd != -1 ) + { + cancelWait(); + struct timeval tv = { tv_sec:0, tv_usec:1100 }; + select( 0, NULL, NULL, NULL, &tv ); + ::close( m_fd ); + m_fd = -1; + } +note( "close end" ); + } + + static std::string getTOSCommMap() + { + const char* env = getenv( "TOSCOMMMAP" ); + return (env == NULL) ? "com1=/dev/ttyS0:usb1=/dev/ttyUSB0" : env; + } +}; + + +#include "TOSComm_wrap.cxx" + diff --git a/tools/tinyos/misc/tos-install-jni.in b/tools/tinyos/misc/tos-install-jni.in index bfb7b5ab..3a8d6f4a 100644 --- a/tools/tinyos/misc/tos-install-jni.in +++ b/tools/tinyos/misc/tos-install-jni.in @@ -10,7 +10,7 @@ if [ $? -ne 0 ]; then exit 1 fi -if cygpath -w / >/dev/null 2>/dev/null; then +if [ cygpath -w / >/dev/null 2>/dev/null ] || [ `uname` == "Darwin" ]; then echo "Installing Java JNI code in $jni ... " for lib in $tinyoslibdir/*.@JNISUFFIX@; do @INSTALLJNI@ $lib "$jni" || exit 1 diff --git a/tools/tinyos/misc/tos-locate-jre b/tools/tinyos/misc/tos-locate-jre index 55908ed9..8820ee34 100755 --- a/tools/tinyos/misc/tos-locate-jre +++ b/tools/tinyos/misc/tos-locate-jre @@ -49,6 +49,11 @@ case `uname` in jhome=`cygpath -u "$jhome"` ;; + Darwin) + #Just statically typed in, uses default location of installation for XTools. May need to be fixed + jhome=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK + ;; + Linux) # Check gentoo java configuration javapath=`java-config -c 2>/dev/null` @@ -108,7 +113,9 @@ if [ "$jni" = "yes" ]; then # Look for a likely JNI directory # Windows, and IBM Java: in jre/bin # Sun Java on Linux: in jre/lib/i386 - if "$jhome/bin/java" -version 2>&1 | grep -q IBM || cygpath -w / >/dev/null 2>/dev/null; then + if [ `uname` = "Darwin" ]; then + jnilocate "/Library/java/Extensions" + elif "$jhome/bin/java" -version 2>&1 | grep -q IBM || cygpath -w / >/dev/null 2>/dev/null; then jnilocate "$jhome/jre/bin" || jnilocate "$jhome/bin" else arch=`uname -m` @@ -118,9 +125,17 @@ if [ "$jni" = "yes" ]; then jnilocate "$jhome/lib/i386" fi elif [ "$javac" = "yes" ]; then - dir="$jhome/bin" + if [ `uname` = "Darwin" ]; then + dir="$jhome/Commands" + else + dir="$jhome/bin" + fi elif [ "$java" = "yes" ]; then - dir="$jhome/bin" + if [ `uname` = "Darwin" ]; then + dir="$jhome/Commands" + else + dir="$jhome/bin" + fi fi # Check that what we found actually exists -- 2.39.2