STM32
直播中

杨勇

7年用户 1188经验值
私信 关注
[问答]

如何实现自己写个串口编程和控制台程序实现一键下载?

如何实现自己写个串口编程和控制台程序实现一键下载?

回帖(1)

袁钧质

2021-12-3 09:48:24
鉴于flymcu下载时有点慢,flash_loader.exe容易卡死的原因,所以决定自己写个串口编程和控制台程序。然后写成bat文件,再整合到Visual studio的外部工具里,实现一键下载。





STM32_ISP的协议文档可以在st的官网上找到。
先说下控制台的大致思路:
程序的目标:把*.bin文件通过指定串口发送到stm32,stm32把收到的*.bin文件数据存到指定的flash地址。
控制台这边要给的指令是:例如:COM4 256000 0X08000000 M:codedebugtext.bin
1.电脑的串口编号: COM4
2.要使用的串口波特率: 256000
3.编程地址: 0X08000000
4.*.bin文件路径: M:codedebugtext.bin
所有的指令可以通过int main(int argc, char** argv),的**argv指针获得。
例如:把上面的指令通过CMD输入后





程序:



int main(int argc, char** argv)
{
    for (int i = 0; i < argc; i++)
    {
        printf("argv[%d]:%sn", i, argv);
    }

}
运行结果:


argv[0]:M:stm32_isp_programerstm32_isp_programmerDebugstm32_isp_programmer.exe
argv[1]:COM6
argv[2]:256000
argv[3]:0X08000000
argv[4]:M:codedebugtext.bin


但是获得只是文本类型(char *)。


windows 要打开串口的话用需要用WCHAR* 类型。


所以要做一定的类型转换。


字符串转WCHAR:


#include
wchar_t wstr[20];
swprintf(wstr, 20, L"%S", str);
LPCWSTR wstr_p= wstr;
字符串转10进制


字符串转16进制


#include
long baudrate = strtol(setBuadrate_p, &endptr, 10);
long writeAddress = strtol(writeAddress_p, &endptr, 16);
然后是打开串口:


SerialPort.hSerial = CreateFile(filename, //lpFileName
                GENERIC_READ | GENERIC_WRITE,//dwDesiredAccess
                0, //dwShareMode
                NULL,//lpSecurityAttributes
                OPEN_EXISTING,//dwCreationDisposition
                FILE_ATTRIBUTE_NORMAL,
                NULL);//hTemplateFile
串口配制:


SerialPort.NewDCBParams.BaudRate = baudrate;
SerialPort.NewDCBParams.ByteSize = 8;
SerialPort.NewDCBParams.StopBits = ONESTOPBIT;
SerialPort.NewDCBParams.Parity = EVENPARITY;
if (!SetCommState(SerialPort.hSerial, &SerialPort.NewDCBParams)) {
    printf("nSetCommState error!n");
    fflush(stdout);
    return(1);
}
COMMTIMEOUTS timeouts = { 0 };
timeouts.ReadIntervalTimeout = 1000;
timeouts.ReadTotalTimeoutConstant = 1000;
timeouts.ReadTotalTimeoutMultiplier = 10;
timeouts.WriteTotalTimeoutConstant = 50;
timeouts.WriteTotalTimeoutMultiplier = 10;
if (!SetCommTimeouts(SerialPort.hSerial, &timeouts)) {
    printf("nSetCommTimeouts error!n");
    fflush(stdout);
    return(1);
}
串口读写:


DWORD serial_write(unsigned char* buffer, DWORD len)
{
        DWORD lengthwrote;
        if (!WriteFile(SerialPort.hSerial, buffer, len, &lengthwrote, NULL)) {
                if (GetLastError() == ERROR_IO_PENDING)
                {
                        printf("Error:%d Serial write fail, exiting lengthwrote:%dn", GetLastError(), lengthwrote);
                }
                printf("Error:%d Serial write fail, exiting lengthwrote:%dn", GetLastError(), lengthwrote);
                exit(1);
        }
        return(lengthwrote);
}
DWORD serial_read(unsigned char* buffer, size_t len) //windows version
{
        DWORD bytesread;
        if (!ReadFile(SerialPort.hSerial, buffer, len, &bytesread, NULL)) {
                printf("Error: Serial read fail, exitingn");
                exit(1);
        }
        return(bytesread);
}
如果有加了RTS#控制的话,还可以用RTS来控制单片机复位:


void hardwareReset()
{
        UINT8 restTime = 5;
        while (restTime--)
        {
                if (!EscapeCommFunction(SerialPort.hSerial, SETRTS)) {
                        printf("nEscapeCommFunction error in serial_config, SETRTSn");
                        fflush(stdout);
                        exit(1);
                }
                Sleep(100);
                if (!EscapeCommFunction(SerialPort.hSerial, CLRRTS)) {
                        printf("nEscapeCommFunction error in serial_config, SETRTSn");
                        fflush(stdout);
                        exit(1);
                }
                Sleep(100);
                printf("%dn", restTime);
        }
}



后面是STM32 ISP协议部分:


主要用到这几个:


void autoBaudrateStart(void);//自动识别波特率
void clear_writeprotect(void);//清除写保护
void get_version(void);//获取bootloader版本号,不同版本支持的指令不一样
void get_id(void);//获取芯片ID
void globalerase_flash(void);//全片清除flash
void program_memory(void);//flash编程
然后是通信格式:


基本是:


1字节命令+1字节命令反码


N字节内容+1字节所有内容字节的^(异或运算)


通信流程:发送指令,等待ACK或者NACK,发送内容,等待ACK或者NACK


主程序:


#include
#include
#include
#include "Serial.h"
#include "action.h"
#include
/*
COM3 115200 0X08000000 D:SDALJGG.BIN
*/
int main(int argc, char** argv)
{
        SYSTEMTIME bootTime;
        SYSTEMTIME exitTime;
        char* selectPort_p;
        char* setBuadrate_p;
        char* writeAddress_p;
        char* loadFile;
        GetSystemTime(&bootTime);
        for (int i = 0; i < argc; i++)
        {
                printf("argv[%d]:%sn", i, argv);
        }
        selectPort_p = argv[1];
        setBuadrate_p = argv[2];
        writeAddress_p = argv[3];
        loadFile = argv[4];
        printf("selectPort:%sn", selectPort_p);
        printf("setBuadrate_p:%sn", setBuadrate_p);
        printf("writeAddress_p:%sn", writeAddress_p);
        printf("loadFile:%sn", loadFile);
        char *endptr;       
        long baudrate = strtol(setBuadrate_p, &endptr, 10);
        long writeAddress = strtol(writeAddress_p, &endptr, 16);
        hostHandle.baudrate = baudrate;
        hostHandle.loadFile = loadFile;
        hostHandle.serialDev = selectPort_p;
        hostHandle.writeAddress = writeAddress;
        serial_init(selectPort_p, baudrate);
        autoBaudrateStart();
        get_version();
        get_id();
        clear_writeprotect();
        globalerase_flash();
        program_memory();
        printf("Isp complete and reseting...n");
        hardwareReset();
        GetSystemTime(&exitTime);
        size_t timeUse = (exitTime.wMinute * 60 + exitTime.wSecond) * 1000 + exitTime.wMilliseconds;
        timeUse = timeUse - ((bootTime.wMinute * 60 + bootTime.wSecond) * 1000 + bootTime.wMilliseconds);
        printf("Total time use: %d.%d secondsn", timeUse/1000, timeUse%1000);       
}
串口配置:


#pragma once
#include
char serial_init(char * serialPortName, UINT32 baudrate);
DWORD serial_write(unsigned char* buffer, DWORD len);
DWORD serial_read(unsigned char* buffer, size_t len);
void Serial_putc(unsigned char c);
unsigned char Serial_getc(void);
void hardwareReset();
typedef struct  {
        int open;
        int status;
        HANDLE hSerial;
        DCB OldDCBParams;
        DCB NewDCBParams;
}SerialPort_s;
extern SerialPort_s SerialPort;
#include
#include
#include
#include "Serial.h"

SerialPort_s SerialPort;
void hardwareReset()
{
        UINT8 restTime = 5;
        while (restTime--)
        {
                if (!EscapeCommFunction(SerialPort.hSerial, SETRTS)) {
                        printf("nEscapeCommFunction error in serial_config, SETRTSn");
                        fflush(stdout);
                        exit(1);
                }
                Sleep(100);
                if (!EscapeCommFunction(SerialPort.hSerial, CLRRTS)) {
                        printf("nEscapeCommFunction error in serial_config, SETRTSn");
                        fflush(stdout);
                        exit(1);
                }
                Sleep(100);
                printf("%dn", restTime);
        }
}
char serial_init(char *serialPortName, UINT32 baudrate)
{
        wchar_t portName[20];
        swprintf(portName, 20, L"%S", serialPortName);
        LPCWSTR filename = portName;
        SerialPort.hSerial = CreateFile(filename, //lpFileName
                GENERIC_READ | GENERIC_WRITE,//dwDesiredAccess
                0, //dwShareMode
                NULL,//lpSecurityAttributes
                OPEN_EXISTING,//dwCreationDisposition
                FILE_ATTRIBUTE_NORMAL,
                NULL);//hTemplateFile

        if (SerialPort.hSerial == INVALID_HANDLE_VALUE)
        {
                if (GetLastError() == ERROR_FILE_NOT_FOUND)
                {
                        printf("ERROR_FILE_NOT_FOUND: Serial port: %ws not found on your computer.n", filename);
                        fflush(stdout);
                        return(1);
                }
                else if (GetLastError() == ERROR_ACCESS_DENIED)
                {
                        printf("ERROR_ACCESS_DENIED: Serisl port: %ws Access denied!n", filename);
                        fflush(stdout);
                        return(1);
                }
                else if (GetLastError() == ERROR_INVALID_NAME)
                {
                        printf("ERROR_INVALID_NAME Error: Serisl port: %ws !n", filename);
                        fflush(stdout);
                        return(1);
                }
                else {
                        printf("Error: Serial operat failure. Error Code:%ldn", GetLastError());
                        fflush(stdout);
                        return(1);
                }
        }                       
        printf("Serial port: %s open success!n", serialPortName);
        //success!

        switch (baudrate) {
        case 2400:
                SerialPort.NewDCBParams.BaudRate = CBR_2400;
                break;
        case 4800:
                SerialPort.NewDCBParams.BaudRate = CBR_4800;
                break;
        case 9600:
                SerialPort.NewDCBParams.BaudRate = CBR_9600;
                break;
        case 19200:
                SerialPort.NewDCBParams.BaudRate = CBR_19200;
                break;
        case 38400:
                SerialPort.NewDCBParams.BaudRate = CBR_38400;
                break;
        case 57600:
                SerialPort.NewDCBParams.BaudRate = CBR_57600;
                break;
        case 115200:
                SerialPort.NewDCBParams.BaudRate = CBR_115200;
                break;
        case 256000:
                SerialPort.NewDCBParams.BaudRate = CBR_256000;
                break;
        default:
                SerialPort.NewDCBParams.BaudRate = baudrate;
                printf("baudrate:%d may not support.n", baudrate);
                fflush(stdout);
                break;
        }
        SerialPort.NewDCBParams.ByteSize = 8;
        SerialPort.NewDCBParams.StopBits = ONESTOPBIT;
        SerialPort.NewDCBParams.Parity = EVENPARITY;
        if (!SetCommState(SerialPort.hSerial, &SerialPort.NewDCBParams)) {
                printf("nSetCommState error!n");
                fflush(stdout);
                return(1);
        }
        COMMTIMEOUTS timeouts = { 0 };
        timeouts.ReadIntervalTimeout = 1000;
        timeouts.ReadTotalTimeoutConstant = 1000;
        timeouts.ReadTotalTimeoutMultiplier = 10;
        timeouts.WriteTotalTimeoutConstant = 50;
        timeouts.WriteTotalTimeoutMultiplier = 10;
        if (!SetCommTimeouts(SerialPort.hSerial, &timeouts)) {
                printf("nSetCommTimeouts error!n");
                fflush(stdout);
                return(1);
        }
        printf("Serial port: %sn", serialPortName);
        printf("Buadrate: %dn", baudrate);
        printf("Data bits: 8n");
        printf("Parity: Evenn");
        printf("Stop bits: 1n");
        printf("Flow control: nonen");
        printf("Serial init complete!n");
        printf("nnnTrying to rest and connet target, please push and hold ""boot0"" button!n");
        printf("Using RTS LOW to reset taeget...n");
        hardwareReset();
        PurgeComm(SerialPort.hSerial, (PURGE_RXCLEAR));
        return 0;
}
DWORD serial_write(unsigned char* buffer, DWORD len)
{
        DWORD lengthwrote;
        if (!WriteFile(SerialPort.hSerial, buffer, len, &lengthwrote, NULL)) {
                if (GetLastError() == ERROR_IO_PENDING)
                {
                        printf("Error:%d Serial write fail, exiting lengthwrote:%dn", GetLastError(), lengthwrote);
                }
                printf("Error:%d Serial write fail, exiting lengthwrote:%dn", GetLastError(), lengthwrote);
                exit(1);
        }
        return(lengthwrote);
}
DWORD serial_read(unsigned char* buffer, size_t len) //windows version
{
        DWORD bytesread;
        if (!ReadFile(SerialPort.hSerial, buffer, len, &bytesread, NULL)) {
                printf("Error: Serial read fail, exitingn");
                exit(1);
        }
        return(bytesread);
}
void Serial_putc(unsigned char c)
{
        if (serial_write(&c, 1) != (size_t)1)
        {
                perror("Error:Serial write one byte fail, exitingn");
                exit(1);
        }
}
unsigned char Serial_getc(void)
{
        unsigned char byte;
        int bytesread;
        int trycount;
        bytesread = 0;
        trycount = 0;
        while (bytesread == 0 && trycount < 10)
        {
                bytesread = serial_read(&byte, 1);
                trycount++;
                if (trycount > 1) {
                        printf("Waiting data from serial port: %i rx:%xn", trycount, bytesread);
                        fflush(stdout);
                }
        }
        if (bytesread != 1) {
                perror("Error: serial port no reponse, exitingn");
                exit(1);
        }
        return(byte);
}
通信协议:


#pragma once

// * Usart config*/
// * 1bit start
// * 0x7F data bits
// * even parity bit
// * one stop bit
// */

#define STM32_ISP_CMD_AUTOBUADRATE 0x7f
#define STM32_ISP_ACK 0x79
#define STM32_ISP_NACK 0x1f

#define STM32_ISP_CMD_GET 0x00
#define STM32_ISP_CMD_GETVERSION 0x01
#define STM32_ISP_CMD_GETID 0x02
#define STM32_ISP_CMD_READMEMORY 0x11
#define STM32_ISP_CMD_GO 0x21
#define STM32_ISP_CMD_WRITEMEMORY 0x31
#define STM32_ISP_CMD_ERASE 0x43
#define STM32_ISP_CMD_EXTENDEDERASE 0x44
#define STM32_ISP_CMD_WRITEPROTECT 0x63
#define STM32_ISP_CMD_WRITEUNPROTECT 0x73
#define STM32_ISP_CMD_READOUTPROTECT 0x82
#define STM32_ISP_CMD_READOUTUNPROTECT 0x92

#define STM32_ISP_CMD_GETVERSIONBYTESTOREAD 3
#define STM32_ISP_CMD_GETVERSION_VERSIONBYTE 0
#define STM32_ISP_CMD_GETVERSION_RDPROTDISABLEDQTYBYTE 1
#define STM32_ISP_CMD_GETVERSION_RDPROTENABLEDQTYBYTE 2

#define STM32_CMD_ERASEGLOBALPAGEQTYFIELD 0xff

#define READPACKETMAXDATA 0x80
#define WRITEPACKETMAXDATA 0x80
#define READPACKETREADCALLSMAX 20

#define STM32FLASHSTART 0x08000000

#define COMMANDWAIT 10
#define COMMANDRETRYCOUNT 4

#define SENDPACKETWAIT 0
#define PACKETREADWAIT 0

#define AUTOBAUDRETRYCOUNT 4
#define AUTOBAUDRETRYWAIT 1000


协议驱动:


#pragma once
#include
#define MAXPACKLEN 250
typedef struct {
        char* serialDev;
        DWORD32 baudrate;
        DWORD32 writeAddress;
        char* loadFile;
}hostHandle_s;
typedef struct{
        unsigned char storage[MAXPACKLEN];
        int length;
}Packet;
extern hostHandle_s hostHandle;
void waitms(int mstowait);
void packet_append(Packet* packet, unsigned char c);
void packet_append16(Packet* packet, unsigned short int c);
void packet_checksumappend(Packet* packet);
void packet_appendcommandandcheck(Packet* packet, unsigned char command);
void packet_zero(Packet* packet);
void packet_send(Packet* packet);
int  packet_sendandgetack(Packet* packet, int trycount);
void autoBaudrateStart(void);
void clear_writeprotect(void);
void get_version(void);
void get_id(void);
void globalerase_flash(void);
void program_memory(void);
#include
#include
#include "Serial.h"
#include "action.h"
#include "STM32_ISP_CommandDefs.h"
hostHandle_s hostHandle;
void waitms(int mstowait)
{
        Sleep(mstowait);                //windows Sleep() takes ms.  
        return;
}
void packet_append(Packet* packet, unsigned char c)
{
        if (packet->length >= MAXPACKLEN - 1) {
                printf("packet too long in packet_append, exiting!");
                exit(1);
        }
        packet->storage[packet->length] = c;
        packet->length++;
        return;
}
void packet_append16(Packet* packet, unsigned short int c)
{
        if (packet->length >= MAXPACKLEN - 1) {
                printf("packet too long in packet_append, exiting!");
                exit(1);
        }
        packet->storage[packet->length] = c >> 8;
        packet->storage[packet->length + 1] = (unsigned char)c;
        packet->length++;
        return;
}
void packet_checksumappend(Packet* packet)
{
        int i;
        unsigned char checksum = 0;
        for (i = 0; i < packet->length; i++)
                checksum = checksum ^ packet->storage;
        packet_append(packet, checksum);
        return;
}

void packet_appendcommandandcheck(Packet* packet, unsigned char command)
{
        packet_append(packet, command);
        packet_append(packet, ~command);        //checksum for commands is the inverted command.
        return;
}


void packet_zero(Packet* packet)
{
        packet->length = 0;
        return;
}

void packet_send(Packet* packet)
{
        int lengthleft;
        int bytesactuallyread;
        unsigned char* packptr;
        packptr = packet->storage;

        lengthleft = packet->length;
        while (1) {
                bytesactuallyread = serial_write(packptr, lengthleft);
                lengthleft -= bytesactuallyread;
                packptr += (size_t)bytesactuallyread;
                if (lengthleft == 0) break;
        }
        waitms(SENDPACKETWAIT);
        return;
}

int  packet_sendandgetack(Packet* packet, int trycount)
{
        int packsendtrycount = 0;
        while (1) {
                packet_send(packet);
                if (Serial_getc() == STM32_ISP_ACK) break;
                if (++packsendtrycount >= trycount)
                        return(1);
        }
        return(0);//success if we got ACK
}
void autoBaudrateStart(void)
{
        UINT16 trycount = 0;
        char autobaudestablished = 0;
        printf("Auto Baudrate Start ...n"); fflush(stdout);
        while (1)
        {
                trycount++;
                Serial_putc(STM32_ISP_CMD_AUTOBUADRATE);
                unsigned char readByte;
                readByte = Serial_getc();
                if (readByte == STM32_ISP_ACK)
                {
                        autobaudestablished = 1; break;
                        printf("nReceived ACK.n");
                }
                else if (readByte == STM32_ISP_NACK)
                {
                        printf("nReceived NACK.n");
                        autobaudestablished = 1; break;
                }
                if (trycount > 15) break;
                printf(".");
                fflush(stdout);
        }
        if (autobaudestablished)
        {
                printf("Done!n");
                ///*printf("Serial port: %sn", hostopts.serialdevname);
                //printf("Buadrate: %dn", hostopts.baudrate);*/
                printf("Data bits: 8n");
                printf("Parity: Even");
                printf("Stop bits: 1n");
                printf("Flow control: nonen");
                fflush(stdout);
        }
        else
        {
                perror("no respone!n");
                exit(0);
        }
}
void clear_writeprotect(void)
{
        Packet packet;

        packet_zero(&packet);
        packet_appendcommandandcheck(&packet, STM32_ISP_CMD_WRITEUNPROTECT);
        if (packet_sendandgetack(&packet, COMMANDRETRYCOUNT)) {
                printf("tried sending write unprotect command %i times w/o ack, exitingn", COMMANDRETRYCOUNT); fflush(stdout);
                exit(1);
        }
        printf("got first ACK from writeunprotect.. goodn"); fflush(stdout);
        packet_zero(&packet);
        if (packet_sendandgetack(&packet, 1)) {
                printf("didn't get second ack from writeunprotect, exitingn"); fflush(stdout);
                exit(1);
        }
        printf("got second ACK from writeunprotect, assumed successfuln");
        fflush(stdout);
        return;
}
void get_version(void)
{
        Packet outpacket, inpacket;
        int packsendtrycount = 0;
        int bytestoreadfromtarget;
        int bytesactuallyread = 0;
        unsigned char* packptr;

        packet_zero(&outpacket);
        packet_zero(&inpacket);

        packet_appendcommandandcheck(&outpacket, STM32_ISP_CMD_GETVERSION);

        if (packet_sendandgetack(&outpacket, COMMANDRETRYCOUNT))
        {
                printf("tried getversion command %i times w/o ack, exitingn", packsendtrycount);
                exit(1);
        }
        bytestoreadfromtarget = STM32_ISP_CMD_GETVERSIONBYTESTOREAD;

        packptr = inpacket.storage;
        while (1) {
                bytesactuallyread = serial_read(packptr, bytestoreadfromtarget);
                inpacket.length += bytesactuallyread;
                packptr += (size_t)bytesactuallyread;
                bytestoreadfromtarget -= bytesactuallyread;
                if (bytestoreadfromtarget == 0)  break;
        }
        printf("... got %i data bytes from get_version, waiting for an ACKn", inpacket.length);
        if (Serial_getc() == STM32_ISP_ACK)
                printf("got ACK after data in get_version, goodn");
        else {
                printf("didn't get ACK after data in get_version, exitingn");
                exit(1);
        }

        printf("byte %.2i : bootloader version = %.2xn",
                STM32_ISP_CMD_GETVERSION_VERSIONBYTE, inpacket.storage[STM32_ISP_CMD_GETVERSION_VERSIONBYTE]);
        printf("byte %.2i : bootloader version = %.2xn",
                STM32_ISP_CMD_GETVERSION_RDPROTDISABLEDQTYBYTE, inpacket.storage[STM32_ISP_CMD_GETVERSION_RDPROTDISABLEDQTYBYTE]);
        printf("byte %.2i : bootloader version = %.2xn",
                STM32_ISP_CMD_GETVERSION_RDPROTENABLEDQTYBYTE, inpacket.storage[STM32_ISP_CMD_GETVERSION_RDPROTENABLEDQTYBYTE]);
        fflush(stdout);
}
void get_id(void)
{
        Packet outpacket, inpacket;
        int packsendtrycount = 0;
        int bytestoreadfromtarget;
        int bytesactuallyread = 0;
        unsigned char* packptr;
        int i;
        packet_zero(&outpacket);
        packet_zero(&inpacket);
        packet_appendcommandandcheck(&outpacket, STM32_ISP_CMD_GETID);

        if (packet_sendandgetack(&outpacket, COMMANDRETRYCOUNT)) {
                printf("tried getid command %i times w/o ack, exitingn", packsendtrycount);
                exit(1);
        }

        //now get the number of bytes the target says it's going to send us.
        bytestoreadfromtarget = (int)Serial_getc() + 1;

        packptr = inpacket.storage;
        while (1) {
                bytesactuallyread = serial_read(packptr, bytestoreadfromtarget);
                inpacket.length += bytesactuallyread;
                packptr += (size_t)bytesactuallyread;
                bytestoreadfromtarget -= bytesactuallyread;
                if (bytestoreadfromtarget == 0)  break;
        }
        printf("... got %i data bytes from get_command, waiting for an ACKn", inpacket.length);
        if (Serial_getc() == STM32_ISP_ACK)
                printf("got ACK after data in get_id, goodn");
        else {
                printf("didn't get ACK after data in get_id, exitingn");
                exit(1);
        }

        printf("got PID: n");
        for (i = 0; i < inpacket.length; i++)
                printf("%.2x ", inpacket.storage);
        printf("n");
        fflush(stdout);

        return;
}
void globalerase_flash(void)
{
        Packet packet;

        printf("nStarting global flash erase...n"); fflush(stdout);
        packet_zero(&packet);
        packet_appendcommandandcheck(&packet, STM32_ISP_CMD_ERASE);
        if (packet_sendandgetack(&packet, COMMANDRETRYCOUNT)) {
                printf("tried sending erase command %i times w/o ack, exitingn", COMMANDRETRYCOUNT); fflush(stdout);
                exit(1);
        }

        packet_zero(&packet);

        packet_append(&packet, STM32_CMD_ERASEGLOBALPAGEQTYFIELD);
        packet_append(&packet, (unsigned char)~STM32_CMD_ERASEGLOBALPAGEQTYFIELD);
        if (packet_sendandgetack(&packet, 1)) {
                printf("didn't get second ack from globalerase, exitingn"); fflush(stdout);
                exit(1);
        }
        printf("Done!n"); fflush(stdout);
        return;
}
void program_memory(void)
{
        Packet datapacket; //for data
        Packet outpacket; //for command
        unsigned int address;
        char hitEOFinloadfile = 0;
        int packsendtrycount;
        DWORD bytestosendthispacket;
        int bytessenttotal = 0;
        FILE* fp;
        if ((fp = fopen(hostHandle.loadFile, "rb")) == NULL)
        {
                printf("nerror on open %s!", hostHandle.loadFile);
                exit(0);
        }
        //printf("nfseek error:%dn", GetLastError());
        if (fseek(fp, 0L, SEEK_END))
        {
                printf("nfseek error:%dn", GetLastError());
                exit(0);
        }
        long fsize = ftell(fp);
        fclose(fp);
        address = hostHandle.writeAddress;  //starting address
        printf("Starting program memory...n"); fflush(stdout);
        if (hostHandle.loadFile[0] == '') {
                printf("*.bin file needs --loadfile defined, exitingn");
                exit(1);
        }
        wchar_t loadfile[256];
        swprintf(loadfile, 256, L"%S", hostHandle.loadFile);
        LPCWSTR filename = loadfile;
        HANDLE hfile = CreateFile(
                filename,
                GENERIC_READ,//dwDesiredAccess
                0, //dwShareMode
                NULL,//lpSecurityAttributes
                OPEN_EXISTING,//dwCreationDisposition
                FILE_ATTRIBUTE_NORMAL,//dwFlagsAndAttributes
                0);//hTemplateFile

        //ReadFile(

        //)
        //hostresources.inputfile_fd = CreateFile(hostopts.loadfilename, O_RDONLY | O_BINARY);
        if (hfile == INVALID_HANDLE_VALUE)
        {
                if (GetLastError() == ERROR_FILE_NOT_FOUND)
                {
                        printf("ERROR_FILE_NOT_FOUND:%wsn", filename);
                        fflush(stdout);
                        /*return(1);*/
                }
                else if (GetLastError() == ERROR_ACCESS_DENIED)
                {
                        printf("ERROR_ACCESS_DENIED:%wsn", filename);
                        fflush(stdout);
                        /*return(1);*/
                }
                else if (GetLastError() == ERROR_INVALID_NAME)
                {
                        printf("ERROR_INVALID_NAME Error:%wsn", filename);
                        fflush(stdout);
                        /*return(1);*/
                }
                else {
                        printf("Error: Serial operat failure. Error Code:%ldn", GetLastError());
                        fflush(stdout);
                        /*return(1);*/
                }
                exit(0);
        }
        printf("Load file:%sn", hostHandle.loadFile);
        printf("Code size:%ld bytesn", fsize);
        printf("Starting programming....n"); fflush(stdout);
        putchar('n');
        unsigned char totalStep = 0;
        if (fsize / WRITEPACKETMAXDATA < 100)
                totalStep = fsize / WRITEPACKETMAXDATA;
        else
                totalStep = 100;
        for (unsigned char cc = 0; cc < totalStep; cc++)
        {
                putchar('=');
        }
        putchar('n');
        fflush(stdout);
        int lastDP = 0;
        while (!hitEOFinloadfile) {

                BOOL readStatus = ReadFile(hfile, datapacket.storage, WRITEPACKETMAXDATA,&bytestosendthispacket,NULL);
                if (!readStatus)
                {
                        printf("read file error:%dn",GetLastError());
                        exit(1);
                }
                if (bytestosendthispacket < 0) {
                        perror("Trouble reading loadfile!, exiting"); fflush(stdout);
                        exit(1);
                }

                if (bytestosendthispacket == 0) {
                        //printf("nLoading 0 byte, no more data to send.n");fflush(stdout);
                        hitEOFinloadfile = 1;
                        break;        //avoid sending 0 length write packet.
                }

                datapacket.length = bytestosendthispacket;

                //now send the command packet.
                packet_zero(&outpacket);

                packet_appendcommandandcheck(&outpacket, STM32_ISP_CMD_WRITEMEMORY);

                if (packet_sendandgetack(&outpacket, COMMANDRETRYCOUNT)) {
                        printf("Tried sending writememory command %i times w/o ack, exitingn", COMMANDRETRYCOUNT);
                        exit(1);
                }

                int DownloadProgress = bytessenttotal * 100 / fsize;
                //send address
                packet_zero(&outpacket);
                packet_append(&outpacket, ((address & 0xff000000) >> 24));
                packet_append(&outpacket, ((address & 0x00ff0000) >> 16));
                packet_append(&outpacket, ((address & 0x0000ff00) >> 8));
                packet_append(&outpacket, (address & 0x000000ff));
                packet_checksumappend(&outpacket);
                packsendtrycount = 0;


                if (packet_sendandgetack(&outpacket, 1)) {
                        printf("didn't get ack after address+checksum in program_memory exitingn");
                        exit(1);
                }


                packet_zero(&outpacket);
                packet_append(&outpacket, (unsigned char)bytestosendthispacket - 1); //number of bytes to write
                memcpy((outpacket.storage + (size_t)1), datapacket.storage, bytestosendthispacket);
                outpacket.length += bytestosendthispacket;
                packet_checksumappend(&outpacket);

                packet_send(&outpacket);
                if (Serial_getc() != STM32_ISP_ACK) {
                        printf("didn't get ack after length,data,checksum in program_memory exitingn");
                        exit(1);
                }
                bytessenttotal += bytestosendthispacket;
                address += bytestosendthispacket;                //address now at next memory location to write.
                //Gotoxy(currentXY.X+DownloadProgress/2,currentXY.Y);
                if (DownloadProgress > lastDP) {
                        //printf(">%d",DownloadProgress);
                        putchar('>');
                        fflush(stdout);
                        //printf("%d %d n ",DownloadProgress);
                        //putchar('>');

                }
                lastDP = DownloadProgress;
                // Gotoxy(21,4);


        }  //end while !hitEOFinreadfile
        putchar('n');
        for (unsigned char cc = 0; cc < totalStep; cc++)
        {
                putchar('=');
        }
        putchar('n');
        fflush(stdout);
        printf("Total send %i bytes, program complete!n", bytessenttotal);
        CloseHandle(hfile); fflush(stdout);
        return;
}
总体测试情况:


argv[0]:M:stm32_isp_programerstm32_isp_programmerDebugstm32_isp_programmer.exe
argv[1]:COM6
argv[2]:256000
argv[3]:0X08000000
argv[4]:M:Workserial_wireless_v1.1wirelessUsartv1.1.bin
selectPort:COM6
setBuadrate_p:256000
writeAddress_p:0X08000000
loadFile:M:Workserial_wireless_v1.1wirelessUsartv1.1.bin
Serial port: COM6 open success!
Serial port: COM6
Buadrate: 256000
Data bits: 8
Parity: Even
Stop bits: 1
Flow control: none
Serial init complete!



Trying to rest and connet target, please push and hold boot0 button!
Using RTS LOW to reset taeget...


Auto Baudrate Start ...
Done!
Data bits: 8
Parity: EvenStop bits: 1
Flow control: none
... got 3 data bytes from get_version, waiting for an ACK
got ACK after data in get_version, good
byte 00 : bootloader version = 22
byte 01 : bootloader version = 00
byte 02 : bootloader version = 00
... got 2 data bytes from get_command, waiting for an ACK
got ACK after data in get_id, good
got PID:
04 10
got first ACK from writeunprotect.. good
got second ACK from writeunprotect, assumed successful

Starting global flash erase...
Done!
Starting program memory...
Load file:M:Workserial_wireless_v1.1wirelessUsartv1.1.bin
Code size:10660 bytes
Starting programming....

===================================================================================
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
===================================================================================
Total send 10660 bytes, program complete!
Isp complete and reseting...


Total time use: 2.970 seconds
举报

更多回帖

×
20
完善资料,
赚取积分