tools: new flterm

This commit is contained in:
Sebastien Bourdeauducq 2012-03-21 09:11:43 +01:00
parent c26efa28ca
commit ab799b874f

View file

@ -35,6 +35,10 @@
#include <getopt.h> #include <getopt.h>
#include <sfl.h> #include <sfl.h>
#ifdef __linux__
#include <linux/serial.h>
#endif
#define DEFAULT_KERNELADR (0x40000000) #define DEFAULT_KERNELADR (0x40000000)
#define DEFAULT_CMDLINEADR (0x41000000) #define DEFAULT_CMDLINEADR (0x41000000)
#define DEFAULT_INITRDADR (0x41002000) #define DEFAULT_INITRDADR (0x41002000)
@ -375,7 +379,7 @@ static void gdb_process_packet(int infd, int outfd, int altfd)
} }
static void do_terminal(char *serial_port, static void do_terminal(char *serial_port,
int doublerate, int gdb_passthrough, int baud, int gdb_passthrough,
const char *kernel_image, unsigned int kernel_address, const char *kernel_image, unsigned int kernel_address,
const char *cmdline, unsigned int cmdline_address, const char *cmdline, unsigned int cmdline_address,
const char *initrd_image, unsigned int initrd_address, const char *initrd_image, unsigned int initrd_address,
@ -390,6 +394,8 @@ static void do_terminal(char *serial_port,
struct pollfd fds[3]; struct pollfd fds[3];
int flags; int flags;
int rsp_pending = 0; int rsp_pending = 0;
int c_cflag;
int custom_divisor;
/* Open and configure the serial port */ /* Open and configure the serial port */
if(log_path != NULL) { if(log_path != NULL) {
@ -406,11 +412,41 @@ static void do_terminal(char *serial_port,
return; return;
} }
custom_divisor = 0;
switch(baud) {
case 9600: c_cflag = B9600; break;
case 19200: c_cflag = B19200; break;
case 38400: c_cflag = B38400; break;
case 57600: c_cflag = B57600; break;
case 115200: c_cflag = B115200; break;
case 230400: c_cflag = B230400; break;
default:
c_cflag = B38400;
custom_divisor = 1;
break;
}
#ifdef __linux__
if(custom_divisor) {
struct serial_struct serial_info;
ioctl(serialfd, TIOCGSERIAL, &serial_info);
serial_info.custom_divisor = serial_info.baud_base / baud;
serial_info.flags &= ~ASYNC_SPD_MASK;
serial_info.flags |= ASYNC_SPD_CUST;
ioctl(serialfd, TIOCSSERIAL, &serial_info);
}
#else
if(custom_divisor) {
fprintf(stderr, "[FLTERM] baudrate not supported\n");
return;
}
#endif
/* Thanks to Julien Schmitt (GTKTerm) for figuring out the correct parameters /* Thanks to Julien Schmitt (GTKTerm) for figuring out the correct parameters
* to put into that weird struct. * to put into that weird struct.
*/ */
tcgetattr(serialfd, &my_termios); tcgetattr(serialfd, &my_termios);
my_termios.c_cflag = doublerate ? B230400 : B115200; my_termios.c_cflag = c_cflag;
my_termios.c_cflag |= CS8; my_termios.c_cflag |= CS8;
my_termios.c_cflag |= CREAD; my_termios.c_cflag |= CREAD;
my_termios.c_iflag = IGNPAR | IGNBRK; my_termios.c_iflag = IGNPAR | IGNBRK;
@ -535,7 +571,7 @@ static void do_terminal(char *serial_port,
enum { enum {
OPTION_PORT, OPTION_PORT,
OPTION_GDB_PASSTHROUGH, OPTION_GDB_PASSTHROUGH,
OPTION_DOUBLERATE, OPTION_SPEED,
OPTION_DEBUG, OPTION_DEBUG,
OPTION_KERNEL, OPTION_KERNEL,
OPTION_KERNELADR, OPTION_KERNELADR,
@ -563,9 +599,9 @@ static const struct option options[] = {
.val = OPTION_DEBUG .val = OPTION_DEBUG
}, },
{ {
.name = "double-rate", .name = "speed",
.has_arg = 0, .has_arg = 1,
.val = OPTION_DOUBLERATE .val = OPTION_SPEED
}, },
{ {
.name = "kernel", .name = "kernel",
@ -609,7 +645,7 @@ static const struct option options[] = {
static void print_usage() static void print_usage()
{ {
fprintf(stderr, "Serial boot program for Milkymist SoC - v. 2.2\n"); fprintf(stderr, "Serial boot program for Milkymist SoC - v. 2.3\n");
fprintf(stderr, "Copyright (C) 2007, 2008, 2009, 2010, 2011 Sebastien Bourdeauducq\n"); fprintf(stderr, "Copyright (C) 2007, 2008, 2009, 2010, 2011 Sebastien Bourdeauducq\n");
fprintf(stderr, "Copyright (C) 2011 Michael Walle\n"); fprintf(stderr, "Copyright (C) 2011 Michael Walle\n");
fprintf(stderr, "Copyright (C) 2004 MontaVista Software, Inc\n\n"); fprintf(stderr, "Copyright (C) 2004 MontaVista Software, Inc\n\n");
@ -619,7 +655,7 @@ static void print_usage()
fprintf(stderr, "the Free Software Foundation, version 3 of the License.\n\n"); fprintf(stderr, "the Free Software Foundation, version 3 of the License.\n\n");
fprintf(stderr, "Usage: flterm --port <port>\n"); fprintf(stderr, "Usage: flterm --port <port>\n");
fprintf(stderr, " [--double-rate] [--gdb-passthrough] [--debug]\n"); fprintf(stderr, " [--speed <speed>] [--gdb-passthrough] [--debug]\n");
fprintf(stderr, " [--kernel <kernel_image> [--kernel-adr <address>]]\n"); fprintf(stderr, " [--kernel <kernel_image> [--kernel-adr <address>]]\n");
fprintf(stderr, " [--cmdline <cmdline> [--cmdline-adr <address>]]\n"); fprintf(stderr, " [--cmdline <cmdline> [--cmdline-adr <address>]]\n");
fprintf(stderr, " [--initrd <initrd_image> [--initrd-adr <address>]]\n"); fprintf(stderr, " [--initrd <initrd_image> [--initrd-adr <address>]]\n");
@ -634,7 +670,7 @@ int main(int argc, char *argv[])
{ {
int opt; int opt;
char *serial_port; char *serial_port;
int doublerate; int baud;
int gdb_passthrough; int gdb_passthrough;
char *kernel_image; char *kernel_image;
unsigned int kernel_address; unsigned int kernel_address;
@ -648,7 +684,7 @@ int main(int argc, char *argv[])
/* Fetch command line arguments */ /* Fetch command line arguments */
serial_port = NULL; serial_port = NULL;
doublerate = 0; baud = 115200;
gdb_passthrough = 0; gdb_passthrough = 0;
kernel_image = NULL; kernel_image = NULL;
kernel_address = DEFAULT_KERNELADR; kernel_address = DEFAULT_KERNELADR;
@ -667,8 +703,12 @@ int main(int argc, char *argv[])
free(serial_port); free(serial_port);
serial_port = strdup(optarg); serial_port = strdup(optarg);
break; break;
case OPTION_DOUBLERATE: case OPTION_SPEED:
doublerate = 1; baud = strtoul(optarg, &endptr, 0);
if(*endptr != 0) {
fprintf(stderr, "[FLTERM] Couldn't parse baudrate\n");
return 1;
}
break; break;
case OPTION_DEBUG: case OPTION_DEBUG:
debug = 1; debug = 1;
@ -682,7 +722,10 @@ int main(int argc, char *argv[])
break; break;
case OPTION_KERNELADR: case OPTION_KERNELADR:
kernel_address = strtoul(optarg, &endptr, 0); kernel_address = strtoul(optarg, &endptr, 0);
if(*endptr != 0) kernel_address = 0; if(*endptr != 0) {
fprintf(stderr, "[FLTERM] Couldn't parse kernel address\n");
return 1;
}
break; break;
case OPTION_CMDLINE: case OPTION_CMDLINE:
free(cmdline); free(cmdline);
@ -690,7 +733,10 @@ int main(int argc, char *argv[])
break; break;
case OPTION_CMDLINEADR: case OPTION_CMDLINEADR:
cmdline_address = strtoul(optarg, &endptr, 0); cmdline_address = strtoul(optarg, &endptr, 0);
if(*endptr != 0) cmdline_address = 0; if(*endptr != 0) {
fprintf(stderr, "[FLTERM] Couldn't parse cmdline address\n");
return 1;
}
break; break;
case OPTION_INITRD: case OPTION_INITRD:
free(initrd_image); free(initrd_image);
@ -698,7 +744,10 @@ int main(int argc, char *argv[])
break; break;
case OPTION_INITRDADR: case OPTION_INITRDADR:
initrd_address = strtoul(optarg, &endptr, 0); initrd_address = strtoul(optarg, &endptr, 0);
if(*endptr != 0) initrd_address = 0; if(*endptr != 0) {
fprintf(stderr, "[FLTERM] Couldn't parse initrd address\n");
return 1;
}
break; break;
case OPTION_LOG: case OPTION_LOG:
free(log_path); free(log_path);
@ -708,7 +757,7 @@ int main(int argc, char *argv[])
} }
if(serial_port == NULL) { if(serial_port == NULL) {
print_usage(); fprintf(stderr, "[FLTERM] No port given\n");
return 1; return 1;
} }
@ -722,7 +771,7 @@ int main(int argc, char *argv[])
tcsetattr(0, TCSANOW, &ntty); tcsetattr(0, TCSANOW, &ntty);
/* Do the bulk of the work */ /* Do the bulk of the work */
do_terminal(serial_port, doublerate, gdb_passthrough, do_terminal(serial_port, baud, gdb_passthrough,
kernel_image, kernel_address, kernel_image, kernel_address,
cmdline, cmdline_address, cmdline, cmdline_address,
initrd_image, initrd_address, initrd_image, initrd_address,