📄 mxc_download.cpp
字号:
#include <conio.h>
#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"
#include <stdio.h>
#include <windows.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#include <io.h>
#include "mxc_download.h"
//#define PRINTK(fmt, args...) printk(fmt, ## args)
//#define MXC_DOWNLOAD_DEBUG
#ifdef MXC_DOWNLOAD_DEBUG
#define D_PRINTF printf
#else
#define D_PRINTF(x)
#endif
void Setup_Port(int baud);
HANDLE Open_Port(int Port_Num, char* port_name1, int baud);
void Shutdown_Port(char *port_name_, HANDLE portH);
#define READ_BUF_SIZE 0x1000 // bytes
#define READ_BUF_SIZE1 0x1 // bytes
static char read_buffer[READ_BUF_SIZE];
HANDLE hPort = NULL; // Serial Port file pointer
BOOL Port_Ready;
DCB dcb;
COMMTIMEOUTS CommTimeouts;
DWORD g_bytes_written;
int default_BaudRate;
int default_Parity;
int default_ByteSize;
int default_StopBits;
#define PRINT_HELP_MSG() \
{ \
printf("Syntax:\n"); \
printf(" %s <COM Port> <Address> <File Name> <platform>\n", argv[0]); \
printf("\nFor example, to download Redboot binary to 0x81f00000 on \n"); \
printf("MXC275-30 EVB via COM1, use:\n"); \
printf(" %s COM1 0x81f00000 mxc27530evb_redboot.bin mxc27530evb\n", argv[0]); \
printf("For platforms like i.300-30 EVB, MXC300-30 EVB, MXC91131 EVB, \n"); \
printf("MXC91131 MEM1 EVB:\n"); \
printf(" %s COM1 0x83f00000 i30030evb_redboot.bin i30030evb\n", argv[0]); \
printf(" %s COM1 0x83f00000 mxc30030evb_redboot.bin i30030evb\n", argv[0]); \
printf(" %s COM1 0x83f00000 mxc91131evb_redboot.bin mxc91131evb\n", argv[0]); \
printf(" %s COM1 0x83f00000 mxc91131mem1evb_redboot.bin mxc91131mem1evb\n", argv[0]); \
printf("\n"); \
}
#define TEST_FILE
#ifdef TEST_FILE
const char *test_write_file = "readback.bin";
#endif
enum {
e_I30030EVB,
e_MXC27530EVB,
e_MXC91131EVB,
e_MXC91131EVBMEM1,
};
static char *dat_file[] =
{
"i30030evb.dat",
"mxc27530evb.dat",
"mxc91131evb.dat",
"mxc91131mem1evb.dat",
};
char *chip_str[] = {
"i300-30/MXC300-30 EVB",
"MXC275-30 EVB",
"MXC91131 EVB",
"MXC91131 EVB with MEM1 card",
};
int parse_cmd_line(char* argv[], int *p_num, unsigned long *dn_addr, unsigned long *chip)
{
int val1, port;
unsigned long download_addr = 0;
char *ptr;
// Check for COM port
if ((argv[1][0] != 'C' && argv[1][0] != 'c') || (argv[1][1] != 'O' && argv[1][1] != 'o') ||
(argv[1][2] != 'M' && argv[1][2] != 'm') || argv[1][3] == '\0') {
printf("Use 'COM1', 'COM2', ...\n");
return (__LINE__);
}
ptr = &argv[1][3];
while ((val1 = *ptr++) != '\0') {
if (val1 < '0' || val1 > '9') {
printf("Wrong port number.\n");
return (__LINE__);
}
}
port = atoi(&(argv[1][3]));
// Check for download address
if (argv[2][0] != '0' || argv[2][1] != 'x') {
printf("Wrong address, use hex format: 0x.... instead\n");
return (__LINE__);
}
ptr = &argv[2][2];
while ((val1 = *ptr++) != '\0') {
download_addr *= 16;
if (val1 >= 'a' && val1 <= 'f')
download_addr += val1 - 'a' + 10;
else if (val1 >= 'A' && val1 <= 'F')
download_addr += val1 - 'A' + 10;
else if (val1 >= '0' && val1 <= '9')
download_addr += val1 - '0';
else {
printf("Wrong hex value for address \n");
return (__LINE__);
}
}
*dn_addr = download_addr;
// Check for chip
if (strcmp(argv[4], "i30030evb") == 0) {
*chip = e_I30030EVB;
} else if (strcmp(argv[4], "mxc27530evb") == 0) {
*chip = e_MXC27530EVB;
} else if (strcmp(argv[4], "mxc91131evb") == 0) {
*chip = e_MXC91131EVB;
} else if (strcmp(argv[4], "mxc91131mem1evb") == 0) {
*chip = e_MXC91131EVBMEM1;
} else {
printf("Wrong chip\n\n");
return -1;
}
return 0;
}
BOOL write_to_com(HANDLE handle, unsigned char* str, unsigned long len) {
return WriteFile(handle, str, len, &g_bytes_written, NULL);
}
struct send_data {
unsigned char *preamble;
unsigned char *dst_addr;
unsigned char *data_len_bytes;
unsigned char *ubmr;
unsigned char *data_buf;
unsigned char *checksum;
};
struct send_data g_data;
//const DATA_LEN = 1024*16;
const DATA_LEN = 4*1024;
unsigned char buffer_to_send[DATA_LEN];
unsigned char buffer_to_send_download[DATA_LEN]; // 16KB data
unsigned char aA[] = {
'a', 'A', 'a', 'A', 'a', 'A', 'a', 'A', 'a', 'A', 'a',
'A', 'a', 'A', 'a', 'A', 'a', 'A', 'a', 'A', 'a', 'A',
};
unsigned char preamble[] = {0x55, 0x55, 0x55, 0xAA};
unsigned char dst_addr[][4] = {
{0x1F, 0xFF, 0xd0, 0x00}, // MXC913x1
{0x78, 0x00, 0x10, 0x00}, // MXC91231
{0xB8, 0x02, 0x20, 0x00}, // MXC91131
{0xB8, 0x02, 0x20, 0x00}, // MXC91131 on MEM1 EVB
};
#define DEBUG_BOARD
int main(int argc, char* argv[])
{
int port, i;
unsigned long download_addr = 0;
char *file_name;
char *port_name;
HANDLE portH;
FILE *fp, *fp_download;
unsigned long filesize, checksum = 0, bytes_read, chip;
unsigned char data_len_bytes[] = {DATA_LEN >> 8, (DATA_LEN & 0xFF)};
unsigned char ubmr[] = {0, 0};
g_data.preamble = preamble;
g_data.ubmr = ubmr;
g_data.data_buf = buffer_to_send;
g_data.data_len_bytes = data_len_bytes;
printf("\n");
if (argc == 1) {
printf("This program is used to download a file to a memory location on the\n");
printf("MXC platforms and then jump to it.\n\n");
goto help_msg;
}
if (argc != 5) {
printf("Wrong number of arguments.\n");
goto help_msg;
}
if (parse_cmd_line(argv, &port, &download_addr, &chip) != 0) {
goto help_msg;
}
port_name = argv[1];
file_name = argv[3];
g_data.dst_addr = dst_addr[chip];
printf("Downloading %s via %s to 0x%x on %s board\n",
file_name, port_name, download_addr, chip_str[chip]);
if ((portH = Open_Port(port, port_name, 19200)) == INVALID_HANDLE_VALUE) {
printf("Error: %s is in use\n", port_name);
return -1;
}
/////////////// start board file read //////////////////////////////
// Send file via serial port. Open the file first
if ((fp = fopen(dat_file[chip],"rb")) == NULL) {
printf("\nUnable to open %s\n", dat_file[chip]);
exit (-1);
}
if ((fp_download = fopen(file_name,"rb")) == NULL) {
printf("\nUnable to open file: %s\n", file_name);
exit (-1);
}
filesize = filelength(fileno(fp));
// read in board file to send
i = fread(buffer_to_send, sizeof(char), DATA_LEN, fp);
//////////// end of board file read /////////////
//////////// Get the checksum value ///////////////////
checksum = g_data.dst_addr[0] + g_data.dst_addr[1] + g_data.dst_addr[2] + g_data.dst_addr[3] +
g_data.data_len_bytes[0] + g_data.data_len_bytes[1] +
g_data.ubmr[0] + g_data.ubmr[1];
for (i = 0; i < DATA_LEN; i++) {
checksum += g_data.data_buf[i];
}
checksum = 0xFF - (checksum & 0xFF);
g_data.checksum = (unsigned char *) &checksum;
//////////// End of the checksum value ///////////////////
///// Make sure to get back with 'Z' //////////
D_PRINTF("line: %d\n", __LINE__);
if (write_to_com(portH, aA, sizeof(aA)) == 0) {
printf("Failed to write aA to COM port\n");
exit (-1);
}
D_PRINTF("line: %d\n", __LINE__);
if (ReadFile(portH, read_buffer, READ_BUF_SIZE1, &bytes_read, NULL) == 0) {
printf("ReadFile failed at line: %d\n", __LINE__);
goto func_out;
}
D_PRINTF("line: %d\n", __LINE__);
if (read_buffer[0] != 'Z') {
printf("Failed to initialize the board. Wrong value: 0x%x\n", read_buffer[0]);
goto func_out;
}
D_PRINTF("Receiving Z\n");
////////// End of getting back with Z /////////
//////////// Downloading board file to internal RAM /////////
if (write_to_com(portH, g_data.preamble, 4) == 0) {
printf("Failed to write preamble to COM port\n");
exit (-1);
}
if (write_to_com(portH, g_data.dst_addr, 4) == 0) {
printf("Failed to write dest addr to COM port\n");
exit (-1);
}
if (write_to_com(portH, g_data.data_len_bytes, 2) == 0) {
printf("Failed to write data bytes to send to COM port\n");
exit (-1);
}
if (write_to_com(portH, g_data.ubmr, 2) == 0) {
printf("Failed to write ubmr to COM port\n");
exit (-1);
}
if (write_to_com(portH, g_data.data_buf, DATA_LEN) == 0) {
printf("Failed to write data buffer to COM port\n");
exit (-1);
}
if (write_to_com(portH, g_data.checksum, 1) == 0) {
printf("Failed to write checksum to COM port\n");
exit (-1);
}
//////////// Done downloading board file to internal RAM /////////
// Now the board file should be downloaded and the target should executing
// the board file. The board file contains program to change the uart baud
// rate to 115200 and start to download "read" downloaded file int
// switch to higher baud rate after downloading bin into internal RAM
// to be ready to download user-passed in file
if (chip != e_MXC91131EVB && chip != e_MXC91131EVBMEM1) {
D_PRINTF("Changing baud rate to 115200\n");
Setup_Port(115200);
}
D_PRINTF("line: %d\n", __LINE__);
///////////// Check to see if "lucky" is ready ///////
if (ReadFile(portH, read_buffer, 5, &bytes_read, NULL) == 0) {
printf("ReadFile failed at line: %d\n", __LINE__);
goto func_out;
}
D_PRINTF("line: %d\n", __LINE__);
read_buffer[5] = '\0';
if (strcmp(read_buffer, "Lucky") != 0) {
printf("Not lucky. Got: %s\n", read_buffer);
goto func_out;
}
D_PRINTF("line: %d\n", __LINE__);
filesize = filelength(fileno(fp_download));
if (write_to_com(portH, (unsigned char*)&download_addr, 4) == 0) {
printf("Failed to write download addr to COM port\n");
exit (-1);
}
D_PRINTF("line: %d\n", __LINE__);
if (write_to_com(portH, (unsigned char*)&filesize, 4) == 0) {
printf("Failed to write download size to COM port\n");
exit (-1);
}
D_PRINTF("line: %d\n", __LINE__);
// ready to send data
printf("\n");
while (1) {
if ((i = fread(buffer_to_send_download, sizeof(char), DATA_LEN, fp_download)) > 0) {
if (ReadFile(portH, read_buffer, READ_BUF_SIZE1, &bytes_read, NULL) == 0) {
printf("ReadFile failed at line: %d\n", __LINE__);
goto func_out;
}
if (read_buffer[0] != 'Z') {
printf("Failed to initialize the board. Wrong value: 0x%x\n", read_buffer[0]);
goto func_out;
} else {
printf(".");
}
if (write_to_com(portH, buffer_to_send_download, i) == 0)
{
printf("Failed to write data buffer download to COM port\n");
exit (-1);
}
}
if (i < DATA_LEN) break;
}
printf("\n\nDone\n");
func_out:
fclose(fp);
Shutdown_Port(port_name, portH);
exit (0); // Normal return
help_msg:
PRINT_HELP_MSG();
exit (-1);
}
/**************************************************************************************
* Routine Name: Open_Port(int Port_Num, char* port_name1, int baud)
*
* This routine opens a serial port for reading or writing.
**************************************************************************************/
HANDLE Open_Port(int Port_Num, char* port_name1, int baud)
{
HANDLE hPort1;
//printf("\nOpen_Port for RW Opening = %s \n",port_name);
hPort1 = CreateFile (port_name1,// Pointer to the name of the port
GENERIC_READ | GENERIC_WRITE, // Access (read-write) mode
0, // Share mode
NULL, // Pointer to the security attribute
OPEN_EXISTING, // How to open the port
0, // Port attributes
NULL); // Handle to port with attribute
if (hPort1 == INVALID_HANDLE_VALUE) {
printf("Could not open %s\n", port_name1); // process error
return INVALID_HANDLE_VALUE;
}
else {
//printf("Setting up port %s\n",port_name);
Setup_Port(baud);
}
return hPort1;
}
/**************************************************************************************
* Routine Name: Shutdown_Port
*
* This routine closes a port with a serial or parallel port printer.
**************************************************************************************/
void Shutdown_Port(char *port_name_, HANDLE portH)
{
//If a previous serial or parallel port is open and we've changed ports,
//close the first one so the new one can be opened.
if (portH != NULL)
{
CloseHandle(portH);
}
}
/**************************************************************************************
* Routine Name: Setup_Port(int baud)
*
* This routine will setup the serial or parallel port currently selected
**************************************************************************************/
void Setup_Port(int baud)
{
//Check the returned handle for INVALID_HANDLE_VALUE and then set the buffer sizes.
Port_Ready = SetupComm(hPort, PACKET_SIZE, PACKET_SIZE); // set buffer sizes
//Port settings are specified in a Data Communication Block (DCB).
//The easiest way to initialize a DCB is to call GetCommState to
//fill in its default values, override the values that you want to
//change and then call SetCommState to set the values.
//Set up transmission information
//Also see DOS Mode command: Mode COM1: 9600,N,8,1
Port_Ready = GetCommState(hPort, &dcb);
default_BaudRate = dcb.BaudRate;
default_Parity = dcb.Parity;
default_ByteSize = dcb.ByteSize;
default_StopBits = dcb.StopBits;
dcb.BaudRate = baud;
dcb.Parity = NOPARITY;
dcb.ByteSize = 8;
dcb.StopBits = 1;
dcb.fAbortOnError = TRUE;
Port_Ready = SetCommState(hPort, &dcb);
//Communication timeouts are optional but can be set similarly to DCB values
//This will prevent the program from hanging should the port does not respond.
Port_Ready = GetCommTimeouts (hPort, &CommTimeouts);
CommTimeouts.ReadIntervalTimeout = 50;
CommTimeouts.ReadTotalTimeoutConstant = 50;
CommTimeouts.ReadTotalTimeoutMultiplier = 10;
CommTimeouts.WriteTotalTimeoutConstant = 50;
CommTimeouts.WriteTotalTimeoutMultiplier = 10;
Port_Ready = SetCommTimeouts (hPort, &CommTimeouts);
//If all of these API's were successful then the port is ready for use.
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -