JFlash v3


A small application to allow users in linux (…and possibly windows, but not tested) to use openocd without having to remember the telnet command sequence.

I use this program to flash my Imote2s

This is version 3 of the program, which now accepts some flags to set various modes for the JTAG… I’ll document these later.

A useful link, should you want to debug on a live board: Using GDB with openOCD

import java.io.*;
import java.net.*;
import java.util.*;
import java.util.concurrent.*;

public class JFlash{
       
        private static Socket ocdSock = null;
        private static PrintWriter out = null;
        private static BufferedReader in = null;
       
        private static MsgWatcher inWatch = null;
       
        private static BufferedReader OcdErr = null;
        private static BufferedReader OcdOut = null;
       
        private static MsgWatcher OcdErrWatch = null;
        private static MsgWatcher OcdOutWatch = null;

        private static int writeMode = 0;
        private static int writeSpeed = 0;
        private static boolean debugMode = false;
        private static boolean terminalMode = false;

        public static void main( String[] args ){
               
                String flashFile = new String("main.exe");
               
                for( String arg : args ){
                        if( arg != null ){
                                if( arg.startsWith("-f") ){
                                        flashFile = arg.substring(2);
                                }else if( arg.startsWith("-s") ){
                                        writeSpeed = Integer.parseInt( arg.substring(2) );
                                }else if( arg.startsWith("-m") ){
                                        writeMode = Integer.parseInt( arg.substring(2) );
                                }else if( arg.startsWith("-d") ){
                                        debugMode = true;
                                }else if( arg.startsWith("-t") ){
                                        terminalMode = true;
                                        debugMode = true;
                                        System.out.println("[Sys] Terminal mode forced DEBUG mode!");
                                }else{
                                        System.out.println("[Sys] Unknown command line argument ‘" +arg+ "’ skipped!");
                                }
                        }
                }
               
                try{
                       
                        Runtime r = Runtime.getRuntime();
                       
                        System.out.print("[Sys] Killing any other OpenOCD instances… ");
                        Process kill = r.exec("killall openocd");
                        kill.waitFor();
                        System.out.println("Done");
                       
                        System.out.println("[Sys] Starting OpenOCD… ");
                        Process openOCD = r.exec("openocd -f /usr/local/etc/arm-wiggler.cfg");
                        OcdErr = new BufferedReader( new InputStreamReader(openOCD.getErrorStream()) );
                        OcdOut = new BufferedReader( new InputStreamReader(openOCD.getInputStream()) );
                       
                        OcdErrWatch = new MsgWatcher( OcdErr, "[Err] " );
                        OcdErrWatch.start();
                        OcdOutWatch = new MsgWatcher( OcdOut, "[Out] " );
                        OcdOutWatch.start();
                       
                        OcdErrWatch.setDebug( debugMode );
                        System.out.println("[Sys] Connecting to openocd… ");
                        while( ocdSock == null ){
                                try{
                                        System.out.println("[Sys] Attempting to connect to OpenOCD…");
                                        ocdSock = new Socket("localhost", 6666);
                                }catch( Exception e ){
                                        System.out.println("[Sys] Could not connect to OpenOCD! (slow startup?) Retrying…");
                                        Thread.sleep(1000);
                                }
                        }
                        System.out.println("[Sys] Connected!");
                        out = new PrintWriter( ocdSock.getOutputStream(), true ); /* Autoflush */
                        in = new BufferedReader( new InputStreamReader(ocdSock.getInputStream()) );
                       
                        inWatch = new MsgWatcher( in, "[In ] " );
                        inWatch.start();
                        inWatch.setDebug( debugMode );
                       
                        if( writeSpeed > 0 ){
                                System.out.println("[Sys] Set JTAG reset speed to ‘" +writeSpeed+ "’");
                                out.println("jtag_speed "+writeSpeed);
                        }
                       
                        ocd_halt();
                       
                        if( terminalMode ){
                                boolean running = true;
                                BufferedReader terminalInput = new BufferedReader(new InputStreamReader(System.in));
                                System.out.println("——————–");
                                System.out.println("\n\n[Sys] Terminal Mode!");
                                System.out.println("——————–");
                                while( running ){
                                        System.out.print("\tOpenOCD:/$ ");
                                        String stringInput = terminalInput.readLine();
                                       
                                        //Exit command
                                        if( stringInput.equalsIgnoreCase("exit") ){
                                                running = false;
                                               
                                        //Reset command, managed internally
                                        }else if( stringInput.equalsIgnoreCase("reset") ){
                                                ocd_reset();
                                       
                                        //Resume command, managed internally
                                        }else if( stringInput.equalsIgnoreCase("resume") ){
                                                ocd_resume();
                                       
                                        // Do a normal write sequence…
                                        }else if( stringInput.equalsIgnoreCase("autowrite") ){
                                                System.out.println("[Sys] Performing a normal write sequence…");
                                                ocd_halt();
                                                ocd_flash_protect_remove( 0, 0, 10 );
                                                ocd_erase( 0, 0, 10 );
                                                ocd_write_image( flashFile );
                                                ocd_reset();
                                                ocd_resume();
                                                System.out.println("[Sys] Completed write sequence…");
                                       
                                        //Everything else – pass to openOCD
                                        }else{
                                                if( !stringInput.equals("") ){
                                                        out.println( stringInput );
                                                        waitFor( inWatch );
                                                        Thread.sleep(1000);
                                                }
                                        }
                                }
                                System.out.println("[Sys] SHUTDOWN");
                               
                                System.out.print("[Sys] Killing any other OpenOCD instances… ");
                                kill = r.exec("killall openocd");
                                kill.waitFor();
                                System.out.println("Done");
                               
                        }else{
                               
                                /* Default actions are to write the file specified… */
                                ocd_flash_protect_remove( 0, 0, 10 );
                                ocd_erase( 0, 0, 10 );
                                ocd_write_image( flashFile );
                                ocd_reset();
                                ocd_resume();
                               
                                System.out.print("[Sys] Killing any other OpenOCD instances… ");
                                kill = r.exec("killall openocd");
                                kill.waitFor();
                                System.out.println("Done");
                               
                        }
                       
                       
                       
                        System.exit(0);
                       
                }catch( Exception e ){
                        System.out.println("[EXC] Error!");
                        System.out.println( e );
                }
               
               
        }
       
       
       
        public static void ocd_halt() throws Exception{
                /* Halt the device so its safe to flash */
                System.out.println("[Sys] Halting device… ");
                out.println( "halt" );
                out.println( "poll" );
                waitFor( OcdErrWatch, "target state: halted" );
        }
       
        public static void ocd_flash_protect_remove( int bank, int startSector, int endSector ) throws Exception{
                /* Remove the flash protection */
                System.out.println("[Sys] Removing flash protection… ");
                out.println( "flash protect " +bank+ " " +startSector+ " " +endSector+ " off" );
                waitFor( OcdErrWatch, "cleared protection for sectors " +startSector+ " through " +endSector+ " on flash bank "+bank );
        }
       
        public static void ocd_erase( int bank, int startSector, int endSector ) throws Exception{
                /* Erase device… */
                System.out.println("[Sys] Erasing flash… ");
                out.println( "flash erase_sector " +bank+ " " +startSector+ " " +endSector );
                waitFor( OcdErrWatch, "erased sectors " +startSector+ " through " +endSector+ " on flash bank "+bank );
        }
       
        public static void ocd_write_image( String flashFile ) throws Exception{
                /* Write the new flash image */
                System.out.println("[Sys] Writing new flash image ‘" +flashFile+ "’… ");
               
                switch( writeMode ){
                        case 1:
                                System.out.println("[Sys] Writing in mid speed mode…");
                                out.println("load_image "+flashFile+ " 0");
                                break;
                        default:
                                System.out.println("[Sys] Writing in reliable mode…");
                                out.println( "flash write_image "+flashFile );
                               
                                OcdErrWatch.setDebug( false );
                                boolean programming = true;
                                while( programming == true ){
                                        /*Info:   Programming at 00000000, count 00023624 bytes remaining*/
                                        while(!OcdErrWatch.ready()){ Thread.sleep(200); }
                                        String line = OcdErrWatch.readLine();
                                        line = line.replaceAll( ",", "" );
                                        String[] parts = line.split(" ");
               
                                        if( parts[3].equals("Programming") ){
                                                int currentLoc = Integer.parseInt( parts[5], 16 );
                                                int remaining = Integer.parseInt( parts[7], 16 );
                                                int total = currentLoc + remaining;
                       
                                                //System.out.print("Currently at " +currentLoc+ " with " +remaining+ " left to go              \r" );
                                                progressBar( total, currentLoc );
                                        }
                                        if( parts[0].equals("wrote") )
                                                        programming = false;
                                }
       
                                OcdErrWatch.setDebug( debugMode );
                }
                System.out.println(""); /* Newline to escape anything in this section… */
        }
       
        public static void ocd_reset() throws Exception{
                /* Reset and run! */
                System.out.println("[Sys] RESET… ");
                out.println( "reset" );
                waitFor( inWatch );
        }
       
        public static void ocd_resume() throws Exception{
                System.out.println("[Sys] RESUME… ");
                out.println( "resume" );
                waitFor( inWatch );
        }
       
       
       
       

        public static void waitFor( MsgWatcher stream ) throws Exception{
                if( stream == null ){
                        throw new Exception("[EXC] The stream is not yet initialized!");
                }else{
                       
                        String read = new String("");
                        while( true ){
                                if( stream.ready() ){
                                        read = stream.readLine();
                                        System.out.println("[Sys] Done");
                                        return;
                                }
                        }
                       
                }
        }
       
        public static void waitFor( MsgWatcher stream, String expectedString) throws Exception{
                System.out.println("[Sys] Waiting for ack…");
                if( stream == null ){
                        throw new Exception("The IO stream isn’t set up yet!");
                }else{
                       
                        String read = new String("");
                       
                        while( true ){
                                if( stream.ready() ){
                                        read = stream.readLine();
                                }
                                if( read != "" && read != null ){
                                        if( read.endsWith(expectedString) || read.startsWith(expectedString) ){
                                                System.out.println("[Sys] Done!");
                                                return;
                                        }
                                        read = "";
                                }
                        }
                       
                }
        }
       
        public static void progressBar( int max, int value ){

                String output = "\r[";
                boolean mode = false;

                for( int i=0; i<40; i++ ){
                        if( ((int)(( (float)value/(float)max)*40)+1) > i ){
                                output += "*";
                        }else{
                                if( mode == false ){
                                        mode = true;
                                        output += "";
                                }
                                output += " ";
                        }
                }

                output += "] " + ((int)(( (float)value/(float)max)*100)+1) + "% ( " +value+ "/" +max+ " )";

                System.out.print( output );

        }
       
}

class MsgWatcher extends Thread{
       
        private BufferedReader stream = null;
        private LinkedBlockingQueue buffer = new LinkedBlockingQueue();
        private boolean locked = false;
        private String prefix = null;
        private boolean debug = true;
       
        public MsgWatcher( BufferedReader stream ){
                this.stream = stream;
                this.prefix = "<<< ";
        }
       
        public MsgWatcher( BufferedReader stream, String prefix ){
                this.stream = stream;
                this.prefix = prefix;
        }
       
        public void setDebug( boolean mode ){
                this.debug = mode;
        }

        public void run(){
               
                try{
                        System.out.println("[Sys] Msg Listener Running…");
                        while( true ){
                               
                                String read = stream.readLine();
                                if( read != "" && read != null ){
                                        if( this.debug == true ){ System.out.println(this.prefix+read); }
                                        while( this.locked == true ){}
                                        this.locked = true;
                                        buffer.put( read );
                                        this.locked = false;
                                }
                               
                        }
                }catch( Exception e ){
                        System.out.println( e );
                }
               
        }
       
        private void putLine( String line ){
                while( this.locked == true ){}
                this.locked = true;
                buffer.add( line );
                this.locked = false;
        }
       
        public boolean ready(){
                if( this.locked == true )
                        return false;
                if( buffer.size() > 0 )
                        return true;
                return false;
        }
       
        public String readLine() throws Exception{
                String temp = new String("");
               
                if( !this.ready() )
                        throw new Exception( "Attempted read on an unready buffer!" );
               
                while( this.locked == true ){}
                this.locked = true;
                temp = (String)this.buffer.remove();
                this.locked = false;
               
                return temp;
        }
       
}

This Post Has Been Viewed 203 Times