need a linux floppy
Eric W. Biederman
ebiederman at lnxi.com
Thu Dec 9 21:45:01 CET 2004
"Adam Talbot" <talbotx at comcast.net> writes:
> Hummm. Got both tomsrtbt and coyote Linux running. coyote Linux is very
> nice and I have other apps for it. But none of those had minicom on them.
> Any other ideas?
cat /dev/ttyS0
cat > /dev/ttyS0
Should just about do it.
Or for something a little more complete.
Eric
/* To compile run: gcc -g -O -Wall serial_echo.c -o serial_echo */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/poll.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define BUFFER_SIZE (1024)
#define BUFFER_RESERVE 8
speed_t get_baud(int wanted)
{
speed_t result = B0;
switch(wanted) {
case 50: result = B50; break;
case 75: result = B75; break;
case 110: result = B110; break;
case 134: result = B134; break;
case 150: result = B150; break;
case 200: result = B200; break;
case 300: result = B300; break;
case 600: result = B600; break;
case 1200: result = B1200; break;
case 1800: result = B1800; break;
case 2400: result = B2400; break;
case 4800: result = B4800; break;
case 9600: result = B9600; break;
case 19200: result = B19200; break;
case 38400: result = B38400; break;
case 57600: result = B57600; break;
case 115200: result = B115200; break;
case 230400: result = B230400; break;
case 460800: result = B460800; break;
case 500000: result = B500000; break;
case 576000: result = B576000; break;
case 921600: result = B921600; break;
case 1000000: result = B1000000; break;
case 1152000: result = B1152000; break;
case 1500000: result = B1500000; break;
case 2000000: result = B2000000; break;
case 2500000: result = B2500000; break;
case 3000000: result = B3000000; break;
case 3500000: result = B3500000; break;
case 4000000: result = B4000000; break;
}
return result;
}
#define ESC_CHAR '\x1e'
int do_inbuf_actions(char *in_buff, int len, int fd_serial,
char *input_file, int *fd_input_file)
{
static int in_esc = 0;
int i;
for(i = 0; i < len ;) {
if (!in_esc) {
if (in_buff[i] == ESC_CHAR) {
in_esc = 1;
memmove(in_buff, in_buff +1, len - i -1);
len--;
continue;
}
}
if (in_esc) {
if (in_buff[i] == ESC_CHAR) {
in_esc = 0;
i++;
continue;
}
else if (in_buff[i] == '\x3') {
exit(0);
}
else if (in_buff[i] == 'b') {
tcsendbreak(fd_serial, 0);
}
else if (in_buff[i] == 'f') {
int fd;
fd = open(input_file, O_RDONLY | O_NONBLOCK);
if (fd < 0) {
*fd_input_file = -1;
fprintf(stderr, "Cannot open %s %s\n",
input_file, strerror(errno));
}
else {
*fd_input_file = fd;
}
#if 0
do_transmit_file(fd_serial, input_file);
#endif
}
memmove(in_buff, in_buff +1, len -i -1);
len--;
in_esc = 0;
continue;
}
i++;
}
return len;
}
static struct termios initial_term_options;
void do_terminal_cleanup(void)
{
int result;
result = tcsetattr(STDOUT_FILENO, TCSANOW, &initial_term_options);
fprintf(stderr, "Exiting due to error %d -> %s\n",
errno, strerror(errno));
}
void usage(int argc, char **argv)
{
fprintf(stderr, "Usage: %s [[[[[device] speed] none|hard|soft] ro|rw]\n",
argv[0]);
exit(1);
}
int main(int argc, char *argv[])
{
int fd_serial;
char serial_port[] = "/dev/ttyS0";
char *port;
speed_t speed;
struct pollfd fds_wait[3], fds_data_wait[3], *fds;
int result;
char out_buff[BUFFER_SIZE], in_buff[BUFFER_SIZE];
int out_buff_fill, in_buff_fill;
struct termios serial_options, term_options;
char *input_file;
int fd_input_file;
int hard_flow_control;
int soft_flow_control;
int read_only;
port = serial_port;
speed = B115200;
input_file = 0;
hard_flow_control = 0;
soft_flow_control = 0;
read_only = 1;
fd_input_file = -1;
if (argc >= 2) {
port = argv[1];
}
if (argc >= 3) {
speed = get_baud(atoi(argv[2]));
}
if (argc >= 4) {
if (strcmp(argv[3], "none") == 0) {
hard_flow_control = 0;
soft_flow_control = 0;
}
else if (strcmp(argv[3], "hard") == 0) {
hard_flow_control = 1;
}
else if (strcmp(argv[3], "soft") == 0) {
soft_flow_control = 1;
}
else {
usage(argc, argv);
}
}
if (argc >= 5) {
if (strcmp(argv[4], "ro") == 0) {
read_only = 1;
}
else if (strcmp(argv[4], "rw") == 0) {
read_only = 0;
}
else {
usage(argc, argv);
}
}
if (argc >= 6) {
input_file = argv[5];
}
fd_serial = open(port, O_RDWR | O_NONBLOCK);
if (fd_serial < 0) {
fprintf(stderr, "Can't open %s\n", port);
exit(1);
}
result = tcgetattr(STDOUT_FILENO, &initial_term_options);
if (result < 0) {
fprintf(stderr, "result < 0 errno = %d -> %s\n",
errno, strerror(errno));
exit(1);
}
atexit(do_terminal_cleanup);
term_options = initial_term_options;
term_options.c_iflag &= (ISTRIP | IGNBRK );
term_options.c_cflag &= ~(CSIZE | PARENB | IXON | IXOFF | IXANY);
term_options.c_cflag |= (CS8 |CREAD) |
((soft_flow_control)?(IXON|IXOFF|IXANY): 0);
term_options.c_lflag &= 0;
term_options.c_cc[VMIN] = 1;
term_options.c_cc[VTIME] = 0;
result = tcsetattr(STDOUT_FILENO, TCSANOW, &term_options);
if (result < 0) {
fprintf(stderr, "result < 0 errno = %d -> %s\n",
errno, strerror(errno));
exit(1);
}
result = tcsetattr(STDIN_FILENO, TCSANOW, &term_options);
if (result < 0) {
fprintf(stderr, "result < 0 errno = %d -> %s\n",
errno, strerror(errno));
exit(1);
}
result = tcgetattr(fd_serial, &serial_options);
if (result < 0) {
fprintf(stderr, "result < 0 errno = %d -> %s\n",
errno, strerror(errno));
exit(1);
}
serial_options.c_iflag = 0;
serial_options.c_oflag = 0;
serial_options.c_cflag = CS8 | CREAD | ((hard_flow_control)?CRTSCTS:0);
serial_options.c_lflag = 0;
cfsetispeed(&serial_options, speed);
cfsetospeed(&serial_options, speed);
result = tcsetattr(fd_serial, TCSANOW, &serial_options);
if (result < 0) {
fprintf(stderr, "result < 0 errno = %d -> %s\n",
errno, strerror(errno));
exit(1);
}
fds_wait[0].fd = fd_serial;
fds_wait[0].events = POLLIN;
fds_wait[0].revents = 0;
fds_wait[1].fd = STDIN_FILENO;
fds_wait[1].events = POLLIN;
fds_wait[1].revents = 0;
fds_wait[2].fd = -1;
fds_wait[2].events = 0;
fds_wait[2].revents = 0;
fds_data_wait[0].fd = fd_serial;
fds_data_wait[0].events = POLLIN | POLLOUT;
fds_data_wait[0].revents = 0;
fds_data_wait[1].fd = STDIN_FILENO;
fds_data_wait[1].events = POLLIN;
fds_data_wait[1].revents = 0;
fds_data_wait[2].fd = STDOUT_FILENO;
fds_data_wait[2].events = POLLOUT;
fds_data_wait[2].revents = 0;
out_buff_fill = 0;
in_buff_fill = 0;
fds = fds_wait;
for (;;) {
result = poll(fds, 3, -1);
if (result < 0) {
break;
}
if ((fds[0].revents & POLLIN) && (sizeof(out_buff) > out_buff_fill)){
result = read(fd_serial, out_buff + out_buff_fill,
sizeof(out_buff) - out_buff_fill);
if (result > 0) {
out_buff_fill += result;
}
}
if ((fds[1].revents & POLLIN) && (sizeof(in_buff) > in_buff_fill)) {
result = read(STDIN_FILENO, in_buff + in_buff_fill,
sizeof(in_buff) - in_buff_fill);
if (result > 0) {
int bytes;
bytes = do_inbuf_actions(in_buff + in_buff_fill, result, fd_serial, input_file, &fd_input_file);
if (read_only)
bytes = 0;
in_buff_fill += bytes;
}
}
if ((fd_input_file >= 0)
&& ((sizeof(in_buff) - BUFFER_RESERVE) > in_buff_fill)) {
result = read(fd_input_file, in_buff + in_buff_fill,
(sizeof(in_buff) - BUFFER_RESERVE) - in_buff_fill);
if (result > 0) {
in_buff_fill += result;
}
else if (result == 0) {
close(fd_input_file);
fd_input_file = -1;
}
}
if ((fds[2].revents & POLLOUT) && out_buff_fill) {
result = write(STDOUT_FILENO, out_buff, out_buff_fill);
if (result > 0) {
out_buff_fill -= result;
if (out_buff_fill) {
memmove(out_buff, out_buff + result, out_buff_fill);
}
}
}
if ((fds[0].revents & POLLOUT) && in_buff_fill) {
result = write(fd_serial, in_buff, in_buff_fill);
if (result > 0) {
in_buff_fill -= result;
if (in_buff_fill) {
memmove(in_buff, in_buff + result, in_buff_fill);
}
}
}
fds = (in_buff_fill || out_buff_fill || (fd_input_file >= 0))?
fds_data_wait : fds_wait;
}
return 0;
}
More information about the coreboot
mailing list