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:
parent
c1a12edbe9
commit
4045406ed8
|
@ -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;
|
||||||
|
|
||||||
|
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);
|
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;
|
||||||
|
/* 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);
|
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)
|
||||||
|
|
Loading…
Reference in New Issue