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

📄 xmodem.c

📁 Intel PXA270的bootloader程序,在linux环境下运行的.
💻 C
字号:
#include <stdio.h>#include <setup.h>#include <time.h>#include <command.h>#include <string.h>#include "types.h"#define SOH 0x01#define STX 0x02#define EOT 0x04#define ACK 0x06#define NAK 0x15#define CAN 0x18#define BS  0x08#define report(fmt, args...)		printf(fmt, ##args)#define assert(fmt, args...)		//printf(fmt, ##args)#define failed(fmt, args...)		//printf(fmt, ##args)static int xmodem_recv(void *addr, uint size);static void *recv_block(void *buff, int size);static bool ignore_data(int size);static uint16 xmodem_crc(void *addr, int len);extern int uart_getb(void);extern int uart_putb(int ch);static inline int xmodem_getb(int timeout){	int ch;	clock_t end;	end = clock() + CLOCKS_PER_SEC * timeout;	while (clock() < end){		ch = uart_getb();		if (ch >= 0) return ch;	}	return -1;}static inline int xmodem_putb(int ch){	return uart_putb(ch);}static void xmodem_usage(void){	usage_format("xmodem {loader/kernel/ramdisk/root}", "receive file with xmodem");	usage_format("xmodem address", "receive file with xmodem");	return;}static bool do_xmodem(int argc, char **argv){	int received;	ulong maxsize=0, tmp;	void *addr;	struct map *mp;	if (argc != 2) goto invalid;	mp = find_map(argv[1]);	if (mp){		addr = (void *)mp->dramb;		maxsize = mp->maxs;	} else if (strtoul(argv[1], &tmp, 16)){		addr = (void *)tmp;		maxsize = -1;	} else goto invalid;	received = xmodem_recv(addr, maxsize);	report("\r                                               \r");	report("\r                                               \r");	if (!received)		report(" xmodem : failed. not received.\n");	else if (received > maxsize)		report(" xmodem : failed. file size is too big.\n");	else if (received)		report(" xmodem : %d (0x%08X) bytes received.\n", received, received);	if (mp) mp->drams = received;	if (!received || received > maxsize)		return false;	return true;invalid :	xmodem_usage();	return false;}struct command_t cmd_xmodem = {	.name  = "xmodem",	.run   = do_xmodem,	.usage = xmodem_usage};static int xmodem_recv(void *addr, uint maxsize){	int ch;	int received;	int retry;	uchar buff[1024], *dest=addr, *s;	int blksize=0;	int blknum1, blknum2, lastblk;//	uint8 blknum1, blknum2, lastblk;	uint16 crc1, crc2, crcu, crcl;	received = 0;	lastblk = 0;	retry = 20;	while (retry > 0){ 		if (!received) xmodem_putb('C');		ch = xmodem_getb(1);		if (ch < 0){ retry--; continue; }		retry = 1;		if (ch == SOH){			blksize = 128;		} else if (ch == STX){			blksize = 1024;		} else if (ch == EOT){			xmodem_putb(ACK);			break;		} else return 0;		blknum1 = xmodem_getb(1);		if (blknum1 < 0) break;		blknum2 = xmodem_getb(1);		if (blknum2 < 0) break;		if (blknum1 != (uint8)~blknum2)			goto cancel;		if (blknum1 == (uint8)lastblk){			ignore_data(blksize + 2);			xmodem_putb(ACK);			continue;		}		if (blknum1 != (uint8)(lastblk + 1))			goto cancel;		lastblk++;		recv_block(buff, blksize);		if (maxsize - blksize < 0) goto cancel;		memcpy(dest, buff, blksize);		dest += blksize;		maxsize -= blksize;		received += blksize;		crc1 = xmodem_crc(buff, blksize);		crcu = xmodem_getb(1);		crcl = xmodem_getb(1);		crc2 = (crcu << 8) | crcl;		ch = (crc1 == crc2) ? ACK : NAK;		xmodem_putb(ch);	}	s = (uchar *)addr + received - 1;	/* remove pad (0x1A) */	while (*s == 0x1A) s--;	return s - (uchar *)addr + 1;cancel :	xmodem_putb(CAN);	while (xmodem_getb(1) >= 0);	return 0;}static bool ignore_data(int size){	int ch;	while (size--){		ch = xmodem_getb(1);		if (ch < 0) return false;	}	return true;}static void *recv_block(void *buff, int size){	int ch;	uchar *s = buff;	while (size-- > 0){		ch = xmodem_getb(1);		if (ch < 0) return 0;		*s++ = ch;	}	return buff;}static uint16 xmodem_crc(void *addr, int len){	int i;	uint16 crc;	uchar *s = addr;	crc = 0;	while (len-- > 0){		crc = crc ^ ((int)*s++ << 8);		for (i=0; i < 8; i++)			crc = (crc & 0x8000) ? crc << 1 ^ 0x1021 : crc << 1;	}	return crc;}

⌨️ 快捷键说明

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