📄 download.c
字号:
//****************************************************************************
//
// DOWNLOAD.C - Automates the download of code into the NOR FLASH
// on the EP93xx boards.
//
// Copyright (c) 2005 Cirrus Logic, Inc.
//
//****************************************************************************
#include <stdio.h>
#include <string.h>
//****************************************************************************
//
// The arm code which executed at 0x80014000-0x80014800.
// The memory region belong to the internal ethernet buffer.
//
//****************************************************************************
#include "boot/boot.h"
//****************************************************************************
//
// The arm code which executed at 0x00000000-0x00010000.
// The memory region belong to the SDRAM.
//
//****************************************************************************
#include "src/init.h"
#ifdef __CYGWIN__
#define _WIN32
#endif
#ifdef _WIN32
#include <windows.h>
#include "getopt.h"
#endif
#ifdef __linux__
#include <sys/ioctl.h>
#include <sys/timeb.h>
#include <errno.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#endif
//****************************************************************************
//
// lSerialPort is the serial port which is being used.
//
//****************************************************************************
#ifdef _WIN32
HANDLE hSerialPort;
#endif
#ifdef __linux__
long lSerialPort;
#endif
//****************************************************************************
//
// OpenPort opens the specified serial port.
//
//****************************************************************************
int
OpenPort(long lPort,int bUSBPort)
{
#ifdef _WIN32
char pcName[16];
//
// Create the device name for the given serial port.
//
sprintf(pcName, "COM%d", lPort);
//
// Open the serial port.
//
hSerialPort = CreateFile(pcName, GENERIC_READ | GENERIC_WRITE, 0, 0,
OPEN_EXISTING, 0, 0);
if(hSerialPort == INVALID_HANDLE_VALUE)
{
fprintf(stderr, "Could not open serial port %s.\n", pcName);
return(0);
}
//
// Success.
//
return(1);
#elif defined(__linux__)
char pcName[16], pcLock[32], pcBuffer[64];
long lLock, lCount, lPid;
struct termios buf;
//
// Create the file name for the lock file.
//
//sprintf(pcLock, "/var/lock/LCK..ttyS%d", lPort - 1);
if(bUSBPort==0)
{
sprintf(pcLock, "/var/lock/LCK..ttyS%d", lPort - 1);
}
else if(bUSBPort==1)
{
sprintf(pcLock, "/var/lock/LCK..ttyUSB%d", lPort);
}
//
// Attempt to open the lock file.
//
lLock = open(pcLock, O_RDONLY);
if(lLock)
{
//
// The lock file exists, so read from it and then close it.
//
lCount = read(lLock, pcBuffer, 63);
close(lLock);
//
// See if any data was read from the lock file.
//
if(lCount > 0)
{
//
// The PID is currently unknown, so set it to -1.
//
lPid = -1;
//
// See if the lock file contained only four bytes, indicating a
// Kermit-style lock file.
//
if(lCount == 4)
{
//
// Extract the PID from the lock file data.
//
lPid = *(long *)pcBuffer;
}
//
// Otherwise, the lock file is in ASCII.
//
else
{
//
// Make sure that the string is NULL terminated.
//
pcBuffer[lCount] = 0;
//
// Convert the PID from ASCII to an integer.
//
sscanf(pcBuffer, "%d", &lPid);
}
//
// If a PID was found, see if the process still exists.
//
if((lPid > 0) && (kill((pid_t)lPid, 0) < 0) && (errno == ESRCH))
{
//
// The process no longer exists, meaning that the lock is
// stale. Delete the lock file.
//
unlink(pcLock);
}
else
{
//
// The process still exists, so the port is locked.
//
lCount = 0;
}
}
//
// See if the port is locked.
//
if(lCount == 0)
{
//
// Indicate that the port is locked.
//
if(bUSBPort==0)
{
fprintf(stderr, "Serial port /dev/ttyS%d is locked!\n", lPort - 1);
}
else if(bUSBPort==1)
{
fprintf(stderr, "Serial port /dev/ttyUSB%d is locked!\n", lPort);
}
//fprintf(stderr, "Serial port /dev/ttyS%d is locked!\n", lPort - 1);
return(0);
}
}
//
// Create the lock file.
//
lLock = creat(pcLock, 0666);
if(lLock >= 0)
{
//
// Print our PID to the lock file.
//
sprintf(pcBuffer, "%ld\n", (long)getpid());
write(lLock, pcBuffer, strlen(pcBuffer));
close(lLock);
}
//
// Create the device name for the given serial port.
//
//sprintf(pcName, "/dev/ttyS%d", lPort - 1);
if(bUSBPort==0)
{
sprintf(pcName, "/dev/ttyS%d", lPort - 1);
}
else if(bUSBPort==1)
{
sprintf(pcName, "/dev/ttyUSB%d", lPort);
}
//
// Open the serial port.
//
lSerialPort = open(pcName, O_RDWR | O_NONBLOCK);
if(lSerialPort < 0)
{
unlink(pcLock);
//fprintf(stderr, "Could not open serial port %s.\n", pcName);
if(bUSBPort==0)
{
fprintf(stderr, "Could not open normal serial port %s.\n", pcName);
}
else if(bUSBPort==1)
{
fprintf(stderr, "Could not open USB serial port %s.\n", pcName);
}
return(0);
}
//
// Get the attributes of the serial port. This will fail if the serial
// port does not exist (even though the open will succeed if the serial
// port does not exist).
//
if(tcgetattr(lSerialPort, &buf))
{
unlink(pcLock);
fprintf(stderr, "Could not open serial port %s.\n", pcName);
return(0);
}
//
// Success.
//
return(1);
#else
//
// There is no serial port support for the target environment, so return
// an error.
//
fprintf(stderr, "No serial port support!\n");
return(0);
#endif
}
//****************************************************************************
//
// ClosePort closes the currently opened serial port.
//
//****************************************************************************
void
ClosePort(long lPort,int bUSBPort)
{
#ifdef _WIN32
//
// Close the serial port.
//
CloseHandle(hSerialPort);
#endif
#ifdef __linux__
char pcLock[32];
//
// Close the serial port.
//
close(lSerialPort);
//
// Create the file name for the lock file.
//
if(bUSBPort==0)
{
sprintf(pcLock, "/var/lock/LCK..ttyS%d", lPort - 1);
}
else if(bUSBPort==1)
{
sprintf(pcLock, "/var/lock/LCK..ttyUSB%d", lPort);
}
//
// Delete the lock file.
//
unlink(pcLock);
#endif
}
//****************************************************************************
//
// SetBaud sets the baud rate and data format of the serial port.
//
//****************************************************************************
void
SetBaud(long lRate)
{
#ifdef _WIN32
DCB dcb;
//
// Purge any pending characters in the serial port.
//
PurgeComm(hSerialPort, (PURGE_TXABORT | PURGE_RXABORT |
PURGE_TXCLEAR | PURGE_RXCLEAR));
//
// Fill in the device control block.
//
dcb.DCBlength = sizeof(DCB);
dcb.BaudRate = lRate;
dcb.fBinary = TRUE;
dcb.fParity = FALSE;
dcb.fOutxCtsFlow = FALSE;
dcb.fOutxDsrFlow = FALSE;
dcb.fDtrControl = DTR_CONTROL_DISABLE;
dcb.fDsrSensitivity = FALSE;
dcb.fTXContinueOnXoff = TRUE;
dcb.fOutX = FALSE;
dcb.fInX = FALSE;
dcb.fErrorChar = FALSE;
dcb.fNull = FALSE;
dcb.fRtsControl = RTS_CONTROL_DISABLE;
dcb.fAbortOnError = FALSE;
dcb.XonLim = 0;
dcb.XoffLim = 0;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
dcb.XonChar = 17;
dcb.XoffChar = 19;
dcb.ErrorChar = 0;
dcb.EofChar = 0;
dcb.EvtChar = 0;
dcb.wReserved = 0;
//
// Set the new serial port configuration.
//
SetCommState(hSerialPort, &dcb);
#endif
#ifdef __linux__
struct termios buf;
int rate;
//
// Get the current settings for the serial port.
//
if(tcgetattr(lSerialPort, &buf))
{
return;
}
//
// Reset to the serial port to raw mode.
//
buf.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP |
INLCR | IGNCR | ICRNL | IXON);
buf.c_oflag &= ~OPOST;
buf.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
buf.c_cflag &= ~(CSIZE | PARENB);
buf.c_cflag |= CS8;
//
// Get the baud rate.
//
switch(lRate)
{
case 9600:
{
rate = B9600;
break;
}
case 19200:
{
rate = B19200;
break;
}
case 38400:
{
rate = B38400;
break;
}
case 57600:
{
rate = B57600;
break;
}
case 115200:
{
rate = B115200;
break;
}
}
//
// Set the input and output baud rate of the serial port.
//
cfsetispeed(&buf, rate);
cfsetospeed(&buf, rate);
//
// Set data bits to 8.
//
buf.c_cflag &= ~CSIZE;
buf.c_cflag |= CS8;
//
// Set stop bits to one.
//
buf.c_cflag &= ~CSTOPB;
//
// Disable parity.
//
buf.c_cflag &= ~(PARENB | PARODD);
//
// Set the new settings for the serial port.
//
if(tcsetattr(lSerialPort, TCSADRAIN, &buf))
{
return;
}
//
// Wait until the output buffer is empty.
//
tcdrain(lSerialPort);
#endif
}
//****************************************************************************
//
// SendChar sends a character to the serial port.
//
//****************************************************************************
void
SendChar(char cChar)
{
#ifdef _WIN32
DWORD dwLen;
//
// Send this character to the serial port.
//
WriteFile(hSerialPort, &cChar, 1, &dwLen, NULL);
#endif
#ifdef __linux__
//
// Send this character to the serial port.
//
write(lSerialPort, &cChar, 1);
#endif
}
//****************************************************************************
//
// ReceiveChar reads a character from the serial port.
//
//****************************************************************************
char
ReceiveChar(long lTimeout)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -