flash Kinetis: implement automatic bank creation based on device probe 25/3925/5
authorTomas Vanek <vanekt@fbl.cz>
Mon, 26 Dec 2016 14:20:33 +0000 (15:20 +0100)
committerFreddie Chopin <freddie.chopin@gmail.com>
Sat, 17 Jun 2017 11:01:45 +0000 (12:01 +0100)
Kinetis flash driver services huge number of MCU types. They have
one, two or four flash banks with option of FlexNVM. It would
require ~36 config files just for Kx series, more for KLx, KVx and KE1x.

The change implements alternative approach:
- configuration file creates just one pflash bank (common for all devices)
- when a device is probed, additional pflash or flexnvm banks are created
based on flash layout of the connected MCU
- created banks have names with optional numbering e.g. kx.pflash0 kx.pflash1
kx.flexnvm0 kx.flexnvm1
- the first bank gets renamed if numbering is used

Automatic bank creation is enabled by tcl command 'kinetis create_banks'.

Used solution has a drawback: other banks than pflash0 are not accessible
until pflash0 is probed. Fortunately gdb attach and standard programming
accesses banks in right sequence.

Change-Id: I5b9037cbefdb8a4176b7715fbcc3af4da4c1ab60
Signed-off-by: Tomas Vanek <vanekt@fbl.cz>
Reviewed-on: http://openocd.zylin.com/3925
Tested-by: jenkins
Reviewed-by: Joakim NohlgÄrd <joakim.nohlgard@eistec.se>
Reviewed-by: Freddie Chopin <freddie.chopin@gmail.com>
doc/openocd.texi
src/flash/nor/kinetis.c
tcl/target/ke1xf.cfg
tcl/target/ke1xz.cfg
tcl/target/klx.cfg
tcl/target/kx.cfg

index ac09db5e2ca9cee46c28d80a16a75b0d0d651d4a..5fd43009d8681c942ecb7f27f45e8bb2195deded 100644 (file)
@@ -5372,6 +5372,12 @@ Use kinetis_ke driver for KE0x devices.
 flash bank $_FLASHNAME kinetis 0 0 0 0 $_TARGETNAME
 @end example
 
+@deffn Command {kinetis create_banks}
+Configuration command enables automatic creation of additional flash banks
+based on real flash layout of device. Banks are created during device probe.
+Use 'flash probe 0' to force probe.
+@end deffn
+
 @deffn Command {kinetis fcf_source} [protection|write]
 Select what source is used when writing to a Flash Configuration Field.
 @option{protection} mode builds FCF content from protection bits previously
index 8ebdbbea6b69e38f6c6f3e9a6e27eeb9086fe957..dc3dc45976b0f9066a01c95a96e5bdc65d58aac9 100644 (file)
@@ -356,6 +356,7 @@ static const struct kinetis_type kinetis_types_old[] = {
 
 static bool allow_fcf_writes;
 static uint8_t fcf_fopt = 0xff;
+static bool create_banks;
 
 
 struct flash_driver kinetis_flash;
@@ -859,6 +860,87 @@ FLASH_BANK_COMMAND_HANDLER(kinetis_flash_bank_command)
        return ERROR_OK;
 }
 
+
+static int kinetis_create_missing_banks(struct kinetis_chip *k_chip)
+{
+       unsigned bank_idx;
+       unsigned num_blocks;
+       struct kinetis_flash_bank *k_bank;
+       struct flash_bank *bank;
+       char base_name[80], name[80], num[4];
+       char *class, *p;
+
+       num_blocks = k_chip->num_pflash_blocks + k_chip->num_nvm_blocks;
+       if (num_blocks > KINETIS_MAX_BANKS) {
+               LOG_ERROR("Only %u Kinetis flash banks are supported", KINETIS_MAX_BANKS);
+               return ERROR_FAIL;
+       }
+
+       bank = k_chip->banks[0].bank;
+       if (bank && bank->name) {
+               strncpy(base_name, bank->name, sizeof(base_name));
+               p = strstr(base_name, ".pflash");
+               if (p) {
+                       *p = '\0';
+                       if (k_chip->num_pflash_blocks > 1) {
+                               /* rename first bank if numbering is needed */
+                               snprintf(name, sizeof(name), "%s.pflash0", base_name);
+                               free((void *)bank->name);
+                               bank->name = strdup(name);
+                       }
+               }
+       } else {
+               strncpy(base_name, target_name(k_chip->target), sizeof(base_name));
+               p = strstr(base_name, ".cpu");
+               if (p)
+                       *p = '\0';
+       }
+
+       for (bank_idx = 1; bank_idx < num_blocks; bank_idx++) {
+               k_bank = &(k_chip->banks[bank_idx]);
+               bank = k_bank->bank;
+
+               if (bank)
+                       continue;
+
+               num[0] = '\0';
+
+               if (bank_idx < k_chip->num_pflash_blocks) {
+                       class = "pflash";
+                       if (k_chip->num_pflash_blocks > 1)
+                               snprintf(num, sizeof(num), "%u", bank_idx);
+               } else {
+                       class = "flexnvm";
+                       if (k_chip->num_nvm_blocks > 1)
+                               snprintf(num, sizeof(num), "%u",
+                                        bank_idx - k_chip->num_pflash_blocks);
+               }
+
+               bank = calloc(sizeof(struct flash_bank), 1);
+               if (bank == NULL)
+                       return ERROR_FAIL;
+
+               bank->target = k_chip->target;
+               bank->driver = &kinetis_flash;
+               bank->default_padded_value = bank->erased_value = 0xff;
+
+               snprintf(name, sizeof(name), "%s.%s%s",
+                        base_name, class, num);
+               bank->name = strdup(name);
+
+               bank->driver_priv = k_bank = &(k_chip->banks[k_chip->num_banks]);
+               k_bank->k_chip = k_chip;
+               k_bank->bank_number = bank_idx;
+               k_bank->bank = bank;
+               if (k_chip->num_banks <= bank_idx)
+                       k_chip->num_banks = bank_idx + 1;
+
+               flash_bank_add(bank);
+       }
+       return ERROR_OK;
+}
+
+
 /* Disable the watchdog on Kinetis devices */
 int kinetis_disable_wdog(struct target *target, uint32_t sim_sdid)
 {
@@ -2176,6 +2258,10 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
        }
 
        k_chip->probed = true;
+
+       if (create_banks)
+               kinetis_create_missing_banks(k_chip);
+
        return ERROR_OK;
 }
 
@@ -2596,6 +2682,16 @@ COMMAND_HANDLER(kinetis_fopt_handler)
        return ERROR_OK;
 }
 
+COMMAND_HANDLER(kinetis_create_banks_handler)
+{
+       if (CMD_ARGC > 0)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       create_banks = true;
+
+       return ERROR_OK;
+}
+
 
 static const struct command_registration kinetis_security_command_handlers[] = {
        {
@@ -2666,6 +2762,12 @@ static const struct command_registration kinetis_exec_command_handlers[] = {
                .usage = "[num]",
                .handler = kinetis_fopt_handler,
        },
+       {
+               .name = "create_banks",
+               .mode = COMMAND_CONFIG,
+               .help = "Driver creates additional banks if device with two/four flash blocks is probed",
+               .handler = kinetis_create_banks_handler,
+       },
        COMMAND_REGISTRATION_DONE
 };
 
index 94b175f2de88548808cabf6fe4ee3c34016c3167..b1200cec2b6a375538b17edca2b65ad95b80d2e2 100644 (file)
@@ -5,5 +5,3 @@
 set CHIPNAME ke
 
 source [find target/kx.cfg]
-
-flash bank flexnvm kinetis 0 0 0 0 $_TARGETNAME
index db2d1a4282384af9f5a97b96a91ec2f3ff6fa937..6a3f509ed2bb863784d03e6ca07ca8a5e257ed31 100644 (file)
@@ -5,5 +5,3 @@
 set CHIPNAME ke
 
 source [find target/klx.cfg]
-
-flash bank flexnvm kinetis 0 0 0 0 $_TARGETNAME
index 0df6612f708d93a9919e6feabf669f0765c784f3..c2de9f7d50b2a6270172dabfe1c67aba74d04718 100644 (file)
@@ -1,5 +1,6 @@
 #
-# Freescale Kinetis KL series devices
+# NXP (former Freescale) Kinetis KL series devices
+# Also used for Cortex-M0+ equipped members of KVx and KE1xZ series
 #
 
 source [find target/swj-dp.tcl]
@@ -31,8 +32,9 @@ target create $_TARGETNAME cortex_m -chain-position $_CHIPNAME.cpu
 
 $_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
 
-set _FLASHNAME $_CHIPNAME.flash
+set _FLASHNAME $_CHIPNAME.pflash
 flash bank $_FLASHNAME kinetis 0 0 0 0 $_TARGETNAME
+kinetis create_banks
 
 # Table 5-1. Clock Summary of KL25 Sub-Family Reference Manual
 # specifies up to 1MHz for VLPR mode.
index b39ee3dd18227a9ab7e4ca11256fcbc09985470f..cf777135c6614454b452ddc2de971f99f63ff153 100644 (file)
@@ -1,5 +1,6 @@
 #
-# Freescale Kinetis Kx series devices
+# NXP (former Freescale) Kinetis Kx series devices
+# Also used for Cortex-M4 equipped members of KVx and KE1xF series
 #
 
 source [find target/swj-dp.tcl]
@@ -35,8 +36,9 @@ target create $_TARGETNAME cortex_m -chain-position $_CHIPNAME.cpu
 
 $_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
 
-set _FLASHNAME $_CHIPNAME.flash
+set _FLASHNAME $_CHIPNAME.pflash
 flash bank $_FLASHNAME kinetis 0 0 0 0 $_TARGETNAME
+kinetis create_banks
 
 adapter_khz 1000
 

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)