⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rx.c

📁 rx program which using uart1 in dm355 platform
💻 C
字号:
/*------------------------------------------------------------------------- * Filename:      xmodem.c * Version:       $Id: rx.c,v 1.2 2004/03/15 08:28:46 andersen Exp $ * Copyright:     Copyright (C) 2001, Hewlett-Packard Company * Author:        Christopher Hoover <ch@hpl.hp.com> * Description:   xmodem functionality for uploading of kernels *                and the like * Created at:    Thu Dec 20 01:58:08 PST 2001 *-----------------------------------------------------------------------*//* * xmodem.c: xmodem functionality for uploading of kernels and *            the like * * Copyright (C) 2001 Hewlett-Packard Laboratories * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * * * This was originally written for blob and then adapted for busybox. * */#include <stdlib.h>#include <stdarg.h>#include <stdio.h>#include <unistd.h>#include <errno.h>#include <termios.h>#include <signal.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <string.h>//#include "busybox.h"#define SOH 0x01#define STX 0x02#define EOT 0x04#define ACK 0x06#define NAK 0x15#define CAN 0x18#define BS  0x08/*Cf:  http://www.textfiles.com/apple/xmodem  http://www.phys.washington.edu/~belonis/xmodem/docxmodem.txt  http://www.phys.washington.edu/~belonis/xmodem/docymodem.txt  http://www.phys.washington.edu/~belonis/xmodem/modmprot.col*/#define TIMEOUT 1#define TIMEOUT_LONG 10#define MAXERRORS 10static inline void write_byte(int fd, char cc) {	write(fd, &cc, 1);}static inline void write_flush(int fd) {	tcdrain(fd);}static inline void read_flush(int fd) {	tcflush(fd, TCIFLUSH);}static int read_byte(int fd, unsigned int timeout) {	char buf[1];	int n;	alarm(timeout);	n = read(fd, &buf, 1);	alarm(0);	if (n == 1)		return buf[0] & 0xff;	else		return -1;}static int receive(char *error_buf, size_t error_buf_size,				   int ttyfd, int filefd){	char blockBuf[1024];	unsigned int errors = 0;	unsigned int wantBlockNo = 1;	unsigned int length = 0;	int docrc = 1;	char nak = 'C';	unsigned int timeout = TIMEOUT_LONG;#define note_error(fmt,args...) \	snprintf(error_buf, error_buf_size, fmt,##args)	read_flush(ttyfd);	/* Ask for CRC; if we get errors, we will go with checksum */	write_byte(ttyfd, nak);	write_flush(ttyfd);	for (;;) {		int blockBegin;		int blockNo, blockNoOnesCompl;		int blockLength;		int cksum = 0;		int crcHi = 0;		int crcLo = 0;		blockBegin = read_byte(ttyfd, timeout);		if (blockBegin < 0)			goto timeout;		timeout = TIMEOUT;		nak = NAK;		switch (blockBegin) {		case SOH:		case STX:			break;		case EOT:			write_byte(ttyfd, ACK);			write_flush(ttyfd);			goto done;		default:			goto error;		}		/* block no */		blockNo = read_byte(ttyfd, TIMEOUT);		if (blockNo < 0)			goto timeout;		/* block no one's compliment */		blockNoOnesCompl = read_byte(ttyfd, TIMEOUT);		if (blockNoOnesCompl < 0)			goto timeout;		if (blockNo != (255 - blockNoOnesCompl)) {			note_error("bad block ones compl");			goto error;		}		blockLength = (blockBegin == SOH) ? 128 : 1024;		{			int i;			for (i = 0; i < blockLength; i++) {				int cc = read_byte(ttyfd, TIMEOUT);				if (cc < 0)					goto timeout;				blockBuf[i] = cc;			}		}		if (docrc) {			crcHi = read_byte(ttyfd, TIMEOUT);			if (crcHi < 0)				goto timeout;			crcLo = read_byte(ttyfd, TIMEOUT);			if (crcLo < 0)				goto timeout;		} else {			cksum = read_byte(ttyfd, TIMEOUT);			if (cksum < 0)				goto timeout;		}		if (blockNo == ((wantBlockNo - 1) & 0xff)) {			/* a repeat of the last block is ok, just ignore it. */			/* this also ignores the initial block 0 which is */			/* meta data. */			goto next;		} else if (blockNo != (wantBlockNo & 0xff)) {			note_error("unexpected block no, 0x%08x, expecting 0x%08x", blockNo, wantBlockNo);			goto error;		}		if (docrc) {			int crc = 0;			int i, j;			int expectedCrcHi;			int expectedCrcLo;			for (i = 0; i < blockLength; i++) {				crc = crc ^ (int) blockBuf[i] << 8;				for (j = 0; j < 8; j++)					if (crc & 0x8000)						crc = crc << 1 ^ 0x1021;					else						crc = crc << 1;			}			expectedCrcHi = (crc >> 8) & 0xff;			expectedCrcLo = crc & 0xff;			if ((crcHi != expectedCrcHi) ||			    (crcLo != expectedCrcLo)) {				note_error("crc error, expected 0x%02x 0x%02x, got 0x%02x 0x%02x", expectedCrcHi, expectedCrcLo, crcHi, crcLo);				goto error;			}		} else {			unsigned char expectedCksum = 0;			int i;			for (i = 0; i < blockLength; i++)				expectedCksum += blockBuf[i];			if (cksum != expectedCksum) {				note_error("checksum error, expected 0x%02x, got 0x%02x", expectedCksum, cksum);				goto error;			}		}		wantBlockNo++;		length += blockLength;		if (full_write(filefd, blockBuf, blockLength) < 0) {			note_error("write to file failed: %m");			goto fatal;		}	next:		errors = 0;		write_byte(ttyfd, ACK);		write_flush(ttyfd);		continue;	error:	timeout:		errors++;		if (errors == MAXERRORS) {			/* Abort */			int i;			// if using crc, try again w/o crc			if (nak == 'C') {				nak = NAK;				errors = 0;				docrc = 0;				goto timeout;			}			note_error("too many errors; giving up");		fatal:			for (i = 0; i < 5; i ++)				write_byte(ttyfd, CAN);			for (i = 0; i < 5; i ++)				write_byte(ttyfd, BS);			write_flush(ttyfd);			return -1;		}		read_flush(ttyfd);		write_byte(ttyfd, nak);		write_flush(ttyfd);	} done:	return length;#undef note_error}static void sigalrm_handler(int signum){}int main(int argc, char **argv){	char *fn;	int ttyfd, filefd;	struct termios tty, orig_tty;	struct sigaction act;	int n;	char error_buf[256];	if (argc != 2) {			printf("Usage : rx File\n");            exit(1);    }	fn = argv[1];	ttyfd = open("/dev/ttyS1", O_RDWR);	if (ttyfd < 0) {			printf("rx : open on /dev/ttyS1 failed\n");            exit(1);    }	filefd = open(fn, O_RDWR|O_CREAT|O_TRUNC, 0666);	if (filefd < 0) {			printf("rx : open on %s failed\n", fn);            exit(1);    }	if (tcgetattr(ttyfd, &tty) < 0) {			printf ("rx : tcgetattr failed\n");            exit(1);    }	orig_tty = tty;	cfmakeraw(&tty);	tcsetattr(ttyfd, TCSAFLUSH, &tty);	memset(&act, 0, sizeof(act));	act.sa_handler = sigalrm_handler;	sigaction(SIGALRM, &act, 0);	n = receive(error_buf, sizeof(error_buf), ttyfd, filefd);	close(filefd);	tcsetattr(ttyfd, TCSAFLUSH, &orig_tty);	if (n < 0) {			printf("\n%s : receive failed\n",argv[0]);            exit(1);    }	//bb_fflush_stdout_and_exit(EXIT_SUCCESS);}/*Local Variables:c-file-style: "linux"c-basic-offset: 4tab-width: 4End:*//** Write all of the supplied buffer out to a file.* This does multiple writes as necessary.* Returns the amount written, or -1 on an error.*/ssize_t full_write(int fd, const void *buf, size_t len){        ssize_t cc;        ssize_t total;        total = 0;        while (len > 0) {            cc = safe_write(fd, buf, len);            if (cc < 0)                return cc;      /* write() returns -1 on failure. */            total += cc;            buf = ((const char *)buf) + cc;            len -= cc;        }        return total;}ssize_t safe_write(int fd, const void *buf, size_t count){    ssize_t n;    do {        n = write(fd, buf, count);    } while (n < 0 && errno == EINTR);    return n;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -