STM32 ISP 下载程序, C源码,
鑒于flymcu下載時有點慢,flash_loader.exe容易卡死的原因,所以決定自己寫個串口編程和控制臺程序。然后寫成bat文件,再整合到Visual studio的外部工具里,實現(xiàn)一鍵下載。
STM32_ISP的協(xié)議文檔可以在st的官網(wǎng)上找到。
先說下控制臺的大致思路:
程序的目標:把*.bin文件通過指定串口發(fā)送到stm32,stm32把收到的*.bin文件數(shù)據(jù)存到指定的flash地址。
控制臺這邊要給的指令是:例如:COM4 256000 0X08000000 M:\code\debug\text.bin
1.電腦的串口編號: COM4
2.要使用的串口波特率: 256000
3.編程地址: 0X08000000
4.*.bin文件路徑: M:\code\debug\text.bin
所有的指令可以通過int main(int argc, char** argv),的**argv指針獲得。
例如:把上面的指令通過CMD輸入后
程序:
?
運行結(jié)果:
argv[0]:M:\stm32_isp_programer\stm32_isp_programmer\Debug\stm32_isp_programmer.exe
argv[1]:COM6
argv[2]:256000
argv[3]:0X08000000
argv[4]:M:\code\debug\text.bin
但是獲得只是文本類型(char *)。
windows 要打開串口的話用需要用WCHAR* 類型。
所以要做一定的類型轉(zhuǎn)換。
字符串轉(zhuǎn)WCHAR:
#include <Windows.h> wchar_t wstr[20]; swprintf(wstr, 20, L"%S", str); LPCWSTR wstr_p= wstr;字符串轉(zhuǎn)10進制
字符串轉(zhuǎn)16進制
#include <stdlib.h> long baudrate = strtol(setBuadrate_p, &endptr, 10); long writeAddress = strtol(writeAddress_p, &endptr, 16);然后是打開串口:
SerialPort.hSerial = CreateFile(filename, //lpFileNameGENERIC_READ | GENERIC_WRITE,//dwDesiredAccess0, //dwShareModeNULL,//lpSecurityAttributesOPEN_EXISTING,//dwCreationDispositionFILE_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:%d\n", GetLastError(), lengthwrote);}printf("Error:%d Serial write fail, exiting lengthwrote:%d\n", 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, exiting\n");exit(1);}return(bytesread); }如果有加了RTS#控制的話,還可以用RTS來控制單片機復(fù)位:
void hardwareReset() {UINT8 restTime = 5;while (restTime--){if (!EscapeCommFunction(SerialPort.hSerial, SETRTS)) {printf("\nEscapeCommFunction error in serial_config, SETRTS\n");fflush(stdout);exit(1);}Sleep(100);if (!EscapeCommFunction(SerialPort.hSerial, CLRRTS)) {printf("\nEscapeCommFunction error in serial_config, SETRTS\n");fflush(stdout);exit(1);}Sleep(100);printf("%d\n", restTime);} }?
后面是STM32 ISP協(xié)議部分:
主要用到這幾個:
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字節(jié)命令+1字節(jié)命令反碼
N字節(jié)內(nèi)容+1字節(jié)所有內(nèi)容字節(jié)的^(異或運算)
通信流程:發(fā)送指令,等待ACK或者NACK,發(fā)送內(nèi)容,等待ACK或者NACK
主程序:
#include <Windows.h> #include <stdio.h> #include <tchar.h> #include "Serial.h" #include "action.h" #include <stdlib.h> /* 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]:%s\n", i, argv[i]);}selectPort_p = argv[1];setBuadrate_p = argv[2];writeAddress_p = argv[3];loadFile = argv[4];printf("selectPort:%s\n", selectPort_p); printf("setBuadrate_p:%s\n", setBuadrate_p);printf("writeAddress_p:%s\n", writeAddress_p);printf("loadFile:%s\n", 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 seconds\n", timeUse/1000, timeUse%1000); }串口配置:
#pragma once #include <Windows.h> 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 <Windows.h> #include <tchar.h> #include <stdio.h> #include "Serial.h"SerialPort_s SerialPort; void hardwareReset() {UINT8 restTime = 5;while (restTime--){if (!EscapeCommFunction(SerialPort.hSerial, SETRTS)) {printf("\nEscapeCommFunction error in serial_config, SETRTS\n");fflush(stdout);exit(1);}Sleep(100);if (!EscapeCommFunction(SerialPort.hSerial, CLRRTS)) {printf("\nEscapeCommFunction error in serial_config, SETRTS\n");fflush(stdout);exit(1);}Sleep(100);printf("%d\n", 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, //lpFileNameGENERIC_READ | GENERIC_WRITE,//dwDesiredAccess0, //dwShareModeNULL,//lpSecurityAttributesOPEN_EXISTING,//dwCreationDispositionFILE_ATTRIBUTE_NORMAL,NULL);//hTemplateFileif (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:%ld\n", 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: %s\n", serialPortName);printf("Buadrate: %d\n", baudrate);printf("Data bits: 8\n");printf("Parity: Even\n");printf("Stop bits: 1\n");printf("Flow control: none\n");printf("Serial init complete!\n");printf("\n\n\nTrying 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:%d\n", GetLastError(), lengthwrote);}printf("Error:%d Serial write fail, exiting lengthwrote:%d\n", 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, exiting\n");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, exiting\n");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:%x\n", trycount, bytesread);fflush(stdout);}}if (bytesread != 1) {perror("Error: serial port no reponse, exiting\n");exit(1);}return(byte); }通信協(xié)議:
#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協(xié)議驅(qū)動:
#pragma once #include <Windows.h> #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 <Windows.h> #include <stdio.h> #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[i];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: %s\n", hostopts.serialdevname);//printf("Buadrate: %d\n", hostopts.baudrate);*/printf("Data bits: 8\n");printf("Parity: Even");printf("Stop bits: 1\n");printf("Flow control: none\n");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, exiting\n", COMMANDRETRYCOUNT); fflush(stdout);exit(1);}printf("got first ACK from writeunprotect.. good\n"); fflush(stdout);packet_zero(&packet);if (packet_sendandgetack(&packet, 1)) {printf("didn't get second ack from writeunprotect, exiting\n"); fflush(stdout);exit(1);}printf("got second ACK from writeunprotect, assumed successful\n");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, exiting\n", 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 ACK\n", inpacket.length);if (Serial_getc() == STM32_ISP_ACK)printf("got ACK after data in get_version, good\n");else {printf("didn't get ACK after data in get_version, exiting\n");exit(1);}printf("byte %.2i : bootloader version = %.2x\n",STM32_ISP_CMD_GETVERSION_VERSIONBYTE, inpacket.storage[STM32_ISP_CMD_GETVERSION_VERSIONBYTE]);printf("byte %.2i : bootloader version = %.2x\n",STM32_ISP_CMD_GETVERSION_RDPROTDISABLEDQTYBYTE, inpacket.storage[STM32_ISP_CMD_GETVERSION_RDPROTDISABLEDQTYBYTE]);printf("byte %.2i : bootloader version = %.2x\n",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, exiting\n", 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 ACK\n", inpacket.length);if (Serial_getc() == STM32_ISP_ACK)printf("got ACK after data in get_id, good\n");else {printf("didn't get ACK after data in get_id, exiting\n");exit(1);}printf("got PID: \n");for (i = 0; i < inpacket.length; i++)printf("%.2x ", inpacket.storage[i]);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, exiting\n", 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, exiting\n"); fflush(stdout);exit(1);}printf("Done!\n"); fflush(stdout);return; } void program_memory(void) {Packet datapacket; //for dataPacket outpacket; //for commandunsigned 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:%d\n", GetLastError());if (fseek(fp, 0L, SEEK_END)){printf("\nfseek error:%d\n", GetLastError());exit(0);}long fsize = ftell(fp);fclose(fp);address = hostHandle.writeAddress; //starting addressprintf("Starting program memory...\n"); fflush(stdout);if (hostHandle.loadFile[0] == '\0') {printf("*.bin file needs --loadfile <filename> defined, exiting\n");exit(1);}wchar_t loadfile[256];swprintf(loadfile, 256, L"%S", hostHandle.loadFile);LPCWSTR filename = loadfile;HANDLE hfile = CreateFile(filename,GENERIC_READ,//dwDesiredAccess0, //dwShareModeNULL,//lpSecurityAttributesOPEN_EXISTING,//dwCreationDispositionFILE_ATTRIBUTE_NORMAL,//dwFlagsAndAttributes0);//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:%ws\n", filename);fflush(stdout);/*return(1);*/}else if (GetLastError() == ERROR_ACCESS_DENIED){printf("ERROR_ACCESS_DENIED:%ws\n", filename);fflush(stdout);/*return(1);*/}else if (GetLastError() == ERROR_INVALID_NAME){printf("ERROR_INVALID_NAME Error:%ws\n", filename);fflush(stdout);/*return(1);*/}else {printf("Error: Serial operat failure. Error Code:%ld\n", GetLastError());fflush(stdout);/*return(1);*/}exit(0);}printf("Load file:%s\n", hostHandle.loadFile);printf("Code size:%ld bytes\n", fsize);printf("Starting programming....\n"); fflush(stdout);putchar('\n');unsigned char totalStep = 0;if (fsize / WRITEPACKETMAXDATA < 100)totalStep = fsize / WRITEPACKETMAXDATA;elsetotalStep = 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:%d\n",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, exiting\n", COMMANDRETRYCOUNT);exit(1);}int DownloadProgress = bytessenttotal * 100 / fsize;//send addresspacket_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 exiting\n");exit(1);}packet_zero(&outpacket);packet_append(&outpacket, (unsigned char)bytestosendthispacket - 1); //number of bytes to writememcpy((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 exiting\n");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 !hitEOFinreadfileputchar('\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_programer\stm32_isp_programmer\Debug\stm32_isp_programmer.exe argv[1]:COM6 argv[2]:256000 argv[3]:0X08000000 argv[4]:M:\Work\serial_wireless_v1.1\wirelessUsartv1.1.bin selectPort:COM6 setBuadrate_p:256000 writeAddress_p:0X08000000 loadFile:M:\Work\serial_wireless_v1.1\wirelessUsartv1.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... 4 3 2 1 0 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 successfulStarting global flash erase... Done! Starting program memory... Load file:M:\Work\serial_wireless_v1.1\wirelessUsartv1.1.bin Code size:10660 bytes Starting programming....=================================================================================== >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> =================================================================================== Total send 10660 bytes, program complete! Isp complete and reseting... 4 3 2 1 0 Total time use: 2.970 seconds?
總結(jié)
以上是生活随笔為你收集整理的STM32 ISP 下载程序, C源码,的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ps里面怎么剪切图片(自学ps教程网)
- 下一篇: 超声波定高--过滤突然出现的障碍物