Added support for fine-grained bootloader and flash locking in samd.c

lock_flash and lock_bootprot currently support only locking the whole flash and locking the maximal leading flash chunk (32k). 
An optional numerical parameter is added. It can be specified in decimal or 0x prefixed hexadecimal. 
For samd21 'lock_bootprot 0' locks the first 32k of flash while 'lock_bootprot 6' locks the first 512 bytes. 'lock_bootprot 0' is equivalent to 'unlock_bootprot'.  
Similarly, 'lock_flash <number>' locks the flash segments corresponding to zeros in the binary representation of the given number. 
'lock_flash 0xffff' is equivalent to 'unlock_flash'. 
If the optional parameter is not given both commands work as previously.
This commit is contained in:
arpadbuermen 2022-02-17 13:54:19 +01:00 committed by Piotr Esden-Tempski
parent c1a12edbe9
commit 4045406ed8
1 changed files with 63 additions and 2 deletions

View File

@ -715,11 +715,51 @@ static bool samd_set_flashlock(target *t, uint16_t value, const char **argv)
return true; return true;
} }
static bool parse_unsigned(const char *s, uint32_t *val) {
int l, st;
unsigned long num;
l=strlen(s);
if (l>2 && s[0]=='0' && (s[1]=='x' || s[1]=='X')) {
st=sscanf(s+2, "%lx", &num);
} else {
st=sscanf(s, "%lu", &num);
}
if (st<1) {
return false;
}
*val=(uint32_t)num;
return true;
}
static bool samd_cmd_lock_flash(target *t, int argc, const char **argv) static bool samd_cmd_lock_flash(target *t, int argc, const char **argv)
{ {
unsigned long val;
(void)argc; (void)argc;
(void)argv; (void)argv;
return samd_set_flashlock(t, 0x0000, NULL);
if (argc>2) {
tc_printf(t, "usage: monitor lock_flash [number]\n");
return false;
} else if (argc==1) {
return samd_set_flashlock(t, 0x0000, NULL);
} else {
if (!parse_unsigned(argv[1], &val)) {
tc_printf(t, "number must be either decimal or 0x prefixed hexadecimal\n");
return false;
}
if (val>0xffff) {
tc_printf(t, "number must be between 0 and 0xFFFF\n");
return false;
}
return samd_set_flashlock(t, (uint16_t)val, NULL);
}
} }
static bool samd_cmd_unlock_flash(target *t, int argc, const char **argv) static bool samd_cmd_unlock_flash(target *t, int argc, const char **argv)
@ -764,9 +804,30 @@ static bool samd_set_bootprot(target *t, uint16_t value, const char **argv)
static bool samd_cmd_lock_bootprot(target *t, int argc, const char **argv) static bool samd_cmd_lock_bootprot(target *t, int argc, const char **argv)
{ {
unsigned long val;
(void)argc; (void)argc;
(void)argv; (void)argv;
return samd_set_bootprot(t, 0, NULL); /* locks first 0x7 .. 0, 0x6 .. 512, 0x5 .. 1024, ..., 0x0 .. 32768 bytes of flash*/
if (argc>2) {
tc_printf(t, "usage: monitor lock_bootprot [number]\n");
return false;
} else if (argc==1) {
return samd_set_bootprot(t, 0, NULL);
} else {
if (!parse_unsigned(argv[1], &val)) {
tc_printf(t, "number must be either decimal or 0x prefixed hexadecimal\n");
return false;
}
if (val>7) {
tc_printf(t, "number must be between 0 and 7\n");
return false;
}
return samd_set_bootprot(t, (uint16_t)val, NULL);
}
} }
static bool samd_cmd_unlock_bootprot(target *t, int argc, const char **argv) static bool samd_cmd_unlock_bootprot(target *t, int argc, const char **argv)