print hash for bootloader and firmware versions and allow extracting firmware file version and hash, nicer output formatting

This commit is contained in:
John-Michael Baier
2020-12-19 17:11:01 +01:00
parent 509ad6e95a
commit 13230b4845
+90 -9
View File
@@ -214,6 +214,12 @@ typedef union
#define WAIT_BYTE_TRANSFERRED_MILLIS 200 #define WAIT_BYTE_TRANSFERRED_MILLIS 200
#define WAIT_BITRATE_DETECTION_MICROS 100 #define WAIT_BITRATE_DETECTION_MICROS 100
#define WAIT_RESPONSE_TIMEOUT_MILLIS 100 #define WAIT_RESPONSE_TIMEOUT_MILLIS 100
// size of flash in bytes
#define END_FLASH_BYTES (END_FLASH*2)
// size of boot block in words
#define END_BOOT 0x0400
// size of boot block in bytes
#define END_BOOT_BYTES (END_BOOT*2)
long long getTime() { long long getTime() {
struct timespec ts; struct timespec ts;
@@ -612,6 +618,65 @@ void closeSerial(int fd) {
close(fd); close(fd);
} }
int calcFileChecksum(uint8_t* storeFirstBlock=nullptr) {
std::ifstream inStream;
inStream.open(flashFile, ifstream::in);
if (!inStream.good()) {
std::cerr<<"unable to open file"<<std::endl;
return -1;
}
intelhex ih;
inStream >> ih;
if (ih.getNoErrors()>0 || ih.getNoWarnings()>0) {
std::cerr<<"unable to read file"<<std::endl;
return -1;
}
unsigned long startAddr = 0, endAddr = 0;
if (!ih.startAddress(&startAddr) || !ih.endAddress(&endAddr)) {
std::cerr<<"unable to read file"<<std::endl;
return -1;
}
if (startAddr<END_BOOT_BYTES || endAddr>=END_FLASH_BYTES || endAddr<startAddr || (startAddr&0xf)!=0) {
std::cerr<<"invalid address range"<<std::endl;
return -1;
}
ih.begin();
unsigned long nextAddr = ih.currentAddress();
if (nextAddr!=END_BOOT_BYTES) {
std::cerr<<"unexpected start address in file."<<std::endl;
return -1;
}
unsigned long blockStart = END_BOOT_BYTES;
uint16_t checkSum = 0;
while (blockStart<endAddr && nextAddr<END_FLASH_BYTES) {
for (int pos = 0; pos < WRITE_FLASH_BLOCKSIZE; pos++, nextAddr++) {
unsigned long addr = ih.currentAddress();
uint8_t value = (pos&0x1)==1?0x3f:0xff;
if (addr == nextAddr && ih.getData(&value)) {
ih.incrementAddress();
}
if (storeFirstBlock && nextAddr<END_BOOT_BYTES+0x10) {
storeFirstBlock[pos] = value;
}
checkSum += ((uint16_t)value)<<((pos&0x1)*8);
}
blockStart += WRITE_FLASH_BLOCKSIZE;
}
return checkSum;
}
void printFileChecksum() {
uint8_t data[0x10];
int checkSum = calcFileChecksum(data);
int newFirmwareVersion = -1;
if (data[0x2*2]==0xae && data[0x2*2+1]==0x34 && data[0x3*2+1]==0x34) {
newFirmwareVersion = data[0x3*2];
}
std::cout
<< "New firmware version: " << static_cast<unsigned>(newFirmwareVersion)
<< " [" << std::hex << std::setw (4) << std::setfill('0') << static_cast<signed>(checkSum) << "]" << std::endl;
}
bool flashPic(int fd) { bool flashPic(int fd) {
std::ifstream inStream; std::ifstream inStream;
inStream.open(flashFile, ifstream::in); inStream.open(flashFile, ifstream::in);
@@ -647,18 +712,18 @@ bool flashPic(int fd) {
<< std::hex << std::setfill('0') << std::setw(4) << static_cast<unsigned>(endAddr) << std::hex << std::setfill('0') << std::setw(4) << static_cast<unsigned>(endAddr)
<< std::endl; << std::endl;
} }
if (startAddr<0x800 || endAddr>=0x8000 || endAddr<startAddr || (startAddr&0xf)!=0) { if (startAddr<END_BOOT_BYTES || endAddr>=END_FLASH_BYTES || endAddr<startAddr || (startAddr&0xf)!=0) {
std::cerr<<"invalid address range"<<std::endl; std::cerr<<"invalid address range"<<std::endl;
return false; return false;
} }
ih.begin(); ih.begin();
uint8_t buf[WRITE_FLASH_BLOCKSIZE]; uint8_t buf[WRITE_FLASH_BLOCKSIZE];
unsigned long nextAddr = ih.currentAddress(); unsigned long nextAddr = ih.currentAddress();
if (nextAddr!=0x800) { if (nextAddr!=END_BOOT_BYTES) {
std::cerr<<"unexpected start address in file: 0x"<<std::hex<<std::setfill('0')<<std::setw(4)<<static_cast<unsigned>(nextAddr)<<std::endl; std::cerr<<"unexpected start address in file: 0x"<<std::hex<<std::setfill('0')<<std::setw(4)<<static_cast<unsigned>(nextAddr)<<std::endl;
return false; return false;
} }
unsigned long blockStart = 0x800; unsigned long blockStart = END_BOOT_BYTES;
uint16_t checkSum = 0; uint16_t checkSum = 0;
int eraseRes = eraseFlash(fd, blockStart/2, (endAddr-blockStart)/2); int eraseRes = eraseFlash(fd, blockStart/2, (endAddr-blockStart)/2);
if (eraseRes!=0) { if (eraseRes!=0) {
@@ -802,9 +867,14 @@ int main(int argc, char* argv[]) {
arg_index = argc; // force help output arg_index = argc; // force help output
} }
if (argc-arg_index<1) { if (argc-arg_index<1) {
argp_help(&aargp, stderr, 0, nullptr); if (flashFile) {
printFileChecksum();
exit(EXIT_SUCCESS);
} else {
argp_help(&aargp, stderr, ARGP_HELP_STD_ERR, "ebuspicloader");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
}
int fd = openSerial(argv[arg_index]); int fd = openSerial(argv[arg_index]);
if (fd<0) { if (fd<0) {
@@ -812,7 +882,10 @@ int main(int argc, char* argv[]) {
} }
// read version // read version
if (readVersion(fd, verbose)==0) { if (readVersion(fd, verbose)!=0) {
closeSerial(fd);
exit(EXIT_FAILURE);
}
uint8_t data[0x10]; uint8_t data[0x10];
if (verbose) { if (verbose) {
std::cout << "User ID:" << std::endl; std::cout << "User ID:" << std::endl;
@@ -837,27 +910,36 @@ int main(int argc, char* argv[]) {
int bootloaderVersion = -1; int bootloaderVersion = -1;
if (data[0x2*2]==0xab && data[0x2*2+1]==0x34 && data[0x3*2+1]==0x34) { if (data[0x2*2]==0xab && data[0x2*2+1]==0x34 && data[0x3*2+1]==0x34) {
bootloaderVersion = data[0x3*2]; bootloaderVersion = data[0x3*2];
std::cout<<"Bootloader version: "<< static_cast<unsigned>(bootloaderVersion) <<std::endl; int picSum = calcChecksum(fd, 0x0000, END_BOOT_BYTES);
std::cout
<< "Bootloader version: " << static_cast<unsigned>(bootloaderVersion)
<< " [" << std::hex << std::setw (4) << std::setfill('0') << static_cast<signed>(picSum) << "]" << std::endl;
} else { } else {
std::cerr<<"Bootloader version not found"<<std::endl; std::cerr<<"Bootloader version not found"<<std::endl;
} }
readFlash(fd, 0x0400, false, false, data); readFlash(fd, END_BOOT, false, false, data);
int firmwareVersion = -1; int firmwareVersion = -1;
if (data[0x2*2]==0xae && data[0x2*2+1]==0x34 && data[0x3*2+1]==0x34) { if (data[0x2*2]==0xae && data[0x2*2+1]==0x34 && data[0x3*2+1]==0x34) {
firmwareVersion = data[0x3*2]; firmwareVersion = data[0x3*2];
std::cout<<"Firmware version: "<< static_cast<unsigned>(firmwareVersion) <<std::endl; int picSum = calcChecksum(fd, END_BOOT, END_FLASH_BYTES-END_BOOT_BYTES);
std::cout
<< "Firmware version: " << static_cast<unsigned>(firmwareVersion)
<< " [" << std::hex << std::setw (4) << std::setfill('0') << static_cast<signed>(picSum) << "]" << std::endl;
} else { } else {
std::cout<<"Firmware version not found"<<std::endl; std::cout<<"Firmware version not found"<<std::endl;
} }
readIpSettings(fd); readIpSettings(fd);
std::cout<<std::endl;
bool success = true; bool success = true;
if (flashFile) { if (flashFile) {
printFileChecksum();
if (!flashPic(fd)) { if (!flashPic(fd)) {
success = false; success = false;
} }
} }
if (setIp || setDhcp) { if (setIp || setDhcp) {
if (writeIpSettings(fd)) { if (writeIpSettings(fd)) {
std::cout << "IP settings changed to:" << std::endl;
readIpSettings(fd); readIpSettings(fd);
} else { } else {
success = false; success = false;
@@ -867,7 +949,6 @@ int main(int argc, char* argv[]) {
std::cout << "resetting device." << std::endl; std::cout << "resetting device." << std::endl;
resetDevice(fd); resetDevice(fd);
} }
}
closeSerial(fd); closeSerial(fd);
return 0; return 0;