// Загрузчик usbloader.bin через аварийный порт для модемов на платформе Balong V7R2. // // #include #include #include //#include //#include #include #include #include #ifndef WIN32 #include #include #include #else #include #include "wingetopt.h" #include "printf.h" #endif #ifndef WIN32 int siofd; struct termios sioparm; #else static HANDLE hSerial; #endif FILE* ldr; //************************************************* //* HEX-дамп области памяти * //************************************************* void dump(unsigned char buffer[],int len) { int i,j; unsigned char ch; printf("\n"); for (i=0;i 0x7e)&&(ch<0xc0))) putchar('.'); else putchar(ch); } // заполнение пробелами для неполных строк else printf(" "); } printf("*\n"); } } //************************************************* //* Рассчет контрольной суммы командного пакета //************************************************* void csum(unsigned char* buf, int len) { unsigned int i,c,csum=0; unsigned int cconst[]={0,0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF}; for (i=0;i<(len-2);i++) { c=(buf[i]&0xff); csum=((csum<<4)&0xffff)^cconst[(c>>4)^(csum>>12)]; csum=((csum<<4)&0xffff)^cconst[(c&0xf)^(csum>>12)]; } buf[len-2]=(csum>>8)&0xff; buf[len-1]=csum&0xff; } //************************************************* //* Отсылка командного пакета модему //************************************************* int sendcmd(unsigned char* cmdbuf, int len) { unsigned char replybuf[1024]; unsigned int replylen; #ifndef WIN32 csum(cmdbuf,len); write(siofd,cmdbuf,len); // отсылка команды tcdrain(siofd); replylen=read(siofd,replybuf,1024); #else DWORD bytes_written = 0; DWORD t; csum(cmdbuf, len); WriteFile(hSerial, cmdbuf, len, &bytes_written, NULL); FlushFileBuffers(hSerial); t = GetTickCount(); do { ReadFile(hSerial, replybuf, 1024, (LPDWORD)&replylen, NULL); } while (replylen == 0 && GetTickCount() - t < 1000); #endif if (replylen == 0) return 0; if (replybuf[0] == 0xaa) return 1; return 0; } //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void main(int argc, char* argv[]) { #ifndef WIN32 struct termios sioparm; #else char device[20] = "\\\\.\\COM"; DCB dcbSerialParams = {0}; COMMTIMEOUTS CommTimeouts; DWORD bytes_written, bytes_read; #endif //char* lptr; unsigned int i,res,opt,datasize,pktcount,adr; int nblk; // число блоков для загрузки int bl; // текущий блок unsigned char c; unsigned char cmdhead[14]={0xfe,0, 0xff}; unsigned char cmddata[1040]={0xda,0,0}; unsigned char cmdeod[5]={0xed,0,0,0,0}; struct { int lmode; // режим загрузки: 1 - прямой старт, 2 - через перезапуск A-core int size; // размер блока int adr; // адрес загрузки блока в память int offset; // смещение до блока от начала файла } blk[10]; #ifndef WIN32 unsigned char devname[50]="/dev/ttyUSB0"; #else char devname[50]=""; #endif while ((opt = getopt(argc, argv, "hp:sa:")) != -1) { switch (opt) { case 'h': printf("\n Утилита предназначена для аварийной USB-загрузки модемов E3372S\n\n\ %s [ключи] <имя файла для загрузки>\n\n\ Допустимы следующие ключи:\n\n\ -p - последовательный порт для общения с загрузчиком (по умолчанию /dev/ttyUSB0\n\ \n",argv[0]); return; case 'p': strcpy(devname,optarg); break; } } if (optind>=argc) { printf("\n - Не указано имя файла для загрузки\n"); return; } #ifdef WIN32 if (*devname == '\0') { printf("\n - Последовательный порт не задан\n"); return; } #endif #ifndef WIN32 // Настройка SIO siofd = open(devname, O_RDWR | O_NOCTTY |O_SYNC); if (siofd == -1) { printf("\n - Последовательный порт %s не открывается\n", argv[1]); return; } bzero(&sioparm, sizeof(sioparm)); sioparm.c_cflag = B115200 | CS8 | CLOCAL | CREAD; sioparm.c_iflag = 0; // INPCK; sioparm.c_oflag = 0; sioparm.c_lflag = 0; sioparm.c_cc[VTIME]=1; // таймаут sioparm.c_cc[VMIN]=1; // 1 байт минимального ответа tcsetattr(siofd, TCSANOW, &sioparm); tcflush(siofd,TCIOFLUSH); // очистка выходного буфера #else strcat(device, /*(char*)*/devname); hSerial = CreateFileA(device, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (hSerial == INVALID_HANDLE_VALUE) { printf("\n - Последовательный порт COM%s не открывается\n", devname); return; } ZeroMemory(&dcbSerialParams, sizeof(dcbSerialParams)); dcbSerialParams.DCBlength=sizeof(dcbSerialParams); dcbSerialParams.BaudRate = CBR_115200; dcbSerialParams.ByteSize = 8; dcbSerialParams.StopBits = ONESTOPBIT; dcbSerialParams.Parity = NOPARITY; dcbSerialParams.fBinary = TRUE; dcbSerialParams.fDtrControl = DTR_CONTROL_ENABLE; dcbSerialParams.fRtsControl = RTS_CONTROL_ENABLE; if (!SetCommState(hSerial, &dcbSerialParams)) { printf("\n - Ошибка при инициализации COM-порта\n", devname); CloseHandle(hSerial); return; } CommTimeouts.ReadIntervalTimeout = MAXDWORD; CommTimeouts.ReadTotalTimeoutConstant = 0; CommTimeouts.ReadTotalTimeoutMultiplier = 0; CommTimeouts.WriteTotalTimeoutConstant = 0; CommTimeouts.WriteTotalTimeoutMultiplier = 0; if (!SetCommTimeouts(hSerial, &CommTimeouts)) { printf("\n - Ошибка при инициализации COM-порта\n", devname); CloseHandle(hSerial); return; } #endif ldr=fopen(argv[optind],"rb"); if (ldr == 0) { printf("\n Ошибка открытия %s",argv[optind]); return; } // Прверяем сигнатуру usloader fread(&i,1,4,ldr); if (i != 0x20000) { printf("\n Файл %s не является загрузчиком usbloader\n",argv[optind]); return; } fseek(ldr,36,SEEK_SET); // начало описателей блоков для загрузки // Разбираем заголовок for(nblk=0;nblk<10;nblk++) { fread(&blk[nblk].lmode,1,4,ldr); fread(&blk[nblk].size,1,4,ldr); fread(&blk[nblk].adr,1,4,ldr); fread(&blk[nblk].offset,1,4,ldr); if (blk[nblk].lmode == 0) break; } printf("\n Найдено %i блоков для загрузки",nblk); // Проверяем загрузочный порт c=0; #ifndef WIN32 write(siofd,"A",1); res=read(siofd,&c,1); #else WriteFile(hSerial, "A", 1, &bytes_written, NULL); FlushFileBuffers(hSerial); Sleep(100); ReadFile(hSerial, &c, 1, &bytes_read, NULL); #endif if (c != 0x55) { printf("\n ! Порт не находится в режиме USB Boot\n"); return; } // главный цикл загрузки - загружаем все блоки, найденные в заголовке for(bl=0;bl=blk[bl].size) datasize=blk[bl].size-adr; #ifndef WIN32 fprintf(stderr,"\r Адрес: %08x, пакет# %i размер: %i",blk[bl].adr+adr,pktcount,datasize); #else printf("\r Адрес: %08x, пакет# %i размер: %i",blk[bl].adr+adr,pktcount,datasize); #endif // читаем порцию данных if (datasize != fread(cmddata+3,1,datasize,ldr)) { printf("\n Неожиданный конец файла\n"); return; } // готовим пакет данных cmddata[1]=pktcount; cmddata[2]=(~pktcount)&0xff; pktcount++; if (!sendcmd(cmddata,datasize+5)) { printf("\nМодем отверг пакет данных\nОбраз пакета:"); dump(cmddata,datasize+5); return; } } // Фрмируем пакет конца данных cmdeod[1]=pktcount; cmdeod[2]=(~pktcount)&0xff; if (!sendcmd(cmdeod,5)) { printf("\nМодем отверг пакет конца данных\nОбраз пакета:"); dump(cmdeod,5); } } printf("\n Загрузка окончена\n"); }