Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added code so gdbserver can fully support the STM32F4 variable page s…

…izes

gdbserver can now upload up to 1MB projects to flash
  • Loading branch information...
commit 768a70d3213fcfcd605961a770c5446276fd1df8 1 parent 67db39b
@jnosky jnosky authored
Showing with 122 additions and 80 deletions.
  1. +77 −43 gdbserver/gdb-server.c
  2. +43 −36 src/stlink-common.c
  3. +2 −1  src/stlink-common.h
View
120 gdbserver/gdb-server.c
@@ -21,9 +21,9 @@
#include "gdb-remote.h"
#define FLASH_BASE 0x08000000
+
+//Allways update the FLASH_PAGE before each use, by calling stlink_calculate_pagesize
#define FLASH_PAGE (sl->flash_pgsz)
-#define FLASH_PAGE_MASK (~((1 << 10) - 1))
-#define FLASH_SIZE (FLASH_PAGE * 128)
volatile int do_exit = 0;
void ctrl_c(int sig)
@@ -44,19 +44,19 @@ struct chip_params {
uint32_t bootrom_base, bootrom_size;
} const devices[] = {
{ 0x410, "F1 Medium-density device", 0x1ffff7e0,
- 0x20000, 0x400, 0x5000, 0x1ffff000, 0x800 }, // table 2, pm0063
+ 0x20000, 0x400, 0x5000, 0x1ffff000, 0x800 }, // table 2, pm0063
{ 0x411, "F2 device", 0, /* No flash size register found in the docs*/
- 0x100000, 0x20000, 0x20000, 0x1fff0000, 0x7800 }, // table 1, pm0059
+ 0x100000, 0x20000, 0x20000, 0x1fff0000, 0x7800 }, // table 1, pm0059
{ 0x412, "F1 Low-density device", 0x1ffff7e0,
- 0x8000, 0x400, 0x2800, 0x1ffff000, 0x800 }, // table 1, pm0063
- /*No flash size register? page size is variable */
- { 0x413, "F4 device", 0x1FFF7A10,
- 0x100000, 0x4000, 0x30000, 0x1fff0000, 0x7800 }, // table 1, pm0081
+ 0x8000, 0x400, 0x2800, 0x1ffff000, 0x800 }, // table 1, pm0063
+ /*Page size is variable */
+ { 0x413, "F4 device", 0x1FFF7A10, //RM0090 error same as unique ID
+ 0x100000, 0x4000, 0x30000, 0x1fff0000, 0x7800 }, // table 1, pm0081
{ 0x414, "F1 High-density device", 0x1ffff7e0,
- 0x80000, 0x800, 0x10000, 0x1ffff000, 0x800 }, // table 3 pm0063
+ 0x80000, 0x800, 0x10000, 0x1ffff000, 0x800 }, // table 3 pm0063
// This ignores the EEPROM! (and uses the page erase size,
// not the sector write protection...)
- { 0x416, "L1 Med-density device", 0x1FF8004C, // table 1, pm0062
+ { 0x416, "L1 Med-density device", 0x1FF8004C, // table 1, pm0062
0x20000, 0x100, 0x4000, 0x1ff00000, 0x1000 },
{ 0x418, "F1 Connectivity line device", 0x1ffff7e0,
0x40000, 0x800, 0x10000, 0x1fffb000, 0x4800 },
@@ -64,18 +64,19 @@ struct chip_params {
0x20000, 0x400, 0x2000, 0x1ffff000, 0x800 },
{ 0x428, "F1 High-density value line device", 0x1ffff7e0,
0x80000, 0x800, 0x8000, 0x1ffff000, 0x800 },
- { 0x430, "F1 XL-density device", 0x1ffff7e0, // pm0068
+ { 0x430, "F1 XL-density device", 0x1ffff7e0, // pm0068
0x100000, 0x800, 0x18000, 0x1fffe000, 0x1800 },
{ 0 }
};
int serve(stlink_t *sl, int port);
-char* make_memory_map(const struct chip_params *params, uint32_t flash_size);
+char* make_memory_map(stlink_t *sl, const struct chip_params *params, uint32_t flash_size);
int main(int argc, char** argv) {
stlink_t *sl = NULL;
- int port = 0;
+ int port = 0;
+ uint32_t flash_size;
const char * HelpStr = "\nUsage:\n"
"\tst-util [Arguments]\n"
@@ -209,24 +210,29 @@ int main(int argc, char** argv) {
}
printf("Device connected: %s\n", params->description);
- printf("Device parameters: SRAM: 0x%x bytes, Flash: up to 0x%x bytes in pages of 0x%x bytes\n",
- params->sram_size, params->max_flash_size, params->flash_pagesize);
-
- FLASH_PAGE = params->flash_pagesize;
-
- //sl->flash_pgsz=0x4000;
- //sl->flash_size=0x100000;
-
- uint32_t flash_size;
- stlink_read_mem32(sl, params->flash_size_reg, 4);
- flash_size = sl->q_buf[0] | (sl->q_buf[1] << 8);
+ if(sl->chip_id==STM32F4_CHIP_ID) {
+ flash_size=0x100000; //todo: RM0090 error; size register same address as unique ID
+ printf("Device parameters: SRAM: 0x%x bytes, Flash: up to 0x%x bytes with variable page size\n",
+ params->sram_size, flash_size);
+ }
+ else {
+ printf("Device parameters: SRAM: 0x%x bytes, Flash: up to 0x%x bytes in pages of 0x%x bytes\n",
+ params->sram_size, params->max_flash_size, params->flash_pagesize);
+ stlink_read_mem32(sl, params->flash_size_reg, 4);
+ flash_size = sl->q_buf[0] | (sl->q_buf[1] << 8);
+ //flash_size_reg is in 1k blocks.
+ flash_size *= 0x400;
+ }
- //flash_size=0x100000;
+ /* Init PAGE_SIZE for fixed page size devices.
+ * stlink_calculate_pagesize will then return this value for them.
+ * variable pagesize devices must allways update FLASH_PAGE before use! */
+ FLASH_PAGE = params->flash_pagesize;
+ sl->flash_size=flash_size;
- printf("Flash size is %d KiB.\n", flash_size);
- // memory map is in 1k blocks.
- current_memory_map = make_memory_map(params, flash_size * 0x400);
+ printf("Flash size is %d\n", flash_size);
+ current_memory_map = make_memory_map(sl, params, flash_size);
while(serve(sl, port) == 0);
@@ -238,6 +244,28 @@ int main(int argc, char** argv) {
return 0;
}
+static const char* const memory_map_template_F4 =
+ "<?xml version=\"1.0\"?>"
+ "<!DOCTYPE memory-map PUBLIC \"+//IDN gnu.org//DTD GDB Memory Map V1.0//EN\""
+ " \"http://sourceware.org/gdb/gdb-memory-map.dtd\">"
+ "<memory-map>"
+ " <memory type=\"rom\" start=\"0x00000000\" length=\"0x100000\"/>" // code = sram, bootrom or flash; flash is bigger
+ " <memory type=\"ram\" start=\"0x20000000\" length=\"0x30000\"/>" // sram
+ " <memory type=\"flash\" start=\"0x08000000\" length=\"0x10000\">" //Sectors 0..3
+ " <property name=\"blocksize\">0x4000</property>" //16kB
+ " </memory>"
+ " <memory type=\"flash\" start=\"0x08010000\" length=\"0x10000\">" //Sector 4
+ " <property name=\"blocksize\">0x10000</property>" //64kB
+ " </memory>"
+ " <memory type=\"flash\" start=\"0x08020000\" length=\"0x70000\">" //Sectors 5..11
+ " <property name=\"blocksize\">0x20000</property>" //128kB
+ " </memory>"
+ " <memory type=\"ram\" start=\"0x40000000\" length=\"0x1fffffff\"/>" // peripheral regs
+ " <memory type=\"ram\" start=\"0xe0000000\" length=\"0x1fffffff\"/>" // cortex regs
+ " <memory type=\"rom\" start=\"0x1fff0000\" length=\"0x7800\"/>" // bootrom
+ " <memory type=\"rom\" start=\"0x1fffc000\" length=\"0x10\"/>" // option byte area
+ "</memory-map>";
+
static const char* const memory_map_template =
"<?xml version=\"1.0\"?>"
"<!DOCTYPE memory-map PUBLIC \"+//IDN gnu.org//DTD GDB Memory Map V1.0//EN\""
@@ -254,17 +282,22 @@ static const char* const memory_map_template =
" <memory type=\"rom\" start=\"0x1ffff800\" length=\"0x8\"/>" // option byte area
"</memory-map>";
-char* make_memory_map(const struct chip_params *params, uint32_t flash_size) {
+char* make_memory_map(stlink_t *sl, const struct chip_params *params, uint32_t flash_size) {
/* This will be freed in serve() */
char* map = malloc(4096);
map[0] = '\0';
- snprintf(map, 4096, memory_map_template,
- flash_size,
- params->sram_size,
- flash_size, params->flash_pagesize,
- params->bootrom_base, params->bootrom_size);
-
+ if(sl->chip_id==STM32F4_CHIP_ID) {
+ strcpy(map, memory_map_template_F4);
+ }
+
+ else {
+ snprintf(map, 4096, memory_map_template,
+ flash_size,
+ params->sram_size,
+ flash_size, params->flash_pagesize,
+ params->bootrom_base, params->bootrom_size);
+ }
return map;
}
@@ -491,13 +524,14 @@ struct flash_block {
static struct flash_block* flash_root;
-static int flash_add_block(stm32_addr_t addr, unsigned length,
- stlink_t *sl) {
- if(addr < FLASH_BASE || addr + length > FLASH_BASE + FLASH_SIZE) {
+static int flash_add_block(stm32_addr_t addr, unsigned length, stlink_t *sl) {
+
+ if(addr < FLASH_BASE || addr + length > FLASH_BASE + sl->flash_size) {
fprintf(stderr, "flash_add_block: incorrect bounds\n");
return -1;
}
+ stlink_calculate_pagesize(sl, addr);
if(addr % FLASH_PAGE != 0 || length % FLASH_PAGE != 0) {
fprintf(stderr, "flash_add_block: unaligned block\n");
return -1;
@@ -568,18 +602,18 @@ static int flash_go(stlink_t *sl) {
unsigned length = fb->length;
for(stm32_addr_t page = fb->addr; page < fb->addr + fb->length; page += FLASH_PAGE) {
+
+ //Update FLASH_PAGE
+ stlink_calculate_pagesize(sl, page);
+
#ifdef DEBUG
printf("flash_do: page %08x\n", page);
#endif
- //todo:write flash already does erase so why is this here?
- stlink_erase_flash_page(sl, page);
-
if(stlink_write_flash(sl, page, fb->data + (page - fb->addr),
length > FLASH_PAGE ? FLASH_PAGE : length) < 0)
goto error;
- }
-
+ }
}
stlink_reset(sl);
View
79 src/stlink-common.c
@@ -1,4 +1,4 @@
-
+#define DEBUG_FLASH 0
#include <stdarg.h>
#include <stdio.h>
@@ -148,8 +148,10 @@ static inline uint32_t read_flash_cr(stlink_t *sl) {
stlink_read_mem32(sl, FLASH_F4_CR, sizeof (uint32_t));
else
stlink_read_mem32(sl, FLASH_CR, sizeof (uint32_t));
- fprintf(stdout, "CR:%X\n", *(uint32_t*) sl->q_buf);
- return *(uint32_t*) sl->q_buf;
+#if DEBUG_FLASH
+ fprintf(stdout, "CR:0x%x\n", *(uint32_t*) sl->q_buf);
+#endif
+ return *(uint32_t*) sl->q_buf;
}
static inline unsigned int is_flash_locked(stlink_t *sl) {
@@ -281,7 +283,7 @@ static inline uint32_t read_flash_sr(stlink_t *sl) {
stlink_read_mem32(sl, FLASH_F4_SR, sizeof (uint32_t));
else
stlink_read_mem32(sl, FLASH_SR, sizeof (uint32_t));
- //fprintf(stdout, "SR:%X\n", *(uint32_t*) sl->q_buf);
+ //fprintf(stdout, "SR:0x%x\n", *(uint32_t*) sl->q_buf);
return *(uint32_t*) sl->q_buf;
}
@@ -323,7 +325,9 @@ static inline void write_flash_cr_psiz(stlink_t *sl, uint32_t n) {
uint32_t x = read_flash_cr(sl);
x &= ~(0x03 << 8);
x |= (n << 8);
- fprintf(stdout, "PSIZ:%X %X\n", x, n);
+#if DEBUG_FLASH
+ fprintf(stdout, "PSIZ:0x%x 0x%x\n", x, n);
+#endif
write_uint32(sl->q_buf, x);
stlink_write_mem32(sl, FLASH_F4_CR, sizeof (uint32_t));
}
@@ -334,7 +338,9 @@ static inline void write_flash_cr_snb(stlink_t *sl, uint32_t n) {
x &= ~FLASH_F4_CR_SNB_MASK;
x |= (n << FLASH_F4_CR_SNB);
x |= (1 << FLASH_F4_CR_SER);
- fprintf(stdout, "SNB:%X %X\n", x, n);
+#if DEBUG_FLASH
+ fprintf(stdout, "SNB:0x%x 0x%x\n", x, n);
+#endif
write_uint32(sl->q_buf, x);
stlink_write_mem32(sl, FLASH_F4_CR, sizeof (uint32_t));
}
@@ -393,7 +399,7 @@ void stlink_identify_device(stlink_t *sl) {
(sl->q_buf[3] << 24);
/* Fix chip_id for F4 */
if (((chip_id & 0xFFF) == 0x411) && (core_id == CORE_M4_R0)) {
- printf("Fixing wrong chip_id for STM32F4 Rev A errata\n");
+ //printf("Fixing wrong chip_id for STM32F4 Rev A errata\n");
chip_id = 0x413;
}
sl->chip_id=chip_id;
@@ -816,17 +822,17 @@ uint32_t calculate_F4_sectornum(uint32_t flashaddr){
}
-uint32_t calculate_sectorsize(stlink_t *sl, uint32_t flashaddr){
+uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){
if(sl->chip_id == STM32F4_CHIP_ID) {
uint32_t sector=calculate_F4_sectornum(flashaddr);
- if (sector<4) return (0x4000);
- else if(sector<5) return(0x10000);
- else return(0x20000);
+ if (sector<4) sl->flash_pgsz=0x4000;
+ else if(sector<5) sl->flash_pgsz=0x10000;
+ else sl->flash_pgsz=0x20000;
}
- else return (sl->flash_pgsz);
+ return (sl->flash_pgsz);
}
-int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t page)
+int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr)
{
/* page an addr in the page to erase */
@@ -841,13 +847,11 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t page)
unlock_flash_if(sl);
/* select the page to erase */
- //Page is passed to us as an addr, so calculate the actual page
- uint32_t addr=page;
-
- page=calculate_F4_sectornum(addr);
+ // calculate the actual page from the address
+ uint32_t sector=calculate_F4_sectornum(flashaddr);
- fprintf(stderr, "Erasing Sector:%u SectorSize:%u\n", page, calculate_sectorsize(sl, addr));
- write_flash_cr_snb(sl, page);
+ fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x\n", sector, stlink_calculate_pagesize(sl, flashaddr));
+ write_flash_cr_snb(sl, sector);
/* start erase operation */
set_flash_cr_strt(sl);
@@ -858,8 +862,9 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t page)
/* relock the flash */
//todo: fails to program if this is in
lock_flash(sl);
- fprintf(stdout, "Erase Final CR:%X\n", read_flash_cr(sl));
-
+#if DEBUG_FLASH
+ fprintf(stdout, "Erase Final CR:0x%x\n", read_flash_cr(sl));
+#endif
}
else if (sl->core_id == STM32L_CORE_ID)
@@ -928,7 +933,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t page)
/* write 0 to the first word of the page to be erased */
memset(sl->q_buf, 0, sizeof(uint32_t));
- stlink_write_mem32(sl, page, sizeof(uint32_t));
+ stlink_write_mem32(sl, flashaddr, sizeof(uint32_t));
/* reset lock bits */
stlink_read_mem32(sl, STM32L_FLASH_PECR, sizeof(uint32_t));
@@ -948,7 +953,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t page)
set_flash_cr_per(sl);
/* select the page to erase */
- write_flash_ar(sl, page);
+ write_flash_ar(sl, flashaddr);
/* start erase operation, reset by hw with bsy bit */
set_flash_cr_strt(sl);
@@ -1068,7 +1073,7 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) {
}
else
{
- fprintf(stderr, "unknown coreid: %x\n", sl->core_id);
+ fprintf(stderr, "unknown coreid: 0x%x\n", sl->core_id);
return -1;
}
@@ -1104,12 +1109,8 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned
stlink_identify_device(sl);
-#if 0 /* todo: use in debugging mode only */
- fprintf(stdout, "WriteFlash - addr:%x len:%x\n", addr, len);
- fprintf(stdout, "CoreID:%X ChipID:%X\n", sl->core_id, sl->chip_id);
-#endif
-
/* check addr range is inside the flash */
+ stlink_calculate_pagesize(sl, addr);
if (addr < sl->flash_base) {
fprintf(stderr, "addr too low\n");
return -1;
@@ -1128,14 +1129,20 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned
}
/* erase each page */
- for (off = 0; off < len; off += calculate_sectorsize(sl, addr + off) ) {
- /* addr must be an addr inside the page */
+ for (off = 0; off < len; off += stlink_calculate_pagesize(sl, addr + off) ) {
+ //addr must be an addr inside the page
if (stlink_erase_flash_page(sl, addr + off) == -1) {
fprintf(stderr, "erase_flash_page(0x%zx) == -1\n", addr + off);
return -1;
}
}
+#if 1 /* todo: use in debugging mode only */
+ fprintf(stdout, "WriteFlash - Addr:0x%x len:0x%x\n", addr, len);
+ //fprintf(stdout, "CoreID:0x%x ChipID:0x%x\n", sl->core_id, sl->chip_id);
+#endif
+
+
if (sl->chip_id == STM32F4_CHIP_ID) {
/* todo: check write operation */
@@ -1172,7 +1179,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned
lock_flash(sl);
#if 0 /* todo: debug mode */
- fprintf(stdout, "Final CR:%X\n", read_flash_cr(sl));
+ fprintf(stdout, "Final CR:0x%x\n", read_flash_cr(sl));
#endif
@@ -1262,7 +1269,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned
if (off % sl->flash_pgsz) off &= ~(sl->flash_pgsz - 1);
page = addr + off;
- fprintf(stderr, "invalid write @%x(%x): %x != %x. retrying.\n",
+ fprintf(stderr, "invalid write @0x%x(0x%x): 0x%x != 0x%x. retrying.\n",
page, addr + off, read_uint32(base + off, 0), read_uint32(sl->q_buf, 0));
/* reset lock bits */
@@ -1343,7 +1350,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned
if (aligned_size & (4 - 1))
aligned_size = (cmp_size + 4) & ~(4 - 1);
- fprintf(stdout, "AlignedSize:%x\n", aligned_size);
+ fprintf(stdout, "AlignedSize:0x%x\n", aligned_size);
stlink_read_mem32(sl, addr + off, aligned_size);
if (memcmp(sl->q_buf, base + off, cmp_size))
@@ -1409,7 +1416,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons
stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */
} else {
- fprintf(stderr, "unknown coreid: %x\n", sl->core_id);
+ fprintf(stderr, "unknown coreid: 0x%x\n", sl->core_id);
return -1;
}
@@ -1441,7 +1448,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons
} else {
- fprintf(stderr, "unknown coreid: %x\n", sl->core_id);
+ fprintf(stderr, "unknown coreid: 0x%x\n", sl->core_id);
return -1;
}
View
3  src/stlink-common.h
@@ -243,7 +243,8 @@ extern "C" {
// privates, publics, the rest....
// TODO sort what is private, and what is not
- int stlink_erase_flash_page(stlink_t* sl, stm32_addr_t page);
+ int stlink_erase_flash_page(stlink_t* sl, stm32_addr_t flashaddr);
+ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr);
uint16_t read_uint16(const unsigned char *c, const int pt);
void stlink_core_stat(stlink_t *sl);
void stlink_print_data(stlink_t *sl);
Please sign in to comment.
Something went wrong with that request. Please try again.