Skip to content

Commit ab799b8

Browse files
author
Sebastien Bourdeauducq
committedMar 21, 2012
tools: new flterm
1 parent c26efa2 commit ab799b8

File tree

1 file changed

+66
-17
lines changed

1 file changed

+66
-17
lines changed
 

‎tools/flterm.c

+66-17
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@
3535
#include <getopt.h>
3636
#include <sfl.h>
3737

38+
#ifdef __linux__
39+
#include <linux/serial.h>
40+
#endif
41+
3842
#define DEFAULT_KERNELADR (0x40000000)
3943
#define DEFAULT_CMDLINEADR (0x41000000)
4044
#define DEFAULT_INITRDADR (0x41002000)
@@ -375,7 +379,7 @@ static void gdb_process_packet(int infd, int outfd, int altfd)
375379
}
376380

377381
static void do_terminal(char *serial_port,
378-
int doublerate, int gdb_passthrough,
382+
int baud, int gdb_passthrough,
379383
const char *kernel_image, unsigned int kernel_address,
380384
const char *cmdline, unsigned int cmdline_address,
381385
const char *initrd_image, unsigned int initrd_address,
@@ -390,6 +394,8 @@ static void do_terminal(char *serial_port,
390394
struct pollfd fds[3];
391395
int flags;
392396
int rsp_pending = 0;
397+
int c_cflag;
398+
int custom_divisor;
393399

394400
/* Open and configure the serial port */
395401
if(log_path != NULL) {
@@ -406,11 +412,41 @@ static void do_terminal(char *serial_port,
406412
return;
407413
}
408414

415+
custom_divisor = 0;
416+
switch(baud) {
417+
case 9600: c_cflag = B9600; break;
418+
case 19200: c_cflag = B19200; break;
419+
case 38400: c_cflag = B38400; break;
420+
case 57600: c_cflag = B57600; break;
421+
case 115200: c_cflag = B115200; break;
422+
case 230400: c_cflag = B230400; break;
423+
default:
424+
c_cflag = B38400;
425+
custom_divisor = 1;
426+
break;
427+
}
428+
429+
#ifdef __linux__
430+
if(custom_divisor) {
431+
struct serial_struct serial_info;
432+
ioctl(serialfd, TIOCGSERIAL, &serial_info);
433+
serial_info.custom_divisor = serial_info.baud_base / baud;
434+
serial_info.flags &= ~ASYNC_SPD_MASK;
435+
serial_info.flags |= ASYNC_SPD_CUST;
436+
ioctl(serialfd, TIOCSSERIAL, &serial_info);
437+
}
438+
#else
439+
if(custom_divisor) {
440+
fprintf(stderr, "[FLTERM] baudrate not supported\n");
441+
return;
442+
}
443+
#endif
444+
409445
/* Thanks to Julien Schmitt (GTKTerm) for figuring out the correct parameters
410446
* to put into that weird struct.
411447
*/
412448
tcgetattr(serialfd, &my_termios);
413-
my_termios.c_cflag = doublerate ? B230400 : B115200;
449+
my_termios.c_cflag = c_cflag;
414450
my_termios.c_cflag |= CS8;
415451
my_termios.c_cflag |= CREAD;
416452
my_termios.c_iflag = IGNPAR | IGNBRK;
@@ -535,7 +571,7 @@ static void do_terminal(char *serial_port,
535571
enum {
536572
OPTION_PORT,
537573
OPTION_GDB_PASSTHROUGH,
538-
OPTION_DOUBLERATE,
574+
OPTION_SPEED,
539575
OPTION_DEBUG,
540576
OPTION_KERNEL,
541577
OPTION_KERNELADR,
@@ -563,9 +599,9 @@ static const struct option options[] = {
563599
.val = OPTION_DEBUG
564600
},
565601
{
566-
.name = "double-rate",
567-
.has_arg = 0,
568-
.val = OPTION_DOUBLERATE
602+
.name = "speed",
603+
.has_arg = 1,
604+
.val = OPTION_SPEED
569605
},
570606
{
571607
.name = "kernel",
@@ -609,7 +645,7 @@ static const struct option options[] = {
609645

610646
static void print_usage()
611647
{
612-
fprintf(stderr, "Serial boot program for Milkymist SoC - v. 2.2\n");
648+
fprintf(stderr, "Serial boot program for Milkymist SoC - v. 2.3\n");
613649
fprintf(stderr, "Copyright (C) 2007, 2008, 2009, 2010, 2011 Sebastien Bourdeauducq\n");
614650
fprintf(stderr, "Copyright (C) 2011 Michael Walle\n");
615651
fprintf(stderr, "Copyright (C) 2004 MontaVista Software, Inc\n\n");
@@ -619,7 +655,7 @@ static void print_usage()
619655
fprintf(stderr, "the Free Software Foundation, version 3 of the License.\n\n");
620656

621657
fprintf(stderr, "Usage: flterm --port <port>\n");
622-
fprintf(stderr, " [--double-rate] [--gdb-passthrough] [--debug]\n");
658+
fprintf(stderr, " [--speed <speed>] [--gdb-passthrough] [--debug]\n");
623659
fprintf(stderr, " [--kernel <kernel_image> [--kernel-adr <address>]]\n");
624660
fprintf(stderr, " [--cmdline <cmdline> [--cmdline-adr <address>]]\n");
625661
fprintf(stderr, " [--initrd <initrd_image> [--initrd-adr <address>]]\n");
@@ -634,7 +670,7 @@ int main(int argc, char *argv[])
634670
{
635671
int opt;
636672
char *serial_port;
637-
int doublerate;
673+
int baud;
638674
int gdb_passthrough;
639675
char *kernel_image;
640676
unsigned int kernel_address;
@@ -648,7 +684,7 @@ int main(int argc, char *argv[])
648684

649685
/* Fetch command line arguments */
650686
serial_port = NULL;
651-
doublerate = 0;
687+
baud = 115200;
652688
gdb_passthrough = 0;
653689
kernel_image = NULL;
654690
kernel_address = DEFAULT_KERNELADR;
@@ -667,8 +703,12 @@ int main(int argc, char *argv[])
667703
free(serial_port);
668704
serial_port = strdup(optarg);
669705
break;
670-
case OPTION_DOUBLERATE:
671-
doublerate = 1;
706+
case OPTION_SPEED:
707+
baud = strtoul(optarg, &endptr, 0);
708+
if(*endptr != 0) {
709+
fprintf(stderr, "[FLTERM] Couldn't parse baudrate\n");
710+
return 1;
711+
}
672712
break;
673713
case OPTION_DEBUG:
674714
debug = 1;
@@ -682,23 +722,32 @@ int main(int argc, char *argv[])
682722
break;
683723
case OPTION_KERNELADR:
684724
kernel_address = strtoul(optarg, &endptr, 0);
685-
if(*endptr != 0) kernel_address = 0;
725+
if(*endptr != 0) {
726+
fprintf(stderr, "[FLTERM] Couldn't parse kernel address\n");
727+
return 1;
728+
}
686729
break;
687730
case OPTION_CMDLINE:
688731
free(cmdline);
689732
cmdline = strdup(optarg);
690733
break;
691734
case OPTION_CMDLINEADR:
692735
cmdline_address = strtoul(optarg, &endptr, 0);
693-
if(*endptr != 0) cmdline_address = 0;
736+
if(*endptr != 0) {
737+
fprintf(stderr, "[FLTERM] Couldn't parse cmdline address\n");
738+
return 1;
739+
}
694740
break;
695741
case OPTION_INITRD:
696742
free(initrd_image);
697743
initrd_image = strdup(optarg);
698744
break;
699745
case OPTION_INITRDADR:
700746
initrd_address = strtoul(optarg, &endptr, 0);
701-
if(*endptr != 0) initrd_address = 0;
747+
if(*endptr != 0) {
748+
fprintf(stderr, "[FLTERM] Couldn't parse initrd address\n");
749+
return 1;
750+
}
702751
break;
703752
case OPTION_LOG:
704753
free(log_path);
@@ -708,7 +757,7 @@ int main(int argc, char *argv[])
708757
}
709758

710759
if(serial_port == NULL) {
711-
print_usage();
760+
fprintf(stderr, "[FLTERM] No port given\n");
712761
return 1;
713762
}
714763

@@ -722,7 +771,7 @@ int main(int argc, char *argv[])
722771
tcsetattr(0, TCSANOW, &ntty);
723772

724773
/* Do the bulk of the work */
725-
do_terminal(serial_port, doublerate, gdb_passthrough,
774+
do_terminal(serial_port, baud, gdb_passthrough,
726775
kernel_image, kernel_address,
727776
cmdline, cmdline_address,
728777
initrd_image, initrd_address,

0 commit comments

Comments
 (0)
Please sign in to comment.