diff options
author | Chris Larson <clarson@kergoth.com> | 2004-11-09 00:36:47 +0000 |
---|---|---|
committer | Chris Larson <clarson@kergoth.com> | 2004-11-09 00:36:47 +0000 |
commit | f96441b9faf769c9ecdd4d338b605ea3d0cc4010 (patch) | |
tree | edb17ec2c4ea13c5acb1c7350957a249a820e28d /simpad-utilities | |
parent | b6588aa6851fb220cedc387d21c51513ef8d67f4 (diff) |
Disable bk EOLN_NATIVE conversions on all files in packages FILESPATHs, to prevent it screwing up patches.
BKrev: 4190111fA4MuVozAqwE7xOSL9fr-TA
Diffstat (limited to 'simpad-utilities')
-rw-r--r-- | simpad-utilities/genboot/arnold_boot.h | 28 | ||||
-rw-r--r-- | simpad-utilities/genboot/gen_boot.c | 99 | ||||
-rw-r--r-- | simpad-utilities/serload/main.cpp | 136 | ||||
-rw-r--r-- | simpad-utilities/serload/serialdownload.cpp | 408 | ||||
-rw-r--r-- | simpad-utilities/serload/serialdownload.h | 158 | ||||
-rw-r--r-- | simpad-utilities/serload/serload.1 | 38 |
6 files changed, 867 insertions, 0 deletions
diff --git a/simpad-utilities/genboot/arnold_boot.h b/simpad-utilities/genboot/arnold_boot.h index e69de29bb2..7c8399ac2e 100644 --- a/simpad-utilities/genboot/arnold_boot.h +++ b/simpad-utilities/genboot/arnold_boot.h @@ -0,0 +1,28 @@ + +#define ARNOLDMAGIC "ARNOLDBOOTBLOCK" +#define MAXSEG 32 +#define WRITE_SMART_MAGIC 3141 /* write tftp data to smart */ +#define BOOT_SMART_MAGIC 9876 /* Start an Smartmedia */ +#define REBOOT_MAGIC 9123 /* restart old image ? */ +#define EXTRA_BOOT 0xdead /* Load named image */ + +struct segment { void *base; long len; }; /* len MUST be Multiple of 512 */ + +struct arnold_bootheader { + char magic[16]; + long exec_adr; + long nosegs; + struct segment lseg[MAXSEG]; + long stack_p; + short debuggit; + short writesmart; + unsigned short extrafile; + char otherfile[20]; + + char reserved[1]; /* reserved for future use */ +}; +union bootblock { + char buffer[512]; + struct arnold_bootheader boot; +}; + diff --git a/simpad-utilities/genboot/gen_boot.c b/simpad-utilities/genboot/gen_boot.c index e69de29bb2..1444f60d0b 100644 --- a/simpad-utilities/genboot/gen_boot.c +++ b/simpad-utilities/genboot/gen_boot.c @@ -0,0 +1,99 @@ +#include "arnold_boot.h" +#include <stdio.h> +volatile void +error (char *msg) +{ + fprintf (stderr, "Fatal Error:%s\n", msg); + exit (2); +} +#ifdef LITTLE_END +#define order(x) ((x&0xff)<<24 | (x&0xff00) << 8 | (x&0xff0000) >>8 | (x&0xff000000)>>24) +#define swap(x) ((x&0xff)<<8 | (x&0xff00)>>8) +#else +#define order(x) (x) +#define swap(x) (x) +#endif + +main (int argc, char *argv[]) +{ + union bootblock block0; + char *ep; + int nseg; + + memset ((void *) &block0, 0, sizeof (block0)); + strcpy (block0.boot.magic, ARNOLDMAGIC); + if (argc < 3) + error ("Bad Number of args:\n" + " Usage: gen_boot [-d[n]][-w][-r][-x filename] exec_adr nseg base1 len1 [base len]"); + + if (strncmp (argv[1], "-d",2) == 0) + { + /* Set debugging to value (default 1) */ + if ( argv[1][2] == 0 ) { + block0.boot.debuggit = swap(1); + }else{ + block0.boot.debuggit = swap(argv[1][2] - '0'); + } + argv++; + argc--; + } + if (strcmp (argv[1], "-w") == 0) + { + block0.boot.writesmart = swap(WRITE_SMART_MAGIC); + argv++; + argc--; + } + if (strcmp (argv[1], "-r") == 0) + { + block0.boot.writesmart = swap(REBOOT_MAGIC); /* Try to reboot ram image */ + argv++; + argc--; + } + if (strcmp (argv[1], "-x") == 0) + { + block0.boot.extrafile=swap(EXTRA_BOOT); + strncpy (block0.boot.otherfile,argv[2],sizeof(block0.boot.otherfile)); + + argv+=2; + argc-=2; + } + block0.boot.exec_adr = order (strtoul (argv[1], &ep, 0)); + if (ep != 0 && *ep != 0) + { + error ("Exec_addr ?"); + } + argv++; + argc--; + nseg = strtoul (argv[1], &ep, 0); + block0.boot.nosegs = order (nseg); + if (ep != 0 && *ep != 0) + { + error ("Number of Segments ?"); + } + argv++; + argc--; + argv++; + argc--; /* Start from index 0 */ + if (argc != (nseg * 2)) + { + error ("Wrong number of arguments"); + } + for (nseg = 0; (nseg * 2) < argc; nseg++) + { + block0.boot.lseg[nseg].base = (void *) order (strtoul (argv[nseg * 2], &ep, 0)); + if (ep != 0 && *ep != 0) + { + error ("Base addr of Segment ?"); + } + block0.boot.lseg[nseg].len = order (strtoul (argv[nseg * 2 + 1], &ep, 0)); + if (ep != 0 && *ep != 0) + { + error ("Length of Segment ?"); + } + } + fwrite((void *) &block0, sizeof(block0), 1, stdout); + fflush(stdout); +// write (1, block0, sizeof (block0)); + + exit (0); +} diff --git a/simpad-utilities/serload/main.cpp b/simpad-utilities/serload/main.cpp index e69de29bb2..b65d71753c 100644 --- a/simpad-utilities/serload/main.cpp +++ b/simpad-utilities/serload/main.cpp @@ -0,0 +1,136 @@ +//============================================================================= +// Project: SIMpad +//============================================================================= +// FILE-NAME: main.cpp +// FUNCTION: Serial download of a new image from PC to SIMpad +// +// AUTHOR: Juergen Messerer, Peter Voser +// CREAT.-DATE: 01.04.2001 (dd.mm.yy) +// +// NOTES: - +// +//============================================================================= + +#include <unistd.h> +#include <iostream> +#include <string.h> +#include "serialdownload.h" +using namespace std; + +const int STRING_LENGTH = 128; + +//============================================================================= +//============================================================================= +void printHelp(void) +{ + cout << "serload V1.0 for Linux " << endl; + cout << "Downloading a new image to the SIMpad " + << "using the serial interface." << endl << endl; + cout << "Invocation: serload [IMAGEFILE] [ttyS-PORT]" << endl; + cout << "IMAGEFILE: the file with the new image prepared for the" + << " SIMpad Bootloader." + << endl; + cout << "ttyS-PORT: number of the ttyS-Port for the download." + << endl; + cout << "Note: ttyS0 = COM1, ttyS1 = COM2, ..." << endl << endl; +} + +//============================================================================= +//============================================================================= +int main(int argc, char *argv[]) +{ + int i; + for(i = 0; i < argc; ++i) + { + if(strcmp(argv[i], "--help") == 0) + { + // The user asks for help. + printHelp(); + exit(0); + } + } + + if(argc != 3 && argc != 2) + { + cerr << endl << "Usage: serload [IMAGEFILE] [ttyS-PORT]" << endl; + cerr << "See also \"serload --help\"!" << endl << endl; + exit(1); + } + + char device[STRING_LENGTH]; + if(argc == 3) + { + strcpy(device, "/dev/ttyS"); + strcat(device, argv[2]); + } + else + { + // If no serial port is given, use ttyS0 as default. + strcpy(device, "/dev/ttyS0"); + } + + SerialDownload serload; + int myError, imagesize; + static char *image; + + int success = serload.openSerialPort(device, myError); + if(success != 0) + { + cerr << "Error: cannot open " << device << ". Aborting." + << endl << endl; + exit(2); + } + + myError = serload.loadFile(argv[1], image, imagesize); + if(myError != 0) + { + cerr << "Error: cannot load file " + << argv[1] << "! Aborting." << endl << endl; + exit(3); + } + + cout << "Please press RESET at the back of the SIMpad!" << endl; + int reply = serload.connectToSimpad(115200, myError); + + if(reply != 0) + { + cerr << "Error: cannot connect to SIMpad! Aborting." + << endl << endl; + exit(4); + } + + // Determine number of blocks to send without remaining bytes! + int progress = 0; + int size = imagesize; + int totalBlocks = size / 512; + int numberOfBlocksToSend = totalBlocks; + int numberOfBlocksSent = 0; + + // Send blocks. + while(numberOfBlocksToSend) + { + serload.sendBlock(image, 512, myError); + image += 512; + --numberOfBlocksToSend; + // Update progress info every 100th block. + if(!(numberOfBlocksSent % 100)) + { + progress = 100 * numberOfBlocksSent / totalBlocks; + } + ++numberOfBlocksSent; + } + + // Determine, if there are remaining bytes. + int numberOfRemainingBytes = size % 512; + if(numberOfRemainingBytes) + { + serload.sendBlock(image, numberOfRemainingBytes, myError); + } + + // The bootloader burns the new image. + serload.waitForEndOfBurning(); + + cout << "Update successfully finished! Swich the SIMpad on." << endl; + + return 0; +} diff --git a/simpad-utilities/serload/serialdownload.cpp b/simpad-utilities/serload/serialdownload.cpp index e69de29bb2..c58de2280f 100644 --- a/simpad-utilities/serload/serialdownload.cpp +++ b/simpad-utilities/serload/serialdownload.cpp @@ -0,0 +1,408 @@ +//============================================================================= +// Project: SIMpad +//============================================================================= +// FILE-NAME: serialdownload.cpp +// FUNCTION: Serial download of a new image from PC to SIMpad +// +// AUTHOR: Juergen Messerer, Peter Voser +// CREAT.-DATE: 01.04.2001 (dd.mm.yy) +// +// NOTES: - +// +//============================================================================= + +#include <iostream> +#include "serialdownload.h" +using namespace std; + +//============================================================================= +//============================================================================= +SerialDownload::SerialDownload() +{ +} + +//============================================================================= +//============================================================================= +SerialDownload::~SerialDownload() +{ +} + +//============================================================================= +//============================================================================= +int SerialDownload::openSerialPort(const char* portDev, int& errorNumber) +{ + _serialPort = open(portDev, O_RDWR | O_NONBLOCK); + + if (_serialPort == -1) + { + errorNumber = errno; + return -1; + } + + // Read old serial port setup + termios serialPortSetup; + int success = tcgetattr(_serialPort, &serialPortSetup ); + if (success < 0) + { + errorNumber = errno; + perror(0); + return -1; + } + + serialPortSetup.c_iflag = 0L; + serialPortSetup.c_oflag = 0L; + + // Control mode flags + serialPortSetup.c_cflag &= ~(CSTOPB|PARENB|CRTSCTS); + serialPortSetup.c_cflag |= (CS8|CLOCAL); + + // Local mode flags + serialPortSetup.c_lflag = 0L; + + // control characters + serialPortSetup.c_cc[VTIME] = 0; + serialPortSetup.c_cc[VMIN] = 0; + + // Set baud rate = 38.4kBaud + cfsetispeed(&serialPortSetup, B38400); + cfsetospeed(&serialPortSetup, B38400); + + success=tcsetattr(_serialPort, TCSANOW, &serialPortSetup); + if(success < 0) + { + errorNumber = errno; + perror(0); + return -1; + } + + return 0; +} + +//============================================================================= +//============================================================================= +int SerialDownload::loadFile(const char *fileName, + char *&buffer, + int &numberOfBytes) +{ + FILE *path; + + if((path = fopen(fileName,"rb")) == 0) + { + // Specified file not found. + return -1; + } + + fseek(path, 0, 2); + numberOfBytes = ftell(path); + rewind(path); + + buffer = (char*)malloc((size_t)numberOfBytes); + if(buffer == 0) + { + // Insufficient memory to load file. + fclose(path); + return -2; + } + + if(fread(buffer, numberOfBytes, 1, path) != 1) + { + // Cannot read file. + fclose(path); + return -3; + } + + fclose(path); + return 0; +} + +//============================================================================= +//============================================================================= +bool SerialDownload::changeBaudRate(const int newBaudRate, + int& errorNumber) +{ + int success; + int baudRate; + struct termios setup; + + switch(newBaudRate) + { + case 9600: + baudRate = B9600; + break; + case 19200: + baudRate = B19200; + break; + case 38400: + baudRate = B38400; + break; + case 57600: + baudRate = B57600; + break; + case 115200: + baudRate = B115200; + break; + case 230400: + baudRate = B230400; + break; + case 460800: + baudRate = B460800; + break; + default: + return 0; + break; + } + + success = tcgetattr(_serialPort, &setup); + if (success < 0) + { + errorNumber = errno; + perror(0); + return 0; + } + + cfsetispeed(&setup, baudRate); + cfsetospeed(&setup, baudRate); + success = tcsetattr(_serialPort, TCSANOW, &setup); + if (success < 0) + { + errorNumber = errno; + perror(0); + return 0; + } + + return 1; +} + +//============================================================================= +//============================================================================= +unsigned char SerialDownload::waitForReply(const int transparent) +{ + unsigned char c(0); + int numberBytes(0); + int reply(0); + + struct pollfd commEvent; + commEvent.fd = _serialPort; + commEvent.events = POLLIN; + + for(;;) + { + // Wait until a character has received. + do + { + reply = poll(&commEvent, 1, 1000); + } + while(reply == 0); + + if(commEvent.revents == POLLIN) + { + do + { + numberBytes=read(_serialPort, &c, 1); + if(transparent && numberBytes) + { + cout << c; + cout.flush(); + } + if((c == STX) || + (c == ETX) || + (c == BEL) || + (c == ACK_OK) || + (c == ACK_NOK)) + { + return c; + } + } + while(numberBytes); + } + } + return 0; +} + +//============================================================================= +//============================================================================= +int SerialDownload::connectToSimpad(const int fastBaudRate, + int& errorNumber) +{ + errorNumber = 0; + int bytesWritten; + unsigned char c; + + // Switch baud rate to low connecting baud rate. + if(!changeBaudRate(38400, errorNumber)) + { + return -1; + } + + // Wait for character STX (02) and BEL (07) + while(waitForReply(1) != STX); + while(waitForReply(1) != BEL); + bytesWritten = write(_serialPort, &ACK_BD, 1); + if(!bytesWritten) + { + errorNumber = errno; + return -2; + } + + // Send byte #2 of baud rate + c = (fastBaudRate>>16)&0xff; + bytesWritten = write(_serialPort, &c, 1); + if(!bytesWritten) + { + errorNumber = errno; + return -2; + } + + // Send byte #1 of baud rate + c = (fastBaudRate>>8)&0xff; + bytesWritten = write(_serialPort, &c, 1); + if(!bytesWritten) + { + errorNumber = errno; + return -2; + } + + // Send byte #0 of baud rate + c = fastBaudRate&0xff; + bytesWritten = write(_serialPort, &c, 1); + if(!bytesWritten) + { + errorNumber = errno; + return -2; + } + + c = waitForReply(1); + if (c == ACK_OK) + { + // Switch baud rate to fast baud rate. + if(!changeBaudRate(fastBaudRate, errorNumber)) + { + return -3; + } + } + + // Wait for 1st character with new baud rate. + while(waitForReply(1) != STX); + + bytesWritten = write(_serialPort, &STX, 1); + if(!bytesWritten) + { + errorNumber = errno; + return -4; + } + + while(waitForReply(1) != STX); + return 0; +} + +//============================================================================= +//============================================================================= +bool SerialDownload::sendBlock(const char *buffer, + const int length, + int& errorNumber) +{ + errorNumber = 0; + unsigned char c, check=0xff; + int i; + int bytesWritten; + + while(1) + { + if(length == 512) + { + // It's a complete block. + bytesWritten = write(_serialPort, buffer, 512); + if(!bytesWritten) + { + errorNumber = errno; + return 0; + } + // Create checksum. + for(i = 0; i < 512; ++i) + { + check=(check<<1) ^ buffer[i]; + } + } + else + { + // It's an incomplete block, which must be filled with + // the FILLER pattern. + char lastBlock[512]; + for(i = 0; i < 512; ++i) + { + if(i < length) + { + // Create checksum. + check=(check<<1) ^ buffer[i]; + lastBlock[i] = buffer[i]; + } + else + { + // Create checksum + check=(check<<1) ^ FILLER; + lastBlock[i] = FILLER; + } + } + bytesWritten = write(_serialPort, lastBlock, 512); + if(!bytesWritten) + { + errorNumber = errno; + return 0; + } + } + + while(waitForReply(1) != STX); + + if(length == 512) + { + bytesWritten = write(_serialPort, &STX, 1); + if(!bytesWritten) + { + errorNumber = errno; + return 0; + } + } + else + { + // It was the last block. + bytesWritten = write(_serialPort, &ETX, 1); + if(!bytesWritten) + { + errorNumber = errno; + return 0; + } + } + + // Send checksum. + bytesWritten = write(_serialPort, &check, 1); + if(!bytesWritten) + { + errorNumber = errno; + return 0; + } + + // Wait for ACK_OK as confirmation. Send block again otherwise. + c = waitForReply(1); + if(c == ACK_OK) + { + // The block was successfully sent. + return 1; + } + } +} + +//============================================================================= +//============================================================================= +void SerialDownload::waitForEndOfBurning(void) +{ + // Wait for ETX, which indicates the end of burning. + while(waitForReply(1) != ETX); + + // Send the characters "r" (erase registry) and "o" (power off). + char c = 'r'; + int bytesWritten; + bytesWritten = write(_serialPort, &c, 1); + c = 'o'; + bytesWritten = write(_serialPort, &c, 1); + usleep(7000); +} diff --git a/simpad-utilities/serload/serialdownload.h b/simpad-utilities/serload/serialdownload.h index e69de29bb2..1dd05892b1 100644 --- a/simpad-utilities/serload/serialdownload.h +++ b/simpad-utilities/serload/serialdownload.h @@ -0,0 +1,158 @@ +//============================================================================= +// Project: SIMpad +//============================================================================= +// FILE-NAME: serialdownload.hpp +// FUNCTION: Serial download interface. +// +// AUTHOR: Juergen Messerer, Peter Voser +// CREAT.-DATE: 01.04.2001 (dd.mm.yy) +// +// NOTES: - +// +//============================================================================= + +#ifndef __SERIAL_DOWNLOAD +#define __SERIAL_DOWNLOAD + +#include <errno.h> +#include <fcntl.h> +#include <poll.h> +#include <stdio.h> +#include <stdlib.h> +#include <termios.h> +#include <unistd.h> + +const unsigned char STX = 2; +const unsigned char ETX = 3; +const unsigned char BEL = 7; +const unsigned char ACK_BD = 11; +const unsigned char ACK_OK = 6; +const unsigned char ACK_NOK = 15; +const unsigned char FILLER = 0xff; + +class SerialDownload +{ +public: + SerialDownload(); + ~SerialDownload(); +//============================================================================= +// PURPOSE: Opening a serial port. +// +// PARAMETERS: +// portDev: (IN) port device to open. +// errorNumber: (OUT) error number determined with +// GetLastError(). +// RETURN VALUE: +// serialPort: Filedescriptor of opened serial port. +// If the function fails, it returns -1. +// +// COMMENTS: - +//============================================================================= + int openSerialPort(const char* portDev, int &errorNumber); + +//============================================================================= +// PURPOSE: Loading file with a image +// +// PARAMETERS: +// fileName: (IN) name of file to open +// buffer: (OUT) pointer to loaded image file. +// numberOfBytes: (OUT) size of file. +// +// RETURN VALUE: +// 0: success +// -1: specified file not found +// -2: not enough memory to load file +// -3: cannot read file +// +// COMMENTS: - +//============================================================================= + int loadFile(const char *fileName, char *&buffer, int &numberOfBytes); + +//============================================================================= +// PURPOSE: Connecting to the SIMpad. +// +// PARAMETERS: +// fastBaudRate: (IN) value of fast baud rate. +// errorNumber: (OUT) error number errno +// +// RETURN VALUE: +// 0: success +// -1: switching to connection baud rate 38400baud failed. +// -2: writing to serial port failed. +// -3: switching to fast baud rate failed. +// -4: writing to serial port with fast baud rate failed. +// +// COMMENTS: The connection is set up according to the bootloader's +// serial download protocoll. +//============================================================================= + int connectToSimpad(const int fastBaudRate, + int& errorNumber); + +//============================================================================= +// PURPOSE: Sending a block of 512byte. +// +// PARAMETERS: +// b: (IN) pointer to the beginning of the 512byte buffer. +// len: (IN) length of the buffer. +// errorNumber: (OUT) error number determined with +// GetLastError(). +// RETURN VALUE: +// TRUE: success +// FALSE: error. See errorNumber for the reason. +// +// COMMENTS: The block, which is sent, is always 512byte long. If the +// buffer counts less than 512byte, the block is filled with +// the FILLER pattern. +//============================================================================= + bool sendBlock(const char *b, + const int len, + int& errorNumber); + +//============================================================================= +// PURPOSE: Waiting for the end of burning. +// +// PARAMETERS: - +// +// RETURN VALUE: - +// +// COMMENTS: - +//============================================================================= + void waitForEndOfBurning(void); + +private: + // File descriptor of open serial port. + int _serialPort; + +//============================================================================= +// PURPOSE: Changing baud rate. +// +// PARAMETERS: +// newBaudRate: (IN) new baud rate to switch to. +// errorNumber: (OUT) error number determined with +// GetLastError(). +// +// RETURN VALUE: +// TRUE: success +// FALSE: error. See errorNumber for the reason. +// +// serialMENTS: - +//============================================================================= + bool changeBaudRate(const int newBaudRate, + int &errorNumber); + +//============================================================================= +// PURPOSE: Waiting for control character. +// +// PARAMETERS: +// transparent: (IN) 0 = received characters are sent to +// stdout. +// +// RETURN VALUE: +// c: control character. +// +// COMMENTS: - +//============================================================================= + unsigned char waitForReply(const int transparent); + +}; +#endif // __SERIAL_DOWNLOAD diff --git a/simpad-utilities/serload/serload.1 b/simpad-utilities/serload/serload.1 index e69de29bb2..4d5738b7de 100644 --- a/simpad-utilities/serload/serload.1 +++ b/simpad-utilities/serload/serload.1 @@ -0,0 +1,38 @@ +.TH serload 1 19.08.2001 Distribution "SIMpad Serial Download" +.SH NAME +serload - Downloading a new image to the SIMpad + +.SH SYNOPSIS +.B serload +.I [IMAGEFILENAME] [ttyS-PORT] + +.SH DESCRIPTION +.B serload +downloads a new image to the SIMpad using +the serial port. You need to connect the SIMpad +to your PC with the delivered serial crossover cable +and execute +.B serload +with the image name as parameter. +As an optional parameter, you can provide the serial port +for +.B serload +to use, otherwise, /dev/ttyS0 is assumed as +default. +.B serload +will ask you to reset the SIMpad to +download the new image. Depending on the image, it will +be burnt into the Flash or directly executed in the +RAM without burning. +.P +You can update the operating system, +the firmware (PBL), and the bootloader with this utility. Updating +the bootloader needs two steps: 1st downloading/burning +a special bootloader (the so-called alternativ bootloader), +2nd downloading/burning the new bootloader. + +.SH AUTHORS +Peter Voser, peter.voser@siemens.ch +.br +Juergen Messerer, juergen.messerer@siemens.ch + |