thanks! :) On Thu, Jul 7, 2011 at 7:52 AM, Maxim Cournoyer <[email protected]> wrote: > Le mercredi 06 juillet 2011 à 18:50 -0700, Rodrigo Rosa a écrit : > > On Mon, Jul 4, 2011 at 4:13 PM, Maxim Cournoyer > <[email protected]> wrote: >> On Jul 2, 2011 6:15 PM +0200, Øyvind Harboe wrote: >> >> Use the Source Luke. The end of the command is not linefeed but 0x??. >> There >> ought to be updated docs. Patch? >> >> Great tip! I found it inside the tcl_server.c file; the end of character >> used by the openocd tcl server is 0x1a. >> I managed to get the result I was looking for, a simple application which >> usage goes like: >> >> program </path/to/romfile.bin> >> >> The objective was to automate the ROM flashing procedure from Eclipse IDE >> when working with the LM3S8962 kit. The app can be configured as an >> "external tool" and launched at the touch of a button. It could also be >> called inside a custom makefile. The use of the tcl_server is a great >> feature to me, because an openocd daemon is already running most of the >> time, to provide debugging facility. >> >> I have made a C version and a BASH (w/ netcat) version of such a small >> app. >> I also toyed with tcl to make a telnet-like utility to test openocd's tcl >> server. >> >> I also gathered a LM3S8962.cfg file on the internet and refactored it in >> to >> a similar way to what could be seen inside the /usr/share/openocd/scripts >> folder. I can post all that stuff if anyone is interested. >> > > i'm working on something similar. > would you mind posting your stuff? > thanks! > > Hello Rodrigo! I'm happy to share the small tools I made with you and the > openocd community. > The following scripts/program are tailored for flashing an LM3S8962 target > (except the tcl one), although they should be quite simple to adapt to do > anything. > > Here's a general telnet like utility written in tcl, for quick testing > (tclnet.tcl): > > #!/usr/bin/tclsh > # Simple tcl client to test OpenOCD tcl_server > # > # Based on a script written by Charles Hardin > # > <http://lists.berlios.de/pipermail/openocd-development/2008-July/002368.html> > # > # Author: Maxim Cournoyer, 2011 > > # OpenOCD server settings > set server localhost > set port 6666 > set EOC \x1a > set BUFSIZE 256 > > puts "Use empty line to exit." > > # Open TCP socket > set fo [socket $server $port] > # The following tells the 'read' command to return on EOC. > fconfigure $fo -eofchar $EOC > > puts -nonewline stdout "> " > flush stdout > > while { [gets stdin line] > 0 } { > puts -nonewline "Sending \"$line\" ... " > puts -nonewline $fo "$line$EOC" > flush $fo > > # Server reply reception > set line {} > > if { [catch {set line [read $fo $BUFSIZE]}] } { > close $fo > puts "\nConnection or server error." > exit 1 > } > > # Server returns empty string (only EOC received) if OK. Longer output is > # returned in case of wrong command name or if the user specified the > command name > # with the capture parameter, e.g.: capture { halt } > if { [string equal $line {}] } { > puts "OK." > } else { > puts "\nServer: $line" > } > > puts -nonewline stdout "> " > flush stdout > } > > # We need to reconfigure the channel to normal before closing, > # else we'd get a TCP RST fault. > fconfigure $fo -eofchar \n > close $fo > exit 0 > > Next is a bash written tool to flash the binary ROM onto my LM3S8962 board > (flashROM.sh): > > #!/bin/bash > # > # Simple script that allows flashing ROM onto LM3S8962 target > # by sending commands to the tcl_server of OpenOCD > # > # Author: Maxim Cournoyer, 2011 > > server=localhost > port=6666 > > #------------------------------------------------------------------------------- > # Function definitions > #------------------------------------------------------------------------------- > > # USAGE: send_commands "cmd1 \"cmd2 with spaces\" cmd3" > # Useful to send multiple commands with a single tcp connection. > # Tip : also works for single commands! > send_commands () > { > local argc=$(echo $1 | sed 's/[^,]//g' | wc -m) > local cmds_string="$(echo $1 | sed 's/,/\\x1a/g')\x1a" > local received=$(echo -e $cmds_string | nc $server $port) > local received_symbols=$(( $(echo $received | wc -m) -1 )) > # Error checking: only good for command names. Wrong args to commands > # (e.g. the path to a .bin file) will not be detected here. > if [ $received_symbols == $argc ]; then > echo "Success!" > else > echo "Failed. Check commands synthax." > exit 1 > fi > } > > # USAGE: get_extension "filepath" "extension_length" > # Credits: KenJackson's post at > http://www.linuxforums.org/forum/programming-scripting/67818-get-last-three-characters-string.html > get_extension() > { > local length=$(echo $1 | wc -c) > local offset=$(( $lenght - $2 )) > local extension="${1:$offset}" > echo $extension > } > > #------------------------------------------------------------------------------- > # Main section > #------------------------------------------------------------------------------- > # Argument parsing + file path formatting for relative path support > if [ "$1" ]; then > if [ ! ${1##/*} ]; then > ROM_path="$1" > else > ROM_path="$(pwd)/$1" > fi > else > echo "USAGE: flashROM <absolute ROM file path>" > exit 1 > fi > > # Make sure the file exists > if [ ! -f "$ROM_path" ]; then > echo "Error: the file specified does not exist." > exit 1 > fi > > # Verify that ROM suffix is valid > ROM_suffix="$(get_extension "$ROM_path" 4)" > if [ "$ROM_suffix" != ".bin" ] && [ "$ROM_suffix" != ".hex" ]; then > echo "Error: the file extension is not not valid." > exit 1 > fi > > # Flash ROM routine for LM3S8962 > command1=halt > command2="flash write_image erase \"$ROM_path\"" > command3=reset > send_commands "$command1,$command2,$command3" > > #done > exit 0 > > The next listing is the same program, flashROM.c, is yet another version of > the same program in C: > > /* Simple ROM flash utility for the EK-LM3S8962 board development kit > * for use with OpenOCD. > * > * Based on simple echoserver program written by David Mertz, see > * http://gnosis.cx/publish/programming/sockets.html > * > * Maxim Cournoyer, 2011 > */ > > #include <stdio.h> > #include <stdlib.h> > #include <string.h> > #include <unistd.h> > #include <sys/socket.h> > #include <netinet/in.h> > #include <arpa/inet.h> > #include <netdb.h> > > #define BUFFSIZE 128 > void Die(const char *mess) > { > perror(mess); > exit(1); > } > > > int main(int argc, const char *argv[]) > { > /* server parameters */ > const char server_ip[] = "127.0.0.1"; > const int server_port = 6666; > /* Supported ROM suffixes */ > const char *suffix1 = "bin"; > const char *suffix2 = "hex"; > /* Base of each command */ > char word1[] = "halt"; > const char word2[] = "flash write_image erase "; > const char word3[] = "reset"; > const char EOC[] = "\x1a"; /* End Of Command delimiter */ > > char command1[strlen(word1)+strlen(EOC)+1]; > char *command2; /* will be malloc further */ > char command3[strlen(word3)+strlen(EOC)+1]; > > const char *ROM_path_tmp; > char *ROM_path; > char *path_buf; > if ((path_buf = getcwd(NULL, 0)) == NULL) /* automatic malloc */ > { > Die("Failed to allocate memory."); > } > int i = strlen(path_buf); > > /* Process arguments */ > if (argc != 2) > { > fprintf(stderr, "USAGE: flashrom <rom_absolute_path>\n"); > exit(1); > } > > ROM_path_tmp = argv[1]; > > /* File path formatting for relative path support */ > if (ROM_path_tmp[0] == '/') > { > ROM_path = (char *) ROM_path_tmp; > } > else > { > /* Relative path */ > ROM_path = (char *) malloc(i + strlen(ROM_path_tmp) + 2); /* +1 for '/', +1 > for '\0' = 2 */ > if (ROM_path == NULL) > { > Die("Failed to allocate memory."); > } > strcpy(ROM_path, path_buf); > strcat(ROM_path, "/"); > strcat(ROM_path, ROM_path_tmp); > } > free(path_buf); > > /* Make sure the ROM_path points to an existing file */ > if( access(ROM_path, F_OK) == -1 ) { > Die("Invalid ROM file path specified"); > } > > /* Make sure the last 3 chars of the file are "bin" */ > char ROM_suffix[4]; > int ROM_path_len = strlen(ROM_path); > int tmp = 0; > for (int a = ROM_path_len - 3; a < ROM_path_len; a++) > { > ROM_suffix[tmp] = ROM_path[a]; > tmp++; > } > ROM_suffix[tmp]='\0'; > if ( strcmp(ROM_suffix,suffix1) && strcmp(ROM_suffix,suffix2) ) > { > printf("File suffix is not \"%s\" or \"%s\"! Aborting.\n", suffix1, > suffix2); > exit(1); > } > > int sock; > struct sockaddr_in openocd_server; > char buffer[BUFFSIZE]; /* Size of the buffer for received data */ > > /* Commands definition */ > strcpy(command1, word1); > > /* Allocate dynamic memory for absolute rom's path */ > command2 = (char*) malloc(strlen(word2) + strlen(ROM_path) + strlen(EOC) + > 3); /* Two double quote + '\0' = 3 */ > if ( command2 == NULL ) > { > Die("Failed to allocate memory."); > } > strcpy(command2, word2); > strcat(command2,"\""); > strcat(command2, ROM_path); > strcat(command2,"\""); > if ( ROM_path != ROM_path_tmp ) > { > free(ROM_path); > } > > strcpy(command3, word3); > > /* Command sequence : commands will be sent in this order */ > char *command_sequence[] = { command1, command2, command3 }; > > /* Create the TCP socket */ > if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) > { > Die("Failed to create socket"); > } > > /* Construct the server sockaddr_in structure */ > memset(&openocd_server, 0, sizeof(openocd_server)); /* Clear struct */ > openocd_server.sin_family = AF_INET; /* Internet/IP */ > openocd_server.sin_addr.s_addr = inet_addr(server_ip); /* IP address */ > openocd_server.sin_port = htons(server_port); /* server port */ > > /* Establish connection */ > if (connect(sock, (struct sockaddr *) &openocd_server, > sizeof(openocd_server)) < 0) > { > Die("Failed to connect with server"); > } > > /* Loop for sending the commands */ > for (int j = 0; j < 3; j++) > { > /* Send the word to the server */ > printf("Sending %s... ", command_sequence[j]); > /* Now we add the EOC char */ > strcat(command_sequence[j], EOC); > int msg_len = strlen(command_sequence[j]); > if (send(sock, command_sequence[j], msg_len, 0) != msg_len) > { > Die("Mismatch in number of sent bytes"); > } > > /* Receive the word back from the server */ > int bytes = 0; > if ((bytes = recv(sock, buffer, BUFFSIZE - 1, 0)) < 1) > { > Die("Failed to receive bytes from server"); > } > buffer[bytes] = '\0'; /* Assure null terminated string */ > if (bytes == 1 && (strcmp(buffer, EOC) == 0)) > { > printf("OK.\n"); > } > else > { > printf("FAIL\n"); > } > } > > /* Cleanup and close socket */ > free(command2); > close(sock); > exit(0); > } > > Now for the OpenOCD configuration scripts (for EK-LM3S8962 dev board). The > base of it was found on the Internet and reformatted to respect the > presentation of other OpenOCD scripts. > This one would go in the "target" folder of openocd's scripts dir: > > # file: lm3s8962.cfg > # Script for TI/Luminary Stellaris LM3S8962 > > if { [info exists CHIPNAME] } { > set _CHIPNAME $CHIPNAME > } else { > set _CHIPNAME lm3s8962 > } > > if { [info exists CPUTAPID ] } { > set _CPUTAPID $CPUTAPID > } else { > set _CPUTAPID 0x3ba00477 > } > > #jtag scan chain > jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 1 -irmask 0xf -expected-id > $_CPUTAPID > > #gdb debug target > set _TARGETNAME $_CHIPNAME.cpu > target create $_TARGETNAME cortex_m3 -chain-position $_CHIPNAME.cpu -variant > lm3s > > #set a work area of 16kb starting at address 20000000 (sram start) > $_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size 0x4000 > > set _FLASHNAME $_CHIPNAME.flash > flash bank $_FLASHNAME stellaris 0 0 0 0 $_TARGETNAME > > The next one would go in the "board" folder: > > # file: eki-lm3s8962.cfg > # TI/Luminary Stellaris LM3S8962 Evaluation Kits > # > http://www.luminarymicro.com/products/eki-lm3s8962_can_ethernet_evaluation_kit.html > > # include the FT2232 interface config for on-board JTAG interface > source [find interface/luminary.cfg] > > # include the target config > source [find target/lm3s8962.cfg] > > # jtag speed > jtag_khz 500 > > jtag_nsrst_delay 100 > > #LM3S8962 Evaluation Board has only srst > reset_config srst_only > > Then the OpenOCD daemon could be launched with a simple "openocd -f > board/ek-lm3s8962.cfg" > That's a lot of info, hopefully you'll find something useful in it! I've > attached a gunzipped tarball of these files for convenience. > > Have a nice day!
-- Rodrigo. _______________________________________________ Openocd-development mailing list [email protected] https://lists.berlios.de/mailman/listinfo/openocd-development
