Closed spth closed 7 years ago
Out of curiosity, were you trying to write an address above 64k by using an intel hex file? I just looked at the intel hex code (to add the ability to create intel hex files on output) and it doesn't look like the current code handles the extended segment or extended linear address records from intel hex files that allow them to handle addresses above 64k. I don't think it would be hard to add these (basically just detect the record types and update an "offset" variable).
Unfortunately I don't have any parts with memory above 64k to test with.
I just came up with a quick and dirty patch for handling esa and ela records in intel hex files, and I am attaching it. If it solves your issue I can clean it up an commit it to my fork, along with support for reading out into an intel hex file for the larger devices.
diff --git a/ihex.c b/ihex.c
index 83e97e8..88e3c1b 100644
--- a/ihex.c
+++ b/ihex.c
@@ -23,7 +23,7 @@ static unsigned char checksum(unsigned char *buf, unsigned int length, int chunk
int ihex_read(FILE *pFile, unsigned char *buf, unsigned int start, unsigned int end) {
fseek(pFile, 0, SEEK_SET);
- unsigned int chunk_len, chunk_addr, chunk_type, i, byte, line_no = 0, greatest_addr = 0;
+ unsigned int chunk_len, chunk_addr, chunk_type, i, byte, line_no = 0, greatest_addr = 0, offset = 0;
while(fgets(line, sizeof(line), pFile)) {
line_no++;
// Reading chunk header
@@ -32,6 +32,25 @@ int ihex_read(FILE *pFile, unsigned char *buf, unsigned int start, unsigned int
ERROR2("Error while parsing IHEX at line %d\n", line_no);
}
// Reading chunk data
+ if(chunk_type == 2) // Extended Segment Address
+ {
+ unsigned int esa;
+ if(sscanf(&line[9],"%04x",&esa) != 1) {
+ free(buf);
+ ERROR2("Error while parsing IHEX at line %d\n", line_no);
+ }
+ offset = esa * 16;
+ }
+ if(chunk_type == 4) // Extended Linear Address
+ {
+ unsigned int ela;
+ if(sscanf(&line[9],"%04x",&ela) != 1) {
+ free(buf);
+ ERROR2("Error while parsing IHEX at line %d\n", line_no);
+ }
+ offset = ela * 65536;
+ }
+
for(i = 9; i < strlen(line) - 1; i +=2) {
if(sscanf(&(line[i]), "%02x", &byte) != 1) {
free(buf);
free(buf);
@@ -45,18 +64,18 @@ int ihex_read(FILE *pFile, unsigned char *buf, unsigned int start, unsigned int
// Respect chunk_len and do not capture checksum as data
break;
}
- if(chunk_addr < start) {
+ if((chunk_addr + offset) < start) {
free(buf);
ERROR2("Address %04x is out of range at line %d\n", chunk_addr, line_no);
}
- if(chunk_addr + chunk_len > end) {
+ if(chunk_addr + offset + chunk_len > end) {
free(buf);
ERROR2("Address %04x + %d is out of range at line %d\n", chunk_addr, chunk_len, line_no);
}
- if(chunk_addr + chunk_len > greatest_addr) {
- greatest_addr = chunk_addr + chunk_len;
+ if(chunk_addr + offset + chunk_len > greatest_addr) {
+ greatest_addr = chunk_addr + offset + chunk_len;
}
- buf[chunk_addr - start + (i - 9) / 2] = byte;
+ buf[chunk_addr + offset - start + (i - 9) / 2] = byte;
}
}
AFAIR, I was using a binary file. And looking at the stm8flash code, it seemed it can't handle addresses > 64K in the backends either.
Philipp
@vdudouyt What was the your source of USB protocol for STLinkV2.
It seems you are packing HI() and LO() parts of start address similar to:
Instinticly I tried adding #define EX(x) (((x) & 0xff0000) >> 16)
stlink2_cmd(pgm, 0xf40a, 7, 0x00, 0x01, 0x00, EX(start), HI(start), LO(start), byte);
Does not seem to work! Thank you on the hints!!
I have started to capture USB packets. Now need to compare it to @vdudouyt code. I am flashing only one byte with ST Visual Programmer
I append a "Spreadsheet" 1byte_0x66_write_0xffff_0x10000_comparison.xlsx
Quick comparison: 0xFFFF: 00 02 00 00 F4 0A 00 01 00 00 FF FF 66 FF 00 00 00 00 00 00
0x10000: 00 02 00 00 F4 0A 00 01 00 01 00 00 66 FF 00 00 00 00 00 00
Based on your comparison of the dumps, it looks to me like what you tried should have worked. (that is supplying the EX(start) as the byte before the HI part of the address. So it seems like if you changed the F40A and F40B commands to add that byte, things might "just work".
The only thing that looks a bit different is that they seem to have an extra FF in the buffer after the first byte. If you try reading 16 bits at 0xfffe and 0x10000 do they also append an FF
I cleaned comparison document a bit, deleted wait states 01 00 00 00, ? led toggle ? Next I will try to modify and compile stm8flash code to modify one byte in 0x10000 address, hardcoded
Good news. I managed to write 1byte on address 0x10000
Writing to address over 64k works in latest commit: https://github.com/janezNov/stm8flash/commit/83040e2e5b88fa036ee33bf0288f0de3b8ddd308 Verification also WORKS! Test 128kB Actual data in 'zero' file.bin was /dev/urandom
Closing this issue. The fix has been merged, and I verified it works (see updated README in pull request #74)
Philipp
I did a bit further testing on chips with more than 32K (results in the README.md of my branch). It seems I cannot write outside the lower 32K of flash, i.e. I cannot write outside the lower 64K of the address space.
Philipp